// *******************************************************************
// *******************************************************************
// **
// ** Funciones para MOWE_Validacion (Sistema de validación Web)
// ** Autor y desarrollador: Fco. Javier Pérez Pacheco
// ** Versión: 1.0.0.0000
// **
// ** MOWE_Validación es un sistema para facilitar la validación de
// ** formularios dentro de una web.
// **
// ** El sistema debe funcionar en IE 5 y superiores, NetScape 6
// ** y superiores y Mozilla 1 y superiores
// **
// ** [..]
// **
// ** MW_nombre: Este atributo contiene el nombre del campo que aparecerá en 
// ** el alert en el caso de que apareciese algún error.
// **
// *******************************************************************
// *******************************************************************

// *******************************************************************
// *******************************************************************
// ** Archivo: mowev.js
// ** Código original: Fco. Javier Pérez Pacheco
// ** Versión actual: 2.0.0.031210 - Pablo de la Torre
// **    - Modificación del nombre del archivo a mowev.js
// **    - Se eliminan los caracteres del principio y el final al evaluar.
// **    - mw_validar se llama ahora mwv_validation
// **    - mw_nombre se llama ahora mwv_name
// **    - mw_error se llama ahora mwv_msgerror
// **    - La función validar se llama ahora Validar
// **    - Todas las funciones se han pasado a mayúscula
// **    - Modificación de los parámetros de validación. Ahora son:
// **
// **       : number(\.)?(\[+?\-?\])?(\(d?,d?\))?\? : Comprueba si el campo es numérico
// **                 ^         ^            ^      ^
// **                 |         |            |      |
// **                 |         |            |      ----- Opcional
// **                 |         |            ------------ Rango
// **                 |         ------------------------- Signo
// **                 ----------------------------------- Decimal
// **
// **           : number.(10,20) : Real sin signo entre 10 y 20.
// **           : number[-]? : Entero negativo no obligatorio.
// **           : number[+-](-34,-23) : Entero con signo entre -34 y - 23.
// **           : number[+-](,34) : Entero con signo menor que 34.
// **
// **       : text([^.+])?(\(d?,d?\)?(\?)? : Comprueba que es un texto.
// **                ^        ^      ^
// **                |        |      |
// **                |        |      ----- Opcional
// **                |        ------------ Rango de caracteres
// **                --------------------- Caracteres no permitidos
// **
// **           : text(23,) : Texto de más de 23 caracteres.
// **           : text[^&?]? : Texto opcional sin el carácter & ni ?.
// **           : text : Texto obligatorio.
// **
// **       : type\[.+\]\? : Comprueba si el campo es del tipo indicado
// **                ^   ^
// **                |   |
// **                |   ----- Opcional
// **                --------- Tipo (debe estar definido en este js)
// **
// **           : type[CIF] : CIF obligatorio.
// **           : type[NIF]? : NIF opcional.
// **           : type[Email] : Correo obligatorio.
// **
// **       : equals-to\[.+\] : Automatiza la dependencia de un campo a otro
// **                    ^
// **                    |
// **                    ----- Campo
// **
// **           : equals-to[Correo] : Igual que el campo Correo.
// **
// **       : expression\[\/.+\/\] : Expresión regular
// **                       ^
// **                       |
// **                       ----- Expresión
// **
// **           : expression[\^([A-Za-z][0-9]{8})?$\] : Evalúa si es un correo.
// **
// **       : date.(s|l)\? : Evalúa una fecha
// **             ^  ^   ^
// **             |  |   |
// **             |  |   ----- Opcional
// **             |  --------- Corta (dd/mm/aa) o larga (dd/mm/aaaa)
// **             ------------ Separador
// **
// **    - Esta versión emplea expresiones regulares para evaluar los propios
// **      atributos de entrada. Con la expresión evaluada, genera la expresión
// **      regular definitiva.
// **    - Se añaden errores de tipo FATAL, que aparecen en las siguientes
// **      circunstancias: cuando mvw_validation contiene una expresión que
// **      no se ajusta a los patrones de dicho atributo; cuando se utiliza el 
// **      patrón type[{tipo}], no estando {tipo} definido en el array de
// **      tipos; y cuando se utiliza equals-to con un campo que no existe
// **      en el formulario.
// **    - mwv_msgerror aparece en los tipos type si está definida, con prioridad
// **      sobre el mensaje por defecto. También aparece en expression, como
// **      estaba definido en la versión anterior.
// **    - Arreglada la necesidad de añadir el atributo mwv_validation en todos
// **      los campos, aunque no se deseen validar, por compatibilidad con IE5.
// **    - Con objeto de optimizar el sistema, una vez arreglado lo anterior,
// **      si el atributo mwv_validation es una cadena vacía, se considerará 
// **      un patrón inválido.
// **    - El sistema comprueba que todo elemento a validar tiene el atributo
// **      mwv_name, generando un FATAL si no lo encuentra.
// **
// *******************************************************************
// *******************************************************************

// *******************************************************************
// *******************************************************************
// ** Archivo: mowev.js
// ** Código original: Fco. Javier Pérez Pacheco
// ** Versión actual: 2.0.1.040315 - Pablo de la Torre
// ** 
// **    - Se añade Gs_EEspacio para indicar que el espacio es obligatorio
// **      si se incluye la forma text[^ ].
// *******************************************************************
// *******************************************************************

// ********************************************
// ** Variables globales
// ********************************************
var sFormulario;
var sError = "";

// ********************************************
// ** Definición de tipos para la entrada type
// ********************************************
var iNumTipos = 4;
var asTipo_expresion = new Array(iNumTipos);
var asTipo_ejemplo = new Array(iNumTipos);

// Nota: no añadir en las expresiones regulares de los tipos
// los patrones ^ y $, al principio y final, respectivamente.
// Se hace automáticamente.

var iTipo_NIF = 0; // Se le invoca con type[NIF]
asTipo_expresion[iTipo_NIF] = "[0-9]{8}[A-Za-z]";
asTipo_ejemplo[iTipo_NIF] = "99999999A";

var iTipo_CIF = 1; // Se le invoca con type[CIF]
asTipo_expresion[iTipo_CIF] = "[0-9]{8}[A-Za-z]";
asTipo_ejemplo[iTipo_CIF] = "99999999A";

var iTipo_Email = 2; // Se le invoca con type[Email]
asTipo_expresion[iTipo_Email] = ".+@.+\..+";
asTipo_ejemplo[iTipo_Email] = "micorreo@miservidor.com";

var iTipo_HTTP = 3; // Se le invoca con type[HTTP]
asTipo_expresion[iTipo_HTTP] = "http://.+";
asTipo_ejemplo[iTipo_HTTP] = "http://www.miservidor.com";

// ******************************************+
// ** Funciones
// ******************************************+
function RTrim(sCadena)
{
	while (sCadena.charAt(sCadena.length - 1) == ' ')
		sCadena = sCadena.substr(0, sCadena.length - 2);
	return sCadena;
}

function CargarIdioma(sIdioma)
{
	// ********************************************
	// ** Esta función pone los textos en diferentes idiomas
	// ** 
	// ** sIdioma: Contiene el idioma
	// ** 
	// ********************************************

	switch (sIdioma) {
		case "en":
			Gs_ECabeceraError = "Next errors have ocurred: \n";
			Gs_EEjemplo = "example: ";
			Gs_EY = " and ";
			Gs_EDebeContenerValor = "must have a value";
			Gs_FCampoSinNombre = "field hasn't attribute 'mwv_name'. Please, contact with product's supplier";
			Gs_EEspacio = "space";
			
			Gs_FMowevIncorrecto = "invalid pattern. Please, contact with product's supplier";
			
			Gs_ENumberA = " is not a valid ";
			Gs_ENumberDecimal = " decimal"
			Gs_ENumberConSigno = " with sign"
			Gs_ENumberB = " number";
			Gs_ENumberMenorQue = " must have as minimum ";
			Gs_ENumberMayorQue = " must have as maximum ";
			Gs_ENumberEntreA = " must have between ";
			
			Gs_ETextNoDebeContener = "mustn't have characters ";
			Gs_ETextDebeTener = "must have ";
			Gs_ETextMenosDe = "less than ";
			Gs_ETextMasDe = "more than ";
			Gs_ETextCaracteres = " characters";
			
			Gs_ETypeNoEsCorrecto = " isn't correct";
			Gs_FTypeTipoNoExiste = " type doesn't exist. Please, contact with product's supplier";
			
			Gs_EEqualsToEsDiferente = " is different to ";
			Gs_FEqualsToCampoNoExiste = " destiny field doesn't exist. Please, contact with product's supplier";

			Gs_EDateNoEsCorrecto = "date is not correct";
		break;
		default:
			Gs_ECabeceraError = "Se han producido los siguientes errores: \n";
			Gs_EEjemplo = "ejemplo: ";
			Gs_EY = " y ";
			Gs_EDebeContenerValor = "debe contener un valor";
			Gs_FCampoSinNombre = "el campo no tiene el atributo 'mwv_name'. Por favor, contacte con el suministrador del producto";
			Gs_EEspacio = "espacio";
			
			Gs_FMowevIncorrecto = "patrón inválido. Por favor, contacte con el suministrador del producto";
			
			Gs_ENumberA = " no es un número válido";
			Gs_ENumberDecimal = " decimal"
			Gs_ENumberConSigno = " con signo"
			Gs_ENumberB = "";
			Gs_ENumberMenorQue = " debe ser menor que ";
			Gs_ENumberMayorQue = " debe ser mayor que ";
			Gs_ENumberEntre = " debe estar entre ";
			
			Gs_ETextNoDebeContener = "no debe contener caracteres ";
			Gs_ETextDebeTener = "debe tener ";
			Gs_ETextMenosDe = "menos de ";
			Gs_ETextMasDe = "más de ";
			Gs_ETextCaracteres = " caracteres";
			
			Gs_ETypeNoEsCorrecto = " no es correcto";
			Gs_FTypeTipoNoExiste = " el tipo no existe. Por favor, contacte con el suministrador del producto";
					
			Gs_EEqualsToEsDiferente = " es diferente a ";
			Gs_FEqualsToCampoNoExiste = " el campo destino no existe. Por favor, contacte con el suministrador del producto";
			
			Gs_EDateNoEsCorrecto = "la fecha no es correcta";
		break;
	}
}

function Validar(sForm, sIdioma)
{
	// ********************************************
	// ** Esta función recoge todos los campos y según su tipo y la valición que tenga
	// ** lo envía a la función correspondiente.
	// ** 
	// ** sFormulario: Contiene el name del formulario
	// ** sIdioma: Contiene el idioma
	// ** 
	// ********************************************

	sFormulario = sForm;
	
	CargarIdioma (sIdioma);
	
	eval ("var cInput = document." + sFormulario + ".getElementsByTagName(\"input\");");

	for (i = 0; i < cInput.length; i++)
	{
		var elemento = cInput[i];
		switch (elemento.type)
		{
			case "text": ValidarGenerico(elemento); break;
			case "hidden": ValidarGenerico(elemento); break;
			case "file": ValidarGenerico(elemento); break;
			case "checkbox": ValidarCheck(elemento); break;
			case "password": ValidarGenerico(elemento);	break;
			case "radio": break;
			case "submit": break;
			default: break;
		}
	}
	
	eval ("var cSelect = document." + sFormulario + ".getElementsByTagName(\"select\");");
	for (i = 0; i < cSelect.length; ValidarGenerico(cSelect[i++]));
	
	eval ("var cTextArea = document." + sFormulario + ".getElementsByTagName(\"textarea\");");
	for (i = 0; i < cTextArea.length; ValidarGenerico(cTextArea[i++]));

	if (sError != "")
	{
		sError = Gs_ECabeceraError + sError;
		alert(sError);
		document.continuar = false;
	}
	else
		document.continuar = true;

	sError = "";
}

function ValidarGenerico(cCampo)
{
	// ********************************************
	// ** Esta función envía a la función correspondiente
	// ** 
	// ** CAMPOS DE LA FUNCIÓN:
	// ** 
	// ** cCampo: Este campo contiene el objeto a validar
	// ** 
	// ********************************************

	var sValidacion = cCampo.getAttribute('mwv_validation');

	if (sValidacion != null) // El null es para compatibilidad con IE5
	{
		if (cCampo.getAttribute('mwv_name') != null)
		{
			var bEncontrado = false;

			var erExpresion = /^number(\.)?(\[(\+)?(\-)?\])?(\((\d+)?,(\d+)?\))?(\?)?$/
			if (erExpresion.test(sValidacion))	{ bEncontrado = true; ComprobarNumber(cCampo); }
			
			erExpresion = /^text(\[\^(.+)\])?(\((\d+)?,(\d+)?\))?(\?)?$/
			if (erExpresion.test(sValidacion))	{ bEncontrado = true; ComprobarText(cCampo); }
			
			erExpresion = /^type\[(.+)\](\?)?$/
			if (erExpresion.test(sValidacion))	{ bEncontrado = true; ComprobarType(cCampo); }
			
			erExpresion = /^equals-to\[(.+)\]$/
			if (erExpresion.test(sValidacion))	{ bEncontrado = true; ComprobarEqualsTo(cCampo); }
			
			erExpresion = /^expression\[(.+)\]$/
			if (erExpresion.test(sValidacion))	{ bEncontrado = true; ComprobarExpression(cCampo); }
				
			erExpresion = /^date(.)(s|l)(\?)?$/
			if (erExpresion.test(sValidacion)) { bEncontrado = true; ComprobarDate(cCampo); }
			
			if (!bEncontrado)
				sError += "  - '" + cCampo.getAttribute('mwv_name') + "' : FATAL : " + 
					Gs_FMowevIncorrecto + " (mwv_validation: " + sValidacion + ").\n";
		}
		else
			sError += "  - FATAL : " + Gs_FCampoSinNombre + " (mwv_validation: " + sValidacion + ").\n";
	}
}

function ValidarCheck(cCampo)
{
	// ********************************************
	// ** Esta función envía a la función correspondiente para CheckBoxs
	// ** Aunque esta función parezca que no es útil, si lo es en el caso
	// ** de que se tengan que aceptar una Condiciones
	// ** 
	// ** CAMPOS DE LA FUNCIÓN:
	// ** 
	// ** cCampo: Este campo contiene el objeto a validar
	// ** 
	// ********************************************

	if (!cCampo.attributes['mwv_validation'])
		bValidar = true;
	else
		bValidar = cCampo.attributes['mwv_validation'];

	if (bValidar)  // comprueba si el campo de validación existe
	{
	}
}

function ComprobarNumber(cCampo)
{
	// ********************************************
	// ** Descripción:
	// **   Comprueba que la función es un número.
	// ** 
	// ** Parámetros:
	// **   cCampo: Objeto a validar.
	// ** 
	// ********************************************

	var sExpresion = '', sEjemplo1 = '', sEjemplo2 = ''
	var sErrorInterno = '';
	var sCampo = cCampo.getAttribute('mwv_name');
	
	if (RegExp.$2 != '') // [+-]
	{
		sExpresion += '[';
		// Signo +	
		if (RegExp.$3 != '') sExpresion += '+';
		// Signo -
		if (RegExp.$4 != '')
		{
			sExpresion += '\\-';
			sEjemplo2 = '-';
		}
		if (sExpresion != '')
		{
			sExpresion += ']?';
			sErrorInterno = Gs_ENumberConSigno;
		}
	}
	
	sExpresion += '(\\d)+';
	sEjemplo1 += '425';
	sEjemplo2 += '12';
	
	// . (decimal)
	if (RegExp.$1 != '')
	{
		sExpresion += '(\\.(\\d)+)?';
		sEjemplo1 += '.32';
		sErrorInterno = Gs_ENumberDecimal + sErrorInterno;
	}
	
	// ? (opcional)
	if (RegExp.$8 != '') sExpresion = '(' + sExpresion + ')?';
	sExpresion = '^' + sExpresion + '$';
	
	var sValor_minimo = RegExp.$6; // Valor mínimo
	var sValor_maximo = RegExp.$7; // Valor máximo
	
	var sValor = RTrim(cCampo.value.replace(/^( *)(.+)( +)?$/,"$2"));
	var erExpresion = new RegExp(sExpresion);
	if (!erExpresion.test(sValor))
		sError += "  - '" + sCampo + "'" + Gs_ENumberA + sErrorInterno + Gs_ENumberB + 
			" (" + Gs_EEjemplo + sEjemplo1 + ", " + sEjemplo2 + ").\n";
	else
	{
		var fValor = eval(sValor);
		var fValor_minimo = eval(sValor_minimo);
		var fValor_maximo = eval(sValor_maximo);
		
		if (sValor_minimo != '')
		{
			if (sValor_maximo != '')
			{
				if (fValor < fValor_minimo || fValor > fValor_maximo)
					sError += "  - '" + sCampo + "' " + Gs_ENumberEntre + sValor_minimo + 
						Gs_EY + fValor_maximo + ".\n";
			}
			else 
				if (fValor < fValor_minimo)
					sError += "  - '" + sCampo + "' " + Gs_ENumberMenorQue + fValor_minimo + ".\n"
		}
		else 
			if (fValor > fValor_maximo)
				sError += "  - '" + sCampo + "' " + Gs_ENumberMayorQue + fValor_maximo + ".\n"
	}
}

function ComprobarText(cCampo)
{
	// ********************************************
	// ** Descripción:
	// **   Comprueba que la función es un texto.
	// ** 
	// ** Parámetros:
	// **   cCampo: Objeto a validar.
	// ** 
	// ********************************************

	var sExpresion = '';
	var sErrorInterno = '';
	var sCampo = cCampo.getAttribute('mwv_name');
	
	if (RegExp.$2 != '') // Elementos no válidos
	{
		sExpresion += '[^' + 
			RegExp.$2.replace("\\", "\\\\").replace("-", "\\-").replace("^", "\\^") + "]";
		sErrorInterno += Gs_ETextNoDebeContener + " [" + 
			RegExp.$2.replace(" ","[" + Gs_EEspacio + "]") + "] " + Gs_EY;
	}
	else
		sExpresion += '.';

	var sLongitud_minima = RegExp.$4;
	var sLongitud_maxima = RegExp.$5;
	if (sLongitud_minima != '' || sLongitud_maxima != '') // Mínimo y máximo de caracteres
	{
		sErrorInterno += Gs_ETextDebeTener;
		if (sLongitud_minima == sLongitud_maxima)
		{
			sExpresion += '{' + sLongitud_minima + '}';
			sErrorInterno += sLongitud_minima;
		}
		else
		{
			sExpresion += '{' + sLongitud_minima + "," + sLongitud_maxima + '}';		
			if (sLongitud_minima != '')
				sErrorInterno += Gs_ETextMasDe + sLongitud_minima;
			if (sLongitud_maxima != '')
			{
				if (sLongitud_minima != '') sErrorInterno += Gs_EY;
				sErrorInterno += Gs_ETextMenosDe + sLongitud_maxima;
			}
		}
		sErrorInterno += Gs_ETextCaracteres;
	}			
	else
	{
		sExpresion += '+';
		sErrorInterno += Gs_EDebeContenerValor;
	}
	
	// ? (opcional)
	if (RegExp.$6 != '') sExpresion = '(' + sExpresion + ')?';
	
	sExpresion = '^' + sExpresion + '$';
	var sValor = RTrim(cCampo.value.replace(/^( *)(.+)( +)?$/,"$2"));

	var erExpresion = new RegExp(sExpresion);
	if (!erExpresion.test(sValor))
		sError += "  - '" + sCampo + "' " + sErrorInterno + ".\n";
}

function ComprobarType(cCampo)
{
	// ********************************************
	// ** Descripción:
	// **   Comprueba que la función de un tipo predefinido.
	// ** 
	// ** Parámetros:
	// **   cCampo: Objeto a validar.
	// ** 
	// ********************************************

	var sExpresion = '';
	var sCampo = cCampo.getAttribute('mwv_name');
	
	try
	{
		iTipo = eval("iTipo_" + RegExp.$1);
	}
	catch (exception)
	{
		sError += "  - '" + sCampo + "' : FATAL : " + Gs_FTypeTipoNoExiste + " (type: " + RegExp.$1 + ").\n";
		return;
	}
	
	var sExpresion = asTipo_expresion[iTipo];
	var sEjemplo = asTipo_ejemplo[iTipo];
	
	// ? (opcional)
	if (RegExp.$2 != '') sExpresion = '(' + sExpresion + ')?';
	
	sExpresion = '^' + sExpresion + '$';
	var sValor = RTrim(cCampo.value.replace(/^( *)(.+)( +)?$/,"$2"));
		
	var erExpresion = new RegExp(sExpresion);
	if (!erExpresion.test(sValor))
	{
		var sMsgError = cCampo.getAttribute('mwv_msgerror');
		if (sMsgError == null)
			sError += "  - '" + sCampo + "'" + Gs_ETypeNoEsCorrecto + " (" + Gs_EEjemplo + sEjemplo + ").\n";
		else
			sError += "  - '" + sCampo + "' " + sMsgError + "\n";
	}
}

function ComprobarEqualsTo(cCampo)
{
	// ********************************************
	// ** Comprueba si el campo tiene el mismo valor que otro
	// ** 
	// ** Parámetros:
	// **   cCampo: Objeto a validar.
	// ** 
	// ********************************************

	var sCampo = cCampo.getAttribute('mwv_name');
	eval("var cCampo_destino = document." + sFormulario + "." + RegExp.$1 + ";");
	if (cCampo_destino == null)
	{
		sError += "  - '" + sCampo + "' : FATAL : " + Gs_FEqualsToCampoNoExiste + " (input: " + RegExp.$1 + ").\n";
		return;
	}
	if (cCampo.value != cCampo_destino.value)
     	sError = sError + "  - '" + sCampo + "'" + Gs_EEqualsToEsDiferente + "'" +
     		cCampo_destino.getAttribute('mwv_name') + "'.\n";
}

function ComprobarExpression(cCampo)
{
	// ********************************************
	// ** Comprueba la expresion regular
	// ** 
	// ** Parámetros:
	// **   cCampo: Objeto a validar.
	// ** 
	// ********************************************

	var sCampo = cCampo.getAttribute('mwv_name');
	var erExpresion = new RegExp(RegExp.$1);
 
    if (!erExpresion.test(cCampo.value))
      		sError = sError + "  - '" + sCampo + "': " + cCampo.getAttribute('mwv_msgerror') + "\n";
}

function ComprobarDate(cCampo)
{
	// ********************************************
	// ** Descripción:
	// **   Comprueba que la función de una fecha
	// ** 
	// ** Parámetros:
	// **   cCampo: Objeto a validar.
	// ** 
	// ********************************************

	var sExpresion = '';
	var sEjemplo = '';
	var sCampo = cCampo.getAttribute('mwv_name');
	var bOpcional = false;
	
	var sSeparador = RegExp.$1.replace("\\", "\\\\").replace("+", "\\+").replace("-", "\\-");
	
	sExpresion = "(\\d{1,2})" + sSeparador + "(\\d{1,2})" + sSeparador +
		"(\\d{" + (RegExp.$2=='s'?'2':'4') + "})";
	if (RegExp.$2 == 's')
		sEjemplo = '24' + RegExp.$1.replace("\\", "\\\\") + "11" +
			RegExp.$1.replace("\\", "\\\\") + "02";
	else
		sEjemplo = '24' + RegExp.$1.replace("\\", "\\\\") + "11" +
			RegExp.$1.replace("\\", "\\\\") + "2002";

	// ? (opcional)
	if (RegExp.$3 != '')
	{
		bOpcional = true;
		sExpresion = '(' + sExpresion + ')?';
	}

	sExpresion = '^' + sExpresion + '$';
	
	var sValor = RTrim(cCampo.value.replace(/^( *)(.+)( +)?$/,"$2"));

	var erExpresion = new RegExp(sExpresion);
	if (!erExpresion.test(sValor))
	{
		sError += "  - '" + sCampo + "': " + Gs_EDateNoEsCorrecto + " (" + Gs_EEjemplo + sEjemplo + ").\n";
		return;
	}

	if (sValor == '') return;
	
	var iDia, iMes, iAnno;
	if (bOpcional)
	{
		iDia = eval(RegExp.$2); iMes = eval(RegExp.$3);	iAnno = eval(RegExp.$4);
	}
	else
	{
		iDia = eval(RegExp.$1); iMes = eval(RegExp.$2); iAnno = eval(RegExp.$3);
	}

	var iDiasFebrero = ((iAnno/4) == Math.floor(iAnno/4))?29:28;
	if (iMes < 1 || iMes > 12 || iDia > 31 ||
		((iMes == 4 || iMes == 6 || iMes == 9 || iMes == 11) && iDia > 30) ||
		(iMes == 2 && iDia > iDiasFebrero))
		sError += "  - '" + sCampo + "': " + Gs_EDateNoEsCorrecto + " (" + Gs_EEjemplo + sEjemplo + ").\n";		
}