//.................................................................................................................................................
//.................................................................................................................................................
// ARCHIVO.......: "LGValidaciones"        	TIPO : "JS"
// FECHA CREACIÓN: "09/08/2011"			AUTOR/ES: "CORTIZ"
// DESCRIPCIÓN...: Controles añadidos sobre los elementos que componen las pantallas.
// NOTAS.........:
//.................................................................................................................................................
//.................................................................................................................................................

//.................................................................................................................................................
// VARIABLES GLOBALES: Expresiones regulares a utilizar según el tipo de elemento y el idioma
//.................................................................................................................................................

    // Número
    var numeroExp       = "\\d+";

    // Caracter
    var caracterExp     = "[A-Za-z|Ñ|ñ|ç|Ç|&|á|é|í|ó|ú|ñ|ä|ë|ï|ö|ü|Á|É|Í|Ó|Ú|Ä|Ë|Ï|Ö|Ü| ]";

    // Caracter + Número
    var caracNumExp    = "[\\w.,&| |\\.|!|¡|(|=|)|¿|?|\\|Ñ|ñ|ç|Ç|&|á|é|í|ó|ú|ä|ë|ï|ö|ü|Á|É|Í|Ó|Ú|Ä|Ë|Ï|Ö|Ü|À|È|Ò|Ì|Û|à|è|ì|ò|ù]";

    // Decimal
    var decimalExpPress = "[\\d\\.\\,]";
    var decimalExpBlur  = "^[\\d]+([.,]{0,1}\\d+){0,1}$";

    // E-mail
    var emailExpPress   = "[A-Za-z\\d\\.\\-\\_\\@]";
    var emailExpBlur    = "^([\\w\\-\\.]+)@((\\[([0-9]{1,3}\\.){3}[0-9]{1,3}\\])|(([\\w\\-]+\\.)+)([a-zA-Z]{2,4}))$";

    // Fecha
    var fechaExpPress   = "[\\d/]";
    var fechaExpBlurEs  = "\\b(0?[1-9]|[12][0-9]|3[01])[ /.](0?[1-9]|1[012])[ /.](19|20)?[0-9]{2}\\b";
    var fechaExpBlurEn  = "\\b(19|20)?[0-9]{2}[ /.](0?[1-9]|1[012])[ /.](0?[1-9]|[12][0-9]|3[01])\\b";

    // Hora
    var horaExpPress    =  "[0-9\\:]";
    var horaExpBlur     =  "^(([0-1]?[0-9])|([2][0-3])):([0-5]?[0-9])(:([0-5]?[0-9]))?$";

    // Fecha Hora
    var fechaHoraExpPress    =  "[\\d/: ]";
    var fechaHoraExpBlurEs   =  "^(0?[1-9]|[12][0-9]|3[01])[ /.](0?[1-9]|1[012])[ /.](19|20)?[0-9]{2} (([0-1]?[0-9])|([2][0-3])):([0-5]?[0-9])(:([0-5]?[0-9]))?$";
    var fechaHoraExpBlurEn   = "";

//.................................................................................................................................................
// FUNCION: validadarMascaraElemento
// DESCRIPCION: Comprueba que la tecla a indicar en el elemento (onkeypress) o el valor introducido (onblur) cumpla con la mascara asignada al
//              elemento en curso.
//.................................................................................................................................................
// PARAMETROS DE ENTRADA:
// elemento     : Es el elemento htm sobre el que deseamos realizar la validación
// evento       : Captura el evento que ha producido la llamada a la función
// tipo         : Indica el tipo de elemento al que se le va a realizar la validación.
// localizacion : Indica el idioma para definir el formato con el que se está trabajando. Ej: es – Español, en – Inglés. Sirve de utilidad para formatear, por ejemplo, los números.
// mascara      : Expresión regular que deberemos utilizar para comprobar si lo introducido en el elemento es correcto.
// mensaje      : Indica el mensaje a mostrar al usuario en caso de producirse un error.
//.................................................................................................................................................
// PARAMETROS DE SALIDA: Booleano
//.................................................................................................................................................
function validadarMascaraElemento(elemento, evento, tipo, localizacion, mensaje) {

    var mascara = obtenerMascaraElemento(evento, tipo, localizacion);

    if(typeof mascara == "undefined") alert("No hay máscara para el tipo '"+tipo+"'");

    var tecla = evento.which;    // Tecla presionada

    if(tecla < 32) return true;  // Permitir carácteres no representables (backspace, cancel, escape,...) para evitar problemas con navegadores

    var elementoValor   = (evento.type == "blur")? elemento.value : String.fromCharCode(tecla); // Valor actual del elemento o de la tecla pulsada
    var expresion       = new RegExp(mascara);                                                  // Convertir mascara en expresión regular

    if(elementoValor.match(expresion) != null){
        return true;
    }else{
        if(mensaje != "" && elementoValor != "") marcarElementoErroneo(elemento, mensaje);
        return false;
    }    
}

//.................................................................................................................................................
// FUNCION: obtenerMascaraElemento
// DESCRIPCION: Retorna la mascara a utilizar según el tipo de elemento, el evento y idioma.
//.................................................................................................................................................
// PARAMETROS DE ENTRADA:
// evento       : Captura el evento que ha producido la llamada a la función
// tipo         : Indica el tipo de elemento al que se le va a realizar la validación.
// localizacion : Indica el idioma para definir el formato con el que se está trabajando. Ej: es – Español, en – Inglés. Sirve de utilidad para formatear, por ejemplo, los números.
//.................................................................................................................................................
// PARAMETROS DE SALIDA: Cadena con la mascara escapada.
//.................................................................................................................................................
function obtenerMascaraElemento(evento, tipo, localizacion){
    switch(tipo){
        case "lg-numero":       return numeroExp; break;
        case "lg-caracter":     return caracterExp; break;
        case "lg-caracNum":     return caracNumExp; break;
        case "lg-decimal":
            switch(evento.type){
                case "keypress":return decimalExpPress;
                case "blur":    return decimalExpBlur;
            }
            break;
        case "lg-email":
            switch(evento.type){
                case "keypress":return emailExpPress;
                case "blur":    return emailExpBlur;
            }
            break;
        case "lg-fecha":
            switch(evento.type){
                case "keypress":return fechaExpPress;
                case "blur":    switch(localizacion){
                                    case "es": return fechaExpBlurEs; break;
                                    case "en": return fechaExpBlurEn; break;
                                }
            }
            break;
        case "lg-hora":
            switch(evento.type){
                case "keypress":return horaExpPress;
                case "blur":    return horaExpBlur;
            }
            break;
        case "lg-fechaHora":
            switch(evento.type){
                case "keypress":return fechaHoraExpPress;
                case "blur":    switch(localizacion){
                                    case "es": return fechaHoraExpBlurEs; break;
                                    case "en": return fechaHoraExpBlurEn; break;
                                }
            }
            break;
        case "lg-texto": return caracNumExp; break;
        case "lg-clave": return caracNumExp; break;
        default: break;
    }
}

//.................................................................................................................................................
// FUNCION: realizarControles
// DESCRIPCION: Comprueba, siempre que se haya indicado alguno de los parámetros extras, que el valor final del elemento cumpla lo especificado.
//.................................................................................................................................................
// PARAMETROS DE ENTRADA:
// elemento     : Es el elemento htm sobre el que deseamos realizar la validación
// evento       : Captura el evento que ha producido la llamada a la función
// tipo         : Indica el tipo de elemento al que se le va a realizar la validación.
// valorMinimo  : Indica el valor mínimo permitido.
// valorMaximo  : Indica el valor máximo permitido.
// multiplo     : Indica el valor que deseamos utilizar como múltiplo para los posibles valores indicados por los usuarios en el elemento de pantalla.
// mayusculas   : Indica que el valor del elemento se debe transformar a mayúsculas el valor del elemento.
// quitarAcento : Indica que se deben extraer los signos de puntuación del valor del elemento.
// longitud     : En el caso de un elemento de tipo decimal, por ejemplo, no servirá para identificar el tamaño máximo de la parte entera.
// precision    : En el caso de un elemento de tipo decimal, por ejemplo, no servirá para identificar el tamaño máximo de la parte decimal.
// mensaje      : Indica el mensaje a mostrar al usuario en caso de producirse un error.
//.................................................................................................................................................
// PARAMETROS DE SALIDA: Booleano
//.................................................................................................................................................
function realizarControles(elemento, evento, tipo, valorMinimo, valorMaximo, multiplo, mayusculas, quitarAcento, longitud, precision, mensaje){

    var elementoValor   = elemento.value // Valor actual del elemento
    var mensajeExtra    = "";
    var indicador       = 0;
    var retorno         = true;

    if(elementoValor != ""){
        switch(tipo){
            case "lg-numero": 
                // Si se ha indicado un valor mínimo y/o máximo comprobamos que el valor indicado este entre dicho parámetros.
                if(valorMinimo > 0 || valorMaximo >0){                    
                    if(elementoValor >= valorMinimo && elementoValor <= valorMaximo) retorno = true;
                    else indicador = 1;
                }
                if(multiplo > 0){                    
                    if((elementoValor % multiplo) == 0) retorno = true;
                    else indicador = (indicador == 1)? 2 : 3;
                }
                if(indicador != 0){
                    switch(indicador){
                        case 1: mensajeExtra = "El valor introducido debe estar entre " + valorMinimo.toString() + " y " + valorMaximo.toString(); break;
                        case 2: mensajeExtra = "El valor introducido debe estar entre " + valorMinimo.toString() + " y " + valorMaximo.toString() + " y/o ser multiplo de " + multiplo.toString(); break;
                        case 3: mensajeExtra = "El valor introducido debe ser multiplo de " + multiplo.toString(); break;
                    }
                    marcarElementoErroneo(elemento, (mensaje+" "+mensajeExtra));
                }
                return retorno;
                break;
            case "lg-caracter":
                if(mayusculas) elementoValor = elementoValor.toUpperCase();
                if(quitarAcento) elementoValor = (mayusculas)?  elementoValor.toUpperCase().eliminarSignosPuntuacion() : elementoValor.eliminarSignosPuntuacion();
                break;
            case "lg-caracNum": break; //mayúsculas + obligatorio
            case "lg-decimal":
                elementoValor = elementoValor.replace(" ","");
                if(elementoValor != ""){
                    elementoValor = (evento.type == "blur")? decimalAImporte(elemento.value,longitud,precision) : importeADecimal(elemento.value, precision);
                }
                break;  
            case "lg-email": break;
            case "lg-fecha": break;
            case "lg-hora": break;
            case "lg-fechaHora": break;
            case "lg-texto": break;
            case "lg-clave": break;
            default: break;
        }
        elemento.value = elementoValor;
    }
    return true;
}

//.................................................................................................................................................
// MÉTODO: marcarElementoErroneo
// DESCRIPCION: Se encarga de informar a los usuarios de que el valor que se desea indicar en el elemento no cumple el formato especificado y
//              marca dicho elemento como erroneo añadiendole una clase.
//.................................................................................................................................................
// PARAMETROS DE SALIDA: Mensaje informativo tipo alert
//.................................................................................................................................................
function marcarElementoErroneo(elemento, mensaje){
    //Aqui faltaría que se marque el elemento como erroneo y se podría hacer que en lugar de un alert muestre una capa informativa flotante sobre
    //el elemento
    alert(mensaje);
}

//.................................................................................................................................................
// MÉTODO: eliminarSignosPuntuacion
// DESCRIPCION: Método añadido a la clase String para eliminar los signos de puntuación de la cadena deseada
//.................................................................................................................................................
// PARAMETROS DE SALIDA: Cadena alterada
//.................................................................................................................................................
String.prototype.eliminarSignosPuntuacion = function(){

    var str = "";

    return result = this.replace(/á|é|í|ó|ú|ñ|ä|ë|ï|ö|ü/ig, function (str, salida, s) {

        str = str == "á"? "a" : str == "é" ? "e" : str == "í" ? "i" : str == "ó" ? "o" : str == "ú" ? "u" : str; 
        str = str == "Á"? "A" : str == "É" ? "E" : str == "Í" ? "I" : str == "Ó" ? "O" : str == "Ú" ? "U" : str;
        str = str == "ä"? "a" : str == "ë" ? "e" : str == "ï" ? "i" : str == "ö" ? "o" : str == "ü" ? "u" : str;
        str = str == "Ä"? "A" : str == "Ë" ? "E" : str == "Ï" ? "I" : str == "Ö" ? "O" : str == "Ü" ? "U" : str;
        str = str == "ñ"? "n" : str == "Ñ" ? "N" : str;
        //str = str == "ç"? "c" : str == "Ç" ? "C" : str;

        return (str);

        });
}

//.................................................................................................................................................
// FUNCION: importeADecimal
// DESCRIPCION: Dado un string numérico devuelve un decimal. El último punto o coma indicará la parte decimal, debido a esto eliminarß el resto,
//              entendiendo que son separadores de millares.
//.................................................................................................................................................
// PARAMETROS DE SALIDA: Valor en formato decimal
//.................................................................................................................................................
function importeADecimal(valor, decimales) {

	decimales   = (typeof decimales == "undefined" || decimales.length == 0 || decimales == null) ? true : decimales;

	if (valor == null || valor.length < 0) return valor;
    
        var result  = "";
	var coma    = valor.lastIndexOf(",");
	var punto   = valor.lastIndexOf(".");
	var pos     = -1;
	var lon     = valor.length;

	if (coma != -1) {
            if (punto != -1) pos = (punto > coma)? punto : coma;
            else pos = coma
	} else {
            if (punto != -1) pos = punto;
	}

	if (pos != -1) lon -= (lon - pos);

	for (idx=0;idx<lon;idx++) {
            if ((valor.charAt(idx) != ",") && (valor.charAt(idx) != ".") && (valor.charAt(idx) != " ")) {result+=valor.charAt(idx);}
	}

	if (pos != -1) {
            var separador = (decimales)? "." : "";
            result+= separador + valor.substring(pos + 1,valor.length);
	}

	return result;
}

//.................................................................................................................................................
// FUNCION: decimalAImporte
// DESCRIPCION: Dado un valor decimal (expresión numérica con '.' o una ',' como separador de decimales) devuelve un string con la representación
//              del valor decimal con '.' como separadores de millares, con ',' como separador decimal y con longitud y la precisión indicada.
//.................................................................................................................................................
// PARAMETROS DE SALIDA: Valor en formato importe
// ************************************************************************************************************************************************
function decimalAImporte(valor,longitud,precision){

    var punto           = valor.lastIndexOf(".");
    var parteEntera     = "";
    var parteDecimal    = "";
    var miles           = 0;
    var resultado       = ""; 

    if (punto == -1) punto = valor.lastIndexOf(",");
    
    if (punto != -1) parteDecimal = valor.substring(punto + 1,valor.length);
    else punto = valor.length;
    
    parteEntera     = (punto == 0 || valor.length == 0)? "0" : valor.substring(0, punto);
    parteDecimal    = parteDecimal + repetirCaracter("0", precision - parteDecimal.length);
    
    if (parteEntera.substring(0,1) == '-') {
        parteEntera = parteEntera.substring(1,parteEntera.length);
        miles       = Math.ceil((parteEntera.length) / 3);
        parteEntera = '-' + parteEntera;
    } else {
        miles       = Math.ceil((parteEntera.length) / 3);
    }

    if (miles > 1) {
        for (idx=1;idx<miles;idx++) {
            posPuntoMil = parteEntera.length - (((idx - 1 ) * 4) + 3);
            parteEntera = parteEntera.substring(0, posPuntoMil) + '.' + parteEntera.substring(posPuntoMil, parteEntera.length);
        }
    }

    resultado = (precision == 0)? parteEntera: parteEntera + "," + parteDecimal;
    resultado = repetirCaracter(" ", longitud - resultado.length) + resultado;
    
    return resultado;
}

//.................................................................................................................................................
// FUNCION: repetirCaracter
// DESCRIPCION: Dado un carater devuelve un string con ese caracter repetico el número de veces indicado.
//.................................................................................................................................................
// PARAMETROS DE SALIDA: Valor
//.................................................................................................................................................
function repetirCaracter(caracter,veces){
    var resultado = "";
    if (veces > 0) for(idx=1;idx<= veces;idx++) {resultado = resultado + caracter;}
    return resultado;
}
