/***************************************************************************
*
*    clsValidator  - Version 2.20050325
*    Copyleft: Horacio R. Valdez
*    website: www.hvaldez.com.ar/javascript/clsValidator/sp
*    Soporte: info@hvaldez.com.ar
*    Creado: 05.2004
*    Actualización: 25.03.2005 
*
**************************************************************************** 
* Este script es distribuido bajo la licencia GNU/LGPL
****************************************************************************
* Gracias a:
*    Canal #javascript en Undernet
*    foros del web (www.forosdelweb.com)
*
****************************************************************************
* Cambios en esta versión
*    1- Se optimizaron todas las expresiones regulares y se agregaron nuevas.
*     2- Se deja x default el color de Error #FFC1C1 (antes era "")
*    3- Se deja x default el formato de fecha dd/mm/aaaa 
*   4- Se deja x default el mensaje "[- Se encontraron los siguientes errores en el formulario -]"
*    5- Se agrega la función setFormatoFecha('formato')
*        Formatos aceptados:    
*        5.1- 'EURO': dd/mm/aaaa - formato europeo/sudamericano
*        5.2- 'ISO': aaaa/mm/dd - formato internacional ISO 8601
*        5.3- 'ANSI': aaaa-mm-dd hh:mm:ss am/pm - formato ANSI SQL
*    6- Se agrega la función setFormatoHora('formato')    
*        Formatos aceptados:
*        6.1- '24': Formato 24 hs (1..23)    
*        6.2- '12': Formato 12 hs (am/pm)      
*    7- Se agrega la funcion objValidar.Hora()
*    
****************************************************************************
* Propósito: validar campos y combos en un formulario HTML
****************************************************************************
Forma de uso:
    en documentos HTML:
    var objValidar = new clsValidar;

    todos los métodos se invocan de la misma manera
    objeValidator.nombreDelMetodo("campo","mensaje");    

    campo: nombre del campo que se quiere validar.
    mensaje: mensaje de error si cumple o no la validación.
    Ej. objValidar.Vacio("Usuario","Debe completar el nombre de usuario");


Métodos:
1.    objValidar.setEncabezado(valor)
    Objetivo: Setea el titulo del mensaje de error.
    Parámetros: String;
    Ej: objValidar.setEncabezado("[- Se encontraron errores en el formulario -] ");
       
2.    objValidar.setErrorColor(valor);
    Objetivo: Setea el color de fondo para los campos con error;
    Parámetros: String;
    Ej: objValidar.setErrorColor("#FFF4F4");
    
3.    objValidar.Vacio(campo,msg);
    Objetivo: verifica si el campo es vacío. 
    Parámetros: campo String, msg String;
    Ej: objValidar.Vacio("Usuario","Debe completar el nombre de usuario");

4.    objValidar.Email(campo,msg);
    Objetivo: verifica si el email ingresado es válido. 
    Parámetros: campo String, msg String;
    Ej: objValidar.Email("email", "El email no es válido");    

5.    objValidar.Fecha(campo, msg);
    Objetivo: validar el formato de una fecha.
    Parámetros: campo String, msg String;
    Ej: objValidar.Fecha("fechaNacimiento","La fecha no es válida. Formato dd/mm/aaaa");

6.    objValidar.Iguales(campo1, campo2, msg);
    Objetivo: dado 2 campos verifica que estos sean iguales
    Parámetros: campo1 String, campo2 String, msg String;
    Ej: objValidar.Iguales("passwd1","passwd2","Los passwords son distintos");

7.    objValidar.Longitud(campo, longitud, msg);
    Objetivo: verifica que la longitud del campo sea mayor, menor o igual que un número 
    de caracteres dado
    Parámetros: campo String, longitud, integer, msg String;
    Ej: objValidar.Longitud("passwd1", ">", 8, "El password debe ser mayor a 8 caracteres"); 
        objValidar.Longitud("passwd1", "<", 6, "El password debe ser menor a 6 caracteres"); 
        objValidar.Longitud("passwd1", "=", 4, "El password debe ser igual a 4 caracteres");    

8.     objValidar.Validar();
    Objetivo evaluar si hubieron errores en los campos del formulario. Devuelve TRUE si todo
    está ok y FALSE si hay errores.
    
9.    objValidar.getErrors();
    Objetivo: muestra en pantalla un informe con todos los errores que ocurrieron.
    Ej:
    
    if (objValidar.Validar()) document.frmContacto.submit()     
    else objValidar.getErrors();

10.    objValidar.setFormatoFecha(valor)
    Objetivo: setear el formato de la Fecha. Default: EURO.
    Ver "Cambios en esta versión" para mas detalles sobre las codificaciones
    Parámetros: valor String;
    Ej: objValidar.setFormatoHora('EURO') - dd/mm/aaaa 
        objValidar.setFormatoHora('ISO')  - aaaa/mm/dd 
        objValidar.setFormatoHora('ANSI') - aaaa-mm-dd hh:mm:ss am/pm
        
11.    objValidar.setFormatoHora(valor)
    Objetivo: setear el formato de la Hora. Default: 24.
    Ver "Cambios en esta versión" para mas detalles sobre las codificaciones.
    Parámetros: valor String;
    Ej: objValidar.setFormatoHora('24') - 22:59
        objValidar.setFormatoHora('12')  - 10:59 pm
    
12. objValidar.Hora(campo, msg)
    Objetivo: validar el formato de una hora.
    Parámetros: campo String, msg String;
    Ej: objValidar.Hora("HoraSalida","La hora no es válida.");    
    
****************************************************************************/
function clsValidator() 
{

    /* Data members */
    this.msgError="";                                                            // Return the msg error
    this.errorColor="#97E783";                                                    // color de error x defecto
    this.head = "[- Se encontraron los siguientes errores en el formulario -]"; // encabezado del mensaje de error x defecto
    this.formatoFecha = "EURO"                                                    // formato de fecha x defecto
    this.formatoHora = "12"                                                        // formato de hora x defecto
    this.error = false;            

    /* Methods */
    ///////////////////////////////////////////////////////////

    function setEncabezado(head)    
    {
        this.head = head;
    }
    ///////////////////////////////////////////////////////////

    function AgregarError() {
        this.error=true;
        this.msgError += "* "+arguments[0]+"\n";
        for (var i=1; i < arguments.length ; i++) 
        {
            document.getElementById(arguments[i]).style.backgroundColor=this.errorColor;
        }
    }
    ///////////////////////////////////////////////////////////
    
    function EliminarError()
    {
        for (var i=0; i < arguments.length ; i++) 
        {
            document.getElementById(arguments[i]).style.backgroundColor="";
        }
    }
    ///////////////////////////////////////////////////////////
    
    function setErrorColor(color)
    {
        this.errorColor = color;
    }
    ///////////////////////////////////////////////////////////
    
    function setFormatoFecha(value)
    {
        this.formatoFecha = value;
    }    
    ///////////////////////////////////////////////////////////

    function setFormatoHora(value)
    {
        this.formatoHora = value;
    }
    ///////////////////////////////////////////////////////////

    function Vacio(field,msg) 
    {
        this.EliminarError(field);
        if (document.getElementById(field).value.replace(/ /g, '') == "")
        {
            this.AgregarError(msg, field);
            return false
        }
        return true
    }
    ///////////////////////////////////////////////////////////
    
    function Email(field,msg) 
    {
        this.EliminarError(field);
        var re  = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/;
        if (!re.test(document.getElementById(field).value)) {
            this.AgregarError(msg, field);
            return false
        }
        return true
    }
    ///////////////////////////////////////////////////////////
    
    function Fecha(field, msg) 
    {
        this.EliminarError(field);
    
        var datePat;
        var formatoCorrecto;
        
        switch(this.formatoFecha) {
            case 'ISO':
                datePat = /^(?:(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(\/|-|\.)(?:0?2\1(?:29))$)|(?:(?:1[6-9]|[2-9]\d)?\d{2})(\/|-|\.)(?:(?:(?:0?[13578]|1[02])\2(?:31))|(?:(?:0?[1,3-9]|1[0-2])\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\2(?:0?[1-9]|1\d|2[0-8]))$/;
                formatoCorrecto = "aaaa/mm/dd";
                break;
            case 'EURO': 
                datePat = /^((([0][1-9]|[12][\d])|[3][01])[-/]([0][13578]|[1][02])[-/][1-9]\d\d\d)|((([0][1-9]|[12][\d])|[3][0])[-/]([0][13456789]|[1][012])[-/][1-9]\d\d\d)|(([0][1-9]|[12][\d])[-/][0][2][-/][1-9]\d([02468][048]|[13579][26]))|(([0][1-9]|[12][0-8])[-/][0][2][-/][1-9]\d\d\d)$/;
                formatoCorrecto = "dd/mm/aaaa";
                break;
            case 'ANSI':
                datePat = /^((\d{2}(([02468][048])|([13579][26]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|([1-2][0-9])))))|(\d{2}(([02468][1235679])|([13579][01345789]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\s(((0?[1-9])|(1[0-2]))\:([0-5][0-9])((\s)|(\:([0-5][0-9])\s))([AM|PM|am|pm]{2,2})))?$/;
                formatoCorrecto = "aaaa/mm/dd hh:mm:ss am/pm";
                break;
        }        
        
        var matchArray = document.getElementById(field).value.match(datePat);
        if (matchArray != null) return true
        else
        {
            msg += ' [formato: '+formatoCorrecto+']'
            this.AgregarError(msg, field);
            return false;        
        }
    }
    ///////////////////////////////////////////////////////////
    
    function Hora(field, msg)
    {
        this.EliminarError(field);
        var datePat;

        switch(this.formatoHora) {
            case '24':
                datePat = /^([0-1][0-9]|2[0-3]):[0-5][0-9]$/;
                formatoCorrecto = "hh:mm";
                break;
                
            case '12':
                datePat = /^(1|01|2|02|3|03|4|04|5|05|6|06|7|07|8|08|9|09|10|11|12{1,2}):(([0-5]{1}[0-9]{1}\s{0,1})([AM|PM|am|pm]{2,2}))\W{0}$/;
                formatoCorrecto = "hh:mm am/pm";
                break;
        }
        var matchArray = document.getElementById(field).value.match(datePat);
        if (matchArray != null) return true
        else
        {
            msg += ' [formato: '+formatoCorrecto+']'
            this.AgregarError(msg, field);
            return false;        
        }
    }
    ///////////////////////////////////////////////////////////
    
    function Iguales(field1, field2, msg)
    {
        this.EliminarError(field1,field2);
        if(document.getElementById(field1).value != document.getElementById(field2).value)
        {
            this.AgregarError(msg, field1, field2);
            return false
        }
        return true    
    }
    ///////////////////////////////////////////////////////////
    
    function Longitud(field, operator, length, msg)
    {
        this.EliminarError(field);
        if (operator == "=") operator = "==";
        if ( !(eval("document.getElementById(field).value.length "+operator+" length")) )
        {
            this.AgregarError(msg, field);
            return false
        }
        return true
    }
    ///////////////////////////////////////////////////////////
    
    function Entero(field, msg)
    {
        this.EliminarError(field);
        
        if ( ! ( parseInt(document.getElementById(field).value) == document.getElementById(field).value ) )
        {
            this.AgregarError(msg, field);
            return false
        }
        return true
    }
    ///////////////////////////////////////////////////////////
    
    function Valor(field, operator, valor, msg)
    {
        this.EliminarError(field);
        if (operator == "=") operator = "==";
        if ( !(eval("document.getElementById(field).value "+operator+" valor")) )
        {
            this.AgregarError(msg, field);
            return false
        }
        return true
    }
    ///////////////////////////////////////////////////////////

    function Validar() 
    {
        return !this.error;
    }
    ///////////////////////////////////////////////////////////

    function getErrors() 
    {
        alert(this.head+"\n\n"+this.msgError);
    }
    ///////////////////////////////////////////////////////////
    
    function Telefono(field, msg)
{   var i;
    var dotAppeared;
    dotAppeared = false;
    if (isEmpty(field)) 
       if (isNumber.arguments.length == 1) return defaultEmptyOK;
       else return (isNumber.arguments[1] == true);
    
    for (i = 0; i < field.length; i++)
    {   
        var c = field.charAt(i);
        if( i != 0 ) {
            if ( c == "." ) {
                if( !dotAppeared )
                    dotAppeared = true;
                else
                    this.AgregarError(msg, field);
                    return false;
            } else     
                if (!isDigit(c)) return false;
        } else { 
            if ( c == "." ) {
                if( !dotAppeared )
                    dotAppeared = true;
                else
                    return false;
            } else     
                if (!isDigit(c) && (c != "-") || (c == "+"))
                this.AgregarError(msg, field);
                return false;
        }
    }
    return true;
}

///////////////////////////////////////////////////////////////////

function checkField (theField, theFunction, emptyOK, s)
{   
    var msg;
    if (checkField.arguments.length < 3) emptyOK = defaultEmptyOK;
    if (checkField.arguments.length == 4) {
        msg = s;
    } else {
        if( theFunction == isAlphabetic ) msg = pAlphabetic;
        if( theFunction == isAlphanumeric ) msg = pAlphanumeric;
        if( theFunction == isInteger ) msg = pInteger;
        if( theFunction == isNumber ) msg = pNumber;
        if( theFunction == isEmail ) msg = pEmail;
        if( theFunction == isPhoneNumber ) msg = pPhoneNumber;
        if( theFunction == isName ) msg = pName;
    }
    
    if ((emptyOK == true) && (isEmpty(theField.value))) return true;

    if ((emptyOK == false) && (isEmpty(theField.value))) 
        return warnEmpty(theField);

    if (theFunction(theField.value) == true) 
        return true;
    else
        return warnInvalid(theField,msg);

}

//////////////////////////////////////////////////////////////////

    this.setEncabezado = setEncabezado;
    this.setErrorColor = setErrorColor;
    this.setFormatoFecha = setFormatoFecha;
    this.setFormatoHora = setFormatoHora;
    this.getErrors = getErrors;
    this.AgregarError = AgregarError;
    this.EliminarError = EliminarError;
    this.Vacio = Vacio;
    this.Email = Email;
    this.Fecha = Fecha;
    this.Hora = Hora;
    this.Iguales = Iguales;
    this.Longitud = Longitud;
    this.Entero = Entero;
    this.Valor = Valor;
    this.Validar = Validar;    
    this.Telefono = Telefono;
    
    
}
//////////////////////////////////////////////////////////////////
