document.validaciones_js = true;

//se utiliza junto con la funcion existeRefresco() en el servidor
//en cada submit voluntario que se quiera hacer se deveria llamar a esta funcion que asignara un 
//valor distinto para la cookie de sesión "lastsubmit"
function prevenirRefresco(){
	document.cookie='lastsubmit='+Math.random()+' '+new Date().getTime()+';path=/';
}//prevenirRefresco
/***********************************/
//devuelve true si detecta algun cambio realizado por el usuario en el formulario o false en caso contrario
function cambiosFormulario(formu){
	var i,j,e, cambios = false, haycambios = false;
	for(i = 0; i<formu.elements.length; i++){
		e = formu.elements[i];
		switch (e.type){
		case "radio":
		case "checkbox":
			if (e.checked != e.defaultChecked){
				//alert(e.name);
				cambios = true;
				break;
			}
			break;
		case "select-one":
		case "select-multiple":
			for (j = 0; j<e.options.length; j++){
				if (e.options[j].selected!=e.options[j].defaultSelected){
					//alert(e.name);					
					cambios = true;
					break;
				}
			}//for
			break;
		case "file":
		case "text":
		case "textarea":
		case "password":
			if (e.value!=e.defaultValue){
				//alert(e.name);
				cambios = true;
				break;
			}
			break;
		}//switch
		if (cambios){
			//break;
			e.style.color = "red";
			cambios = false;
			haycambios = true;
		}
	}//for
	//if (cambios){ e.style.backgroundColor = "red";	}
	
	return haycambios; //no se han detectado cambios realizados por el usuario
}//cambiosFormulario
/**********************************************/
//dice si un precio es válido o no
function validarPrecio(precio){
	if (validarReal(precio)){
		if (precio==0){
			alert("¡¡ATENCION!! El precio introducido es 0.");
		}
		return true;
	}
	return false;
}//valiadrPrecio
/***************************/
/***************************/
//dice si un email es valido o no
function validarEmail(email){
	return /^[a-zA-Z0-9_\-]+(\.[a-zA-Z0-9_\-]+)*@[a-zA-Z0-9_\-]+(\.[a-zA-Z0-9_\-]+)+$/.test(email);
}//validarEmail
/***************************/
function validarEntero(num){
	return /^[0-9]+$/.test(new String(num));
}//validarEntero
/***************************/
function validarReal(num){
	return /^[0-9]+(\.[0-9]+)?$/.test(new String(num));
}//validarReal
/***************************/
//valida que una fecha sea del tipo dd-MM-aaaa
function validarFecha(fecha){
	return /^[0-9]{2}\-[0-9]{2}\-[0-9]{4}$/.test(fecha);
}//validarFecha
/***************************/
//valida que una hora sea del tipo hh:mm
function validarHora(hora){
	return /^[0-9]{2}\:[0-9]{2}$/.test(hora);
}//validarFecha
/***************************/
//dice si hay algun checkbox seleccionado de una lista de checkbox
function haySeleccionados(nombre){
	var v = document.getElementsByName(nombre);
	for (var i in v){
		if (v[i].type=="checkbox" && v[i].checked)
			return true;
	}//for
	return false;
}//haySeleccionados
/***************************/
//dice si la cadena es vacia o no
function esCadenaVacia(cadena){
	if (cadena==null || cadena=="")
		return true;
		
	var c;
	for (var i=0; i<cadena.length; i++){
		c = cadena.charAt(i);
		if (c!=" " && c!="\t" && c!="\r" && c!="\n")
			return false;
	}//for

	return true;
}//esCadenaVacia
/**********************************/
//si se llama en un evento onkeyup no deja introducir caracteres que no sean numeros
function filtrarEntero(campo){
	campo.value = campo.value.replace(/[^0-9]/g,"");
}
/**********************************/
//si se llama en un evento onkeyup no deja introducir caracteres que no sean numeros o el punto
function filtrarReal(campo){
	campo.value = campo.value.replace(/\,+/g,".").replace(/[^0-9\.]/g,"");
}
/**********************************/
//si se llama en un evento onkeyup no deja introducir caracteres que no sean numeros o el guion
function filtrarFecha(campo){
	campo.value = campo.value.replace(/[\/\-]+/g,'-').replace(/[^0-9\-]/g,'');
	//campo.value = /[0-9]{2}\-[0-9]{1,2}\-[0-9]{1,4}|[0-9]{2}\-[0-9]{1,2}\-|[0-9]{2}\-[0-9]{1,2}|[0-9]{2}\-|[0-9]{1,2}/.exec(campo.value);
}//filtrarFecha
/***************************/
/*
function compara(valor1, valor2){
	//si los dos valores son numeros
	if (validarReal(valor1) && validarReal(valor2)){
		valor1 = parseFloat(valor1);
		valor2 = parseFloat(valor2);
		
		if (valor1 < valor2)
			return -1;
		else 
		if (valor1 > valor2)
			return 1;
		else
			return 0;
	}//if
	//si alguno de los valores es una cadena
	for(var i=0; i<valor1.length && i<valor2.length; i++){
		if (valor1.charCodeAt(i)<valor2.charCodeAt(i))
			return -1;
		else
		if (valor1.charCodeAt(i)>valor2.charCodeAt(i))
			return 1;		
	}
	if (valor1.length < valor2.length)
		return -1;
	else
	if (valor1.length > valor2.length)
		return 1;
	else
		return 0;
}
/***************************/
//comprueba que se hayan insertado los campos indicados en el vector vsRequeridos. Este vector debe tener el formato:
// Object(campo1=>etiqueta1, ... , campo3=>etiqueta3)
function validarRequeridos(formu, vsRequeridos){
	ok = true;
	for(campo in vsRequeridos){
		if (is_numeric(campo))
			valor = formu.elements[etiqueta].value;
		else
			valor = formu.elements[campo].value;

		if (esCadenaVacia(valor)){
			ok = false;
			alert("ERROR: El campo 'etiqueta' debe tener valor.");
		}//if
	}//foreach
	return ok;
}//validarRequeridos
/***************************/
//dice si la hora hora tiene el formato correcto o no
function validarHora(hora){
	if (!ereg("^([0-9]+)\:([0-9]+)(:([0-9]+))?",hora, regs))
		return false;
	h = regs[1];
	m = regs[2];
	s = 0;
	if (isset(regs[4]))
		s = regs[4];
	
	return ((h>=0 && h<24) && (m>=0 && m<60) && (s>=0 && s<60));
}//validarHora
/********************************/
//dice si es una fecha formada por dia-mes-ano es una fecha valida
function checkdate(dia, mes, ano){
	var d = new Date(ano, mes, dia);
	return (d.getDate()==dia);
}//checkdate
/*******************************/
//Dice si la fecha introducida esta en el formato europero. Devuelve false si es incorrecta o un timestamp si sí lo es.
//Si se indica un valor de cifras_ano el año de la fecha debe tener ese numero de cifras (2 o 4 tipicamente)
function validarFechaEuropa(fecha, cifras_ano){
	var d;
	var regs = new RegExp("^([0-9]+)[\/\-]([0-9]+)[\/\-]([0-9]+)$").exec(fecha);
	if (!regs)
		return false;

	dia = regs[1];
	mes = regs[2] - 1; //para formar una fecha con Date, el mes va de 0..11
	ano = regs[3];
	if (ano<100)
		ano=parseInt(ano)+
			parseInt(new String(new Date().getFullYear()).substring(0,2))*100; //suma 2000, 2100, 2200 segun el seglo qn el que nos encontremos

	if (checkdate(dia,mes,ano) && (cifras_ano==undefined || new String(ano).length == cifras_ano)){
		d = new Date(ano, mes, dia);
		d.setHours(0,0,0,0); //pone las horas, min, sec y ms a 0
		return (d.getTime());
	}else
		return false;
	
}//validarFechaEuropa
/*******************************/
function validarFechaUSA(fecha, cifras_ano){
	var d;
	var regs = new RegExp("^([0-9]+)[\/\-]([0-9]+)[\/\-]([0-9]+)$").exec(fecha);
	if (!regs)
		return false;

	dia = regs[2];
	mes = regs[1] - 1; //para formar una fecha con Date, el mes va de 0..11
	ano = regs[3];
	if (ano<100)
		ano=parseInt(ano)+
			parseInt(new String(new Date().getFullYear()).substring(0,2))*100; //suma 2000, 2100, 2200 segun el seglo qn el que nos encontremos

	if (checkdate(dia,mes,ano) && (cifras_ano==undefined || new String(ano).length == cifras_ano)){
		d = new Date(ano, mes, dia);
		d.setHours(0,0,0,0); //pone las horas, min, sec y ms a 0
		return (d.getTime());
	}else
		return false;
	
}//validarFechaEuropa
/*******************************/
function validarFechaISO(fecha, cifras_ano){
	var d;
	var regs = new RegExp("^([0-9]+)[\/\-]([0-9]+)[\/\-]([0-9]+)$").exec(fecha);
	if (!regs)
		return false;

	dia = regs[3];
	mes = regs[2] - 1; //para formar una fecha con Date, el mes va de 0..11
	ano = regs[1];
	if (ano<100)
		ano=parseInt(ano)+
			parseInt(new String(new Date().getFullYear()).substring(0,2))*100; //suma 2000, 2100, 2200 segun el seglo qn el que nos encontremos

	if (checkdate(dia,mes,ano) && (cifras_ano==undefined || new String(ano).length == cifras_ano)){
		d = new Date(ano, mes, dia);
		d.setHours(0,0,0,0); //pone las horas, min, sec y ms a 0
		return (d.getTime());
	}else
		return false;
	
}//validarFechaEuropa

function Param(key, value){
	this.key = key;
	this.value = value;
}

function buildMessage(sText /*, voParams*/){
	var voParams = arguments;
	if (voParams.shift)
		voParams.shift(); //quitamos el primer elemento que es el argumento sText
	var j = 1;
	var oParam = null;
	for(var i = 0; i<voParams.length; i++){
		oParam = voParams[i];
		if (typeof(oParam)=="string")
			sText = sText.replace(new RegExp("\\{"+j+"\\}"), oParam);
		else
			sText = sText.replace(new RegExp("\\{"+oParam.key+"\\}"), oParam.value);
		j++;
	}//foreach
	return sText;
}//getMessage		


/**************************************************************************/
/**************************************************************************/
/*
INTERFACE:
	function setCampos(campos);

	function validarCampoVSValor(campo1, valor, comparacion=IGUAL, tipo=null);
	function validarCampoVSCampo(campo1, campo2, comparacion=IGUAL, tipo=null);
	function validarCampoVSRangoValores(campo1, linf, lsup, tipo = null);
	function validarCampoVSRangoCampos(campo1, campolinf, campolsup, tipo = null);
	function validarCampoVSListaValores(campo1, valores);
	function validarCampoVSListaCampos(campo1, campos);
	function validarCampoVSExpresion(campos, exp);
	function validarLongitudCampos(campos, longitud);	
	function validarTipoCampos(campos, tipo);
	function validarRequeridos(campos);
	function validarRequeridosOR(campos);
	function validarRequeridosXOR(campos);

	function mostrarAlert();
	function mostrarTexto();

*/


/*public*/
function Validador(formu){
	if (!document.utiles_js)
		alert("SE REQUIERE EL ARCHIVO utiles.js");
		
	/*protected*/ this.m_formu = formu; //puntero al formulario a validar
	/*protected*/ this.m_vsCamposError = new Array(); //campos en los que ha ocurrido algun error
	/*protected*/ this.m_vsCamposWarning = new Array();
	/*protected*/ this.m_asCampos = new Object(); //un array que contiene la relacion entre nombres de campo y etiquetas de los mismos
											  // Object(nombre1=>etiqueta1, ... , nombreN=>etiquetaN)
	/*protected*/ this.m_vsErrores = new Array();
	/*protected*/ this.m_vsWarnings = new Array();
	/*protected*/ this.m_bOK = true;
	
	/*public*/	
	this.setCampos = function(campos){
		var vargs = this.setCampos.arguments;
		
		if (vargs.length==1){ //se presupone que le ha entrado un array asociativo con los nombres de los campos asociados con sus etiquetas
			this.m_asCampos = campos;
			//for(var i in campos) alert(i+"="+campos[i]);
		}else
		if (vargs.length>1){ //si no se supone que le  habran entrado los argumentos del siguiente modo: nom1, etiq1, nom2, etiq2...
			this.m_asCampos = new Object();
			for (var i=0; i<vargs.length; i+=2){
				this.m_asCampos[vargs[i]] = vargs[i+1];
			}//for
		}else
			return false;
	}//setCampos

	/*private*/
	this.agregarError = function(mens, campo, tipoError){
		//if (this.m_formu[campo]==null) //solo se agrega el error si el campo existe
		//	return false;
		if (tipoError==Validador.WARNING){
			this.m_vsWarnings.push(mens);
			this.m_vsCamposWarning.push(campo);
		}else{
			this.m_vsCamposError.push(campo);
			this.m_vsErrores.push(mens);
			if (this.m_bOK)
				this.m_bOK = false;
		}//else
	}//agregarError

	//devuelve la etiqueta del campo si se ha definido o el nombre si no
	/*private*/
	this.nombreCampo = function(campo){
		if (campo.push){ //si se trata de un array
			s = "";
			for (var i=0; i<campo.length; i++){
				s+=this.nombreCampo(campo[i]);
				if (i<(campo.length-1)) 
				if (i==(campo.length-2))
					s+=" y ";
				else
					s+=", ";
			}
			return s;
		}
		if (this.m_asCampos[campo]!=undefined)
			return "\""+this.m_asCampos[campo]+"\"";
		return '"'+campo+'"';
	}//nombreCampo
	
	/*private*/
	this.valorCampo = function(campo){
		var i, aux;

		var e = this.m_formu.elements[campo];

		if (e == undefined)
			return false;

		//if (e.push){alert(campo+" es un array");}
			
		if (e.type=="select-one") //select-one
			return e.options[e.selectedIndex].value;
		else
		if (e.type=="select-multiple"){ //select-multiple
			aux = new Array();
			for (i=0; i<e.options.length; i++){
				if (e.options[i].selected)
					aux.push(e.options[i].value);
			}//for
			return aux;
		}else
		if (e.type=="checkbox"){
			if (e.checked)
				return e.value;
			return false;
		}else
		if (e.type==undefined){//lista de campos (tipicamente radiobuttons o checkboxes)
			if (e[0].type=="radio"){//se devolvera el valor del redio button seleccionado
				for(i=0; i<e.length; i++){
					if (e[i].checked)
						return e[i].value;
				}//for
			}else{ //se devuelve la lista de valores seleccionados
				aux = new Array();
				for(i=0; i<e.length; i++){
					if (((e[i].type!="radio") && (e[i].type!="checkbox")) || e[i].checked)
						aux.push(e[i].value);
				}//for
				return aux;
			}//else
		}else //el resto de elementos de formulario
			return e.value;
	}//campo
	
	/*private*/
	this.tieneValor = function(valor){
		var i;
			
		switch(typeof(valor)){
		case "object": //un conjunto de valores
			for(i=0;i<valor.length;i++){
				if (!esCadenaVacia(valor[i]))
					return true;
			}
			/*for (i=0; i<valor.length; i++)
				if (!esCadenaVacia(valor[i])) //si alguno de los valores no es cadena vacia se devuelve true (se considera que tiene valor)
					return true;
			return false;*/
			return false;
		default: //un unico valor
			return (!esCadenaVacia(valor));
		}
		return false;
	}//valor
	
	/*private*/
	this.nombreComparacion = function(comparacion, tipo){
		switch (tipo){
		case Validador.FECHA_EUROPA:
		case Validador.FECHA_USA:
		case Validador.FECHA_ISO:
			switch (comparacion){
			case Validador.IGUAL: return "igual a";		
			case Validador.MENOR: return "anterior a";		
			case Validador.MENORIGUAL: return "anterior o igual a";		
			case Validador.MAYOR: return "posterior a";		
			case Validador.MAYORIGUAL: return "posterior o igual a";
			case Validador.DISTINTO: return "diferente a";
			}//switch
			break;
		default:
			switch (comparacion){
			case Validador.IGUAL: return "igual a";		
			case Validador.MENOR: return "menor que";		
			case Validador.MENORIGUAL: return "menor o igual que";		
			case Validador.MAYOR: return "mayor que";		
			case Validador.MAYORIGUAL: return "mayor o igual que";
			case Validador.DISTINTO: return "diferente a";
			}//switch	
		}//switch
		return false;
	}//nombreComparacion
		
	/*private*/
	this.hoy = function(){
		var d = new Date();
		d.setHours(0,0,0,0); //pone las horas, minutos, segundos y milisegundos a 0
		return d;
	}//hoy
	
	/*private*/
	this.comparar = function(valor1, valor2, comparacion, tipo){
		
		if (comparacion == undefined) 
			comparacion = Validador.IGUAL; //valor por defecto
			
		switch(tipo){
		case Validador.FECHA_EUROPA:
			if (valor2 == Validador.HOY){
				if (!(valor1 = validarFechaEuropa(valor1)))
					return false;
				valor2 = this.hoy();
			}else
			if (!(valor1 = validarFechaEuropa(valor1)) || 
				!(valor2 = validarFechaEuropa(valor2)))
				return false;
			break;
		case Validador.FECHA_USA:
			if (valor2 == Validador.HOY){
				if (!(valor1 = validarFechaUSA(valor1)))
					return false;
				valor2 = this.hoy();
			}else
			if (!(valor1 = validarFechaUSA(valor1)) || 
				!(valor2 = validarFechaUSA(valor2)))
				return false;
			break;
		case Validador.FECHA_ISO:
			if (valor2 == Validador.HOY){
				if (!(valor1 = validarFechaISO(valor1)))
					return false;
				valor2 = this.hoy();
			}else
			if (!(valor1 = validarFechaISO(valor1)) || 
				!(valor2 = validarFechaISO(valor2)))
				return false;
			break;
		default:
			//si los dos valores son numeros reales se toman como tales
			if (validarReal(valor1) && validarReal(valor2)){
				valor1 = parseFloat(valor1);
				valor2 = parseFloat(valor2);
			}//if
		}//switch
		
		switch (comparacion){
		case Validador.IGUAL:	return (valor1 == valor2);
		case Validador.DISTINTO:	return (valor1 != valor2);
		case Validador.MENOR:	return (valor1 < valor2);
		case Validador.MENORIGUAL: return (valor1 <= valor2);
		case Validador.MAYOR:	return (valor1 > valor2);
		case Validador.MAYORIGUAL: return (valor1 >= valor2);
		default:
			myAlert("ERRROR EN EL TIPO DE COMPARACIÓN.");
		}//switch	
		return false;
	}//comparar
	/******************************/
	//Compara el valor del campo1 con un valor escalar proporcionado.
	//Devuelve true si se cumple la comparacion o false en caso contrario.
	//En el caso de comparar fechas debe indicarse en el campo tipo (FECHA_EUROPA o FECHA_USA o FECHA_ISO).
	/*public*/	
	this.validarCampoVSValor = function(campo1, valor, comparacion, tipo, tipoError, sMens){
		var valor1;
		valor1 = this.valorCampo(campo1);

		if (!this.tieneValor(valor1)) //si no tiene valor el campo1 no se realiza la comprobacion
			return true;	
	
		if (comparacion == undefined) 
			comparacion = Validador.IGUAL; //valor por defecto

		if (this.comparar(valor1, valor, comparacion, tipo))
			return true;

		if (sMens==undefined) var sMens = "";
		if (sMens=="")
			sMens = "El campo {campo} debe ser {comparacion} {valor}.";
		
		this.agregarError(buildMessage(sMens,
			new Param("campo", this.nombreCampo(campo1)),
			new Param("comparacion",this.nombreComparacion(comparacion, tipo)),
			new Param("valor", valor)), campo1, tipoError);
			
		return false;	
	}//compararConValor
	
	//Compara el valor del campo1 con el valor del campo2
	//Devuelve true si se cumple la comparacion o false en caso contrario.
	//En el caso de comparar fechas debe indicarse en el campo tipo (FECHA_EUROPA o FECHA_USA o FECHA_ISO).
	/*public*/	
	this.validarCampoVSCampo = function(campo1, campo2, comparacion, tipo, tipoError, sMens){
		var valor1, valor2;
		valor1 = this.valorCampo(campo1);	
		
		if (!this.tieneValor(valor1)) //si no tiene valor el campo1 no se realiza la comprobacion
			return true;	
		
		if (comparacion == undefined) 
			comparacion = Validador.IGUAL; //valor por defecto	

		valor2 = this.valorCampo(campo2);
		
		if (this.comparar(valor1, valor2, comparacion, tipo))
			return true;
			
		if (sMens==undefined) var sMens = "";
		if (sMens=="")
			sMens = "El campo {campo1} debe ser {comparacion} el campo {campo2}.";

		this.agregarError(buildMessage(sMens,
			new Param("campo1",this.nombreCampo(campo1)),
			new Param("campo2",this.nombreCampo(campo2)),
			new Param("comparacion",this.nombreComparacion(comparacion, tipo))), campo1, tipoError);
			
		return false;
	}//compararConCampo
	
	//Comprueba si el valor del campo1 se encuentra entre los valores linf y lsup
	//Devuelve true si se cumple la comparacion o false en caso contrario.
	//En el caso de comparar fechas debe indicarse en el campo tipo (FECHA_EUROPA o FECHA_USA o FECHA_ISO).
	/*public*/
	this.validarCampoVSRangoValores = function (campo1, linf, lsup, tipo, tipoError, sMens){
		var valor1;
		valor1 = this.valorCampo(campo1);
		if (!this.tieneValor(valor1)) //si no tiene valor el campo1 no se realiza la comprobacion
			return true;	
	
		//si linf y lsup tienen valor y linf>lsup se intercambian los valores
		if (!esCadenaVacia(linf) && !esCadenaVacia(lsup) && linf > lsup){
			var aux = lsup;
			lsup = linf;
			linf = aux;
		}//if	
	
		if (this.comparar(valor1,linf, Validador.MAYORIGUAL,tipo) && 
			this.comparar(valor1,lsup, Validador.MENORIGUAL,tipo))
			return true;
			
		if (sMens==undefined) var sMens = "";
		if (sMens=="")
			sMens = "El valor del campo {campo} debe estar comprendido entre {linf} y {lsup}.";
			
		this.agregarError(buildMessage(sMens,
			new Param("campo",this.nombreCampo(campo1)),
			new Param("linf",linf),
			new Param("lsup",lsup)), campo1, tipoError);
			
		return false;				
	}//compararConRangoValores
	
	//Comprueba si el valor del campo1 se encuentra entre los valores de los campos campolinf y campolsup
	//Devuelve true si se cumple la comparacion o false en caso contrario.
	//En el caso de comparar fechas debe indicarse en el campo tipo (FECHA_EUROPA o FECHA_USA o FECHA_ISO).
	/*public*/
	this.validarCampoVSRangoCampos = function (campo1, campolinf, campolsup, tipo, tipoError, sMens){
		var valor1, linf, lsup;
		valor1 = this.valorCampo(campo1);
		
		if (!this.tieneValor(valor1)) //si no tiene valor el campo1 no se realiza la comprobacion
			return true;		
		
		linf = this.valorCampo(campolinf); //limite inferior
		lsup = this.valorCampo(campolsup); //limite superior

		//si linf y lsup tienen valor y linf>lsup se intercambian los valores
		if (!esCadenaVacia(linf) && !esCadenaVacia(lsup) && linf > lsup){
			var aux = lsup;
			lsup = linf;
			linf = aux;
		}//if	
		
		if ((esCadenaVacia(linf) || this.comparar(valor1,linf,Validador.MAYORIGUAL,tipo)) && 
			(esCadenaVacia(lsup) || this.comparar(valor1,lsup,Validador.MENORIGUAL,tipo)))
			return true;
			
		if (sMens==undefined) var sMens = "";
		if (sMens=="")
			sMens = "El valor del campo {campo} debe estar comprendido entre el valor de {campolinf} y {campolsup}.";
			
		this.agregarError(buildMessage(sMens,
			new Param("campo", this.nombreCampo(campo1)),
			new Param("campolinf", this.nombreCampo(campolinf)),
			new Param("campolsup", this.nombreCampo(campolsup))), campo1, tipoError);
			
		return false;				
	}//compararConRangoNumeros

	//Comprueba si el valor del campo1 se encuentra entre los valores valores (un array de valores)
	//Devuelve true si se cumple la comparacion o false en caso contrario.
	//En el caso de comparar fechas debe indicarse en el campo tipo (FECHA_EUROPA o FECHA_USA o FECHA_ISO).
	//
	//La comparacion funciona asi, si se usa comparacion IGUAL (por defecto) se cumple si el valor del campo1 coincide con 
	//alguno de los valores indicados en el array valores.
	//Si se usa otra comprobacion se comprueba que se cumpla para todos los valores indicados	
	//
	/*public*/
	this.validarCampoVSListaValores = function (campo1, valores, comparacion, tipo, tipoError, sMens){
		var i, value;
		var valor1 = this.valorCampo(campo1);
		if (esCadenaVacia(valor1))
			return true;

		if (comparacion == undefined) 
			comparacion = Validador.IGUAL; //valor por defecto				
		
		var ok = true;
		if (comparacion == Validador.IGUAL){
			for(i=0; i< valores.length; i++){
				value = valores[i];
				if (this.comparar(valor1,value,comparacion,tipo))
					return true;			
			}//for
		}else{
			for(i=0; i< valores.length; i++){
				value = valores[i];
				if (!this.comparar(valor1,value,comparacion,tipo)){
					ok = false;
					break;
				}
			}//for
			if (ok)
				return true;
		}//else
		
			
		if (sMens==undefined) var sMens = "";
		if (sMens==""){
			sMens = "El valor del campo {campo}";
			if (comparacion == Validador.IGUAL)
				sMens+=" debe tener uno de los siguientes valores: {valores}.";
			else
				sMens+=" debe ser {comparacion} los valores: {valores}.";
		}
		
		this.agregarError(buildMessage(sMens,
			new Param("campo",this.nombreCampo(campo1)),
			new Param("valores",valores),
			new Param("comparacion",this.nombreComparacion(comparacion, tipo))), campo1, tipoError);

		return false;					
	}//compararConListaValores

	//Comprueba si el valor del campo1 se encuentra entre los valores  de los campos campos (un array de nombres de campos)
	//Devuelve true si se cumple la comparacion o false en caso contrario.
	//En el caso de comparar fechas debe indicarse en el campo tipo (FECHA_EUROPA o FECHA_USA o FECHA_ISO).
	//
	//La comparacion funciona asi, si se usa comparacion IGUAL (por defecto) se cumple si el valor del campo1 coincide con 
	//el valor de alguno de los campos indicados.
	//Si se usa otra comprobacion se comprueba que se cumpla para todos los valores de los campos indicados
	/*public*/
	this.validarCampoVSListaCampos = function (campo1, campos, comparacion, tipo, tipoError, sMens){
		var i, value, ok;
		var valor1 = this.valorCampo(campo1);
		if (esCadenaVacia(valor1))
			return true; //si no tiene valor el campo1 no tiene sentido realizar la comparacion
		/*ok = false;
		for(key in campos){ 
			value = this.valorCampo(campos[key]);	
			if (this.tieneValor(value)){
				ok = true;
				break;
			}//if
		}//for
		if (!ok)
			return true;//si ninguno de los campos tiene valor no tiene sentido realizar la comparacion
			*/
		if (comparacion == undefined) 
			comparacion = Validador.IGUAL; //valor por defecto	de la comparacion		
		
		ok = true;
		if (comparacion == Validador.IGUAL){ //si la comparacion es de igualdad
			for(i=0; i< campos.length; i++){
				value = this.valorCampo(campos[i]);
				if (this.comparar(valor1,value,comparacion,tipo))
					return true; //basta con que coincida con uno de los valores de los campos
			}//for
		}else{//para el resto de comparaciones
			for(i=0; i<campos.length; i++){
				value = this.valorCampo(campos[i]); //la comparacion debe cumplirse para todos los campos
				if (!this.tieneValor(value))//si el campo no tiene valor no se compara
					continue;
				if (!this.comparar(valor1,value,comparacion,tipo)){
					ok = false;
					break;
				}//if
			}//for
			if (ok)
				return true;
		}//else
		
		if (sMens==undefined) var sMens = "";
		if (sMens==""){
			sMens = "El valor del campo {campo}";
			if (comparacion == Validador.IGUAL)
				sMens+=" debe ser igual que uno de los siguientes: {campos}.";
			else
				sMens+=" debe ser {comparacion} los valores de : {campos}.";
		}//if
		this.agregarError(buildMessage(sMens,
			new Param("campo",this.nombreCampo(campo1)),
			new Param("campos",this.nombreCampo(campos)),
			new Param("comparacion",this.nombreComparacion(comparacion, tipo))), campo1, tipoError);

		return false;				
	}//compararConListaCampos
	
	//comprueba que el valor de todos los campos indicados cumplan la expresion regular exp
	/*public*/	
	this.validarCamposVSExpresion = function (campos, exp, tipoError, sMens){
		var ok = true;
		var campo, valor;
		var re = new RegExp(exp);
		
		if (sMens==undefined) var sMens = "";
		if (sMens=="")
			sMens = "El campo {campo} no tiene el formato correcto.";			
		
		for(var i=0; i< campos.length; i++){
			campo = campos[i];
			valor = this.valorCampo(campo);
			if (!esCadenaVacia(valor))
			if (!re.test(valor)){
				ok = false;
				this.agregarError(buildMessage(sMens,
					new Param("campo", this.nombreCampo(campo))), campo, tipoError);
			}//if
		}//foreach
				
		return ok;
	}//validarExpresionRegular
	
	//compara la longitud (el numero de caracteres de su valor) de los campos indicados con $longitud y una comparacion $comparacion
	/*public*/	
	this.validarLongitudCampos = function(campos, longitud, comparacion, tipoError, sMens){
		var ok = true;
		
		if (comparacion == undefined) 
			comparacion = Validador.IGUAL; //valor por defecto	

		if (sMens==undefined) var sMens = "";
		if (sMens=="")
			sMens = "La longitud del campo {campo} debe ser {comparacion} {longitud}.";	
			
		for (var key in campos){
			campo = campos[key];
			valor = this.valorCampo(campo);
			
			if (esCadenaVacia(valor)) //si el campo no tiene valor no se valida su tipo
				continue;
			
			if (!this.comparar(new String(valor).length, longitud, comparacion)){
				ok = false;
				
				this.agregarError(buildMessage(sMens,
					new Param("campo",this.nombreCampo(campo)),
					new Param("longitud", longitud),
					new Param("comparacion", this.nombreComparacion(comparacion))), campo, tipoError);
			}//if
		}//foreach
		
		return ok;
	}//compararLongitud	
	
	//comprueba que los campos indicados sean del tipo indicado
	/*public*/	
	this.validarTipoCampos = function (campos, tipo, tipoError, sMens){
		var ok = true;
		var campo;
	
		for (var key in campos){
			campo = campos[key];
			valor = this.valorCampo(campo);
			if (!this.tieneValor(valor)) //si el campo no tiene valor no se valida su tipo
				continue;

			switch(tipo){
			case Validador.FECHA_EUROPA:
				ok = validarFechaEuropa(valor);
				if (sMens==undefined) var sMens = "";
				if (sMens=="")
					sMens = "El campo {campo} debe contener una fecha válida en formato día-mes-año.";
				break;
			case Validador.FECHA_USA:
				ok = validarFechaUSA(valor);
				if (sMens==undefined) var sMens = "";
				if (sMens=="")
					sMens = "El campo {campo} debe contener una fecha válida en formato mes-día-año.";
				break;
			case Validador.FECHA_ISO:
				ok = validarFechaISO(valor);
				if (sMens==undefined) var sMens = "";
				if (sMens=="")
					sMens = "El campo {campo} debe contener una fecha válida en formato año-mes-día.";
				break;			
			case Validador.HORA:
				ok = validarHora(valor);
				if (sMens==undefined) var sMens = "";
				if (sMens=="")
					sMens = "El campo {campo} debe contener una hora válida.";
				break;			
			case Validador.ENTERO:
				ok = validarEntero(valor);
				if (sMens==undefined) var sMens = "";
				if (sMens=="")
					sMens = "El campo {campo} debe contener un número entero.";
				break;
			case Validador.DECIMAL:
				ok = validarReal(valor);
				if (sMens==undefined) var sMens = "";
				if (sMens=="")
					sMens = "El campo {campo} debe contener un número real.";	
				break;
			case Validador.EMAIL:
				ok = validarEmail(valor);
				if (sMens==undefined) var sMens = "";
				if (sMens=="")
					sMens = "El campo {campo} debe contener una dirección de email válida.";
				break;			
			case Validador.NOMBRE:
			case Validador.MONEDA:
			case Validador.URL:
			default:
				alert("EL TIPO INDICADO NO SE ENCUENTRA.");
				return false;
			}//switch
			if (!ok)
				this.agregarError(buildMessage(sMens,
					new Param("campo",this.nombreCampo(campo))),campo, tipoError);
		}//foreach
		return ok;
	}//validarTipo
	
	/*public*/	
	//todos los campos indicados en el array campos deben tener valor
	this.validarCamposRequeridos = function (campos, tipoError, sMens){
		var ok = true;
		var campo;
		if (sMens==undefined) var sMens = "";
		if (sMens=="")
			sMens = "El campo {campo} debe tener valor.";			
		for(var i=0;i<campos.length;i++){
			campo = campos[i];
			if (!this.tieneValor(this.valorCampo(campo))){
				ok = false;
				this.agregarError(buildMessage(sMens, 
					new Param("campo",this.nombreCampo(campo))), campo, tipoError);
			}//if
		}//for

		return ok;
	}//validarRequeridos
	
	/*public*/	
	//alguno de los campos indicados en el array campos debe tener valor
	this.validarCamposRequeridosOR = function (campos, tipoError, sMens){
		var campo, aux="", mens;
		var todosNombresIguales = true;
		
		if (sMens==undefined) var sMens = "";
		if (sMens=="")
			sMens = "Al menos uno de los siguientes campos debe tener valor: {campos}.";

		for(var i=0;i<campos.length;i++){
			campo = campos[i];
			
			if (this.tieneValor(this.valorCampo(campo)))
				return true;
			if (todosNombresIguales){
				if (aux!=this.nombreCampo(campo) && aux!="")
					todosNombresIguales = false;
				aux = this.nombreCampo(campo);
			}
		}//for
		
		if (todosNombresIguales){
			if (sMens=="")
				sMens = "El campo "+aux+" debe tener valor.";
		}
			
		this.agregarError(buildMessage(sMens, 
			new Param("campos",campos)), campos[0], tipoError);
			
		return false;
	}//validarCamposRequeridosOR
	
	/*public*/	
	//solo uno de los campos indicados en el array campos debe tener valor
	this.validarCamposRequeridosXOR = function(campos, tipoError, sMens){
		
		var num = 0;
		var campo;
		for(var i=0;i<campos.length;i++){
			campo = campos[i];
			if (this.tieneValor(this.valorCampo(campo))){
				num++;
			}//if
		}//foreach

		if (sMens==undefined) var sMens = "";

		//segun el numero de campos rellenados:
		switch(num){
		case 1: return true;
		case 0: //no se ha rellenado ningun campo
			if (sMens=="")
				sMens = "Uno de los siguientes campos debe tener valor: {campos}.";
			break;
		default:
			if (sMens=="")
				sMens = "Sólo uno de los siguientes campos debe tener valor: {campos}.";
		}//switch
				
		this.agregarError(buildMessage(sMens,
			new Param("campos",this.nombreCampo(campos))), campos[0], tipoError);
	
		return false;
	}//validarCamposRequeridosXOR
	
	/*public*/	
	this.mostrarAlert = function(sMens){
		if (this.m_vsErrores.length==0)
			return true;
	
		if (sMens==undefined) var sMens = "";
		if (sMens=="")
			sMens = "Ocurrieron los siguientes errores:";
		sMens+="\n\r";
		for(var i=0; i<this.m_vsErrores.length; i++){
			sMens+="  - "+this.m_vsErrores[i]+" \n\r";
		}//foreach
		myAlert(sMens);
		var e = this.m_formu.elements[this.m_vsCamposError[0]];
		try{e.focus();}catch(ex){} //coloca el foco sobre el primer campo en el que se ha detectado un error
	}//mostrarAlert
	
	/*public*/	
	this.mostrarTexto = function(){
		/*foreach(this.m_vsErrores as key=>mens_error){
			mens+="<li>".htmlentities(mens_error)."</li>";
		}//foreach
		?>
		<div>Ocurrieron los siguientes errores:<br />
			<ul><?=mens?></ul>
		</div><?*/
	}//mostrarTexto
	
	//valida el formulario y marca los campos donde ha ocurrido un error
	/*public*/
	this.validar = function(){
		var i, e, capa, txt;
		var sError = " ";
		var sWarning = " ";
		
		//quita las marcas de error a todos los campos
		var v = document.getElementsByTagName("span");
		for (i=0; i<v.length; i++){
			if (v[i].className == "capaError")
				v[i].innerHTML = "";
		}//for

		//los campos erroneos los marca con un *
		for(i=0;i<this.m_vsCamposError.length;i++){
		
			if (e = document.getElementById('capa'+this.m_vsCamposError[i])){
				e.innerHTML = sError;
			}else{
				e = this.m_formu.elements[this.m_vsCamposError[i]];//elemento del formulario
				if (e==null)
					continue;
				if (e.type==undefined)//si es una lista de nodos (como en el caso de radiobuttons)
					e = e[0];
			
				capa  = document.createElement("span"); //se crea un elemento SPAN
				capa.id = "capa"+this.m_vsCamposError[i];
				capa.className = "capaError";
				
				txt = document.createTextNode(sError); //se crea un nodo de texto "*" y se mete en el SPAN recien creado
				capa.appendChild(txt);

				e.parentNode.insertBefore(capa,e); //el "*" se inserta justo delante del elemento del formulario
				//e.parentNode.insertBefore(capa,e.nextSibling); //el "*" se inserta justo despues del elemento del formulario
			}//else
		}//for

		//los campos erroneos los marca con un !
		for(i=0;i<this.m_vsCamposWarning.length;i++){
			if (e = document.getElementById('capa'+this.m_vsCamposWarning[i]))
				e.innerHTML = sWarning;
			else
			{
				e = this.m_formu.elements[this.m_vsCamposWarning[i]];//elemento del formulario
				
				capa  = document.createElement("span"); //se crea un elemento SPAN
				capa.id = "capa"+this.m_vsCamposWarning[i];
				
				txt = document.createTextNode(sWarning); //se crea un nodo de texto "*" y se mete en el SPAN recien creado
				capa.appendChild(txt);
			
				e.parentNode.insertBefore(capa, e.nextSibling); //se inserta justo despues del elemento del formulario
			}//else
		}		
		
		if (this.m_bOK){
			for(i=0;i<this.m_vsWarnings;i++){
				if (!myConfirm(this.m_vsWarnings[i]+"\r\n ¿Desea continuar pese a ello?"))
					return false;
			}//for
		}//if
		
		return this.m_bOK;
	}//validar
}//Validador

//formatos de fecha
Validador.FECHA_EUROPA = 1;
Validador.FECHA_USA = 2;
Validador.FECHA_ISO = 3;

//tipos a validar
Validador.HORA = 101;
Validador.ENTERO = 102;
Validador.DECIMAL = 103;
Validador.MONEDA = 104;
Validador.URL = 105;
Validador.EMAIL = 106;
Validador.NOMBRE = 107;
//define("CP","108");
//define("TELEFONO","109");

//tipos de comparacion
Validador.MENOR = 1;
Validador.MENORIGUAL = 2;
Validador.IGUAL = 3;
Validador.MAYOR = 4;
Validador.MAYORIGUAL = 5;
Validador.DISTINTO = 6;

//fechas predefinidas
Validador.HOY = "la fecha actual";


Validador.ERROR = -1;
Validador.WARNING = 99;


function isTelefono(s){
if(!s) return false;
var filter=/^[9|8][0-9]{8}$/;
return filter.test(s);
}

function isMovil(s){
if(!s) return false;
var filter=/^[6][0-9]{8}$/; 
return filter.test(s);
}

function isTelefonoPortugal(s){
if(!s) return false;
var filter=/^[2][0-9]{8}$/;
return filter.test(s);
}

function isMovilPortugal(s){
if(!s) return false;
var filter=/^[9][0-9]{8}$/;
return filter.test(s);
}