/*
'::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
'   JS encargado de validar datos de formularios
'::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
	
	Versión :		3.60
	Fecha Creacion :	01/04/2003 dd/mm/yyyy
	Autor :			Sclar Ignacio
	
	Empresa :		E-VOLUTION			    
	Ultima Modificacion :	08/03/2004 dd/mm/yyyy
	Autor :			Sclar Ignacio
			
'::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DOCUMENTACION

Instanciar el validador
~~~~~~~~~~~~~~~~~~~~~~~
En estos ejemplos se usara myVal como objeto contenedor del validador
myVal = new Validator('numero de formulario' | 'nombre del formulario');

Se pueden setear las siguientes propiedades que no son requeridas pero hacen al diseño y funcionalidad del formulario
myVal.classTextError = class del mensaje de error
myVal.classInputError = class que se le pondra al input con error
myVal.classInputDefault = class por defecto de los input
myVal.Trim =		= Por defecto es true, pero en caso de no querer que se trimeen los campos, ponerlo en false

Iniciar la validacion
~~~~~~~~~~~~~~~~~~~~~
myVal.initValidation (nombre del campo a validar,id del div en el que se mostraran los mensajes de error);

Finalizar la validacion
~~~~~~~~~~~~~~~~~~~~~~~
myVal.endValidation(); -> ejecuta todos los datos que se le hayan cargado a la validacion correspondiente

Metodos de la validacion
~~~~~~~~~~~~~~~~~~~~~~~~
myVal.isnull(mensaje de error) -> comprueba que haya mas de 1 caracter
myVal.minChars (cant minima,mensaje de error) -> comprueba que no se ingrese un string menor al indicado
myVal.maxChars (cant maxima,mensaje de error) -> comprueba que no se ingrese un string mayor al indicado
myVal.login (mensaje de error) -> el texto debe estar comprendido entre [a-z] [A-Z] [0-9] "-" "_"
myVal.email (mensaje de error) -> comprueba que sea un email valido
myVal.password (mensaje de error) -> comprueba que los passwords ingresados sean validos
el campo donde se repite el password debe llamarse igual que el campo original antecedido por "re"
myVal.integer (mensaje de error) -> comprueba que sea un numero entero
myVal.maxInt (cant maxima,mensaje de error) -> comprueba que no se ingrese un numero mayor al indicado
myVal.minInt (cant minima,mensaje de error) -> comprueba que no se ingrese un numero menor al indicado
myVal.flotante (mensaje de error) -> debe ser un numero flotante

Iniciar regla
~~~~~~~~~~~~~
myVal.initRule(nombre del campo,valor deseado para ejecutar la regla,id del div para el mensaje de error,mensaje de error)

Lo que hace la regla es verificar un determinado valor en un campo para que segun este, otros campos se conviertan en requeridos o no.
Los campos que esten dentro de una regla pueden estar tambien dentro de una validacion
initRule chequea el campo que uno le ingrese y en caso de que el valor de este coincida con el valor que uno le ingreso, se inicia la regla
si la regla no es satisfactoria, se mostrara el mensaje de error que uno le indique en el div proporcionado.
Si uno quiere que la regla se inicie con cualquiera que sea el valor que tenga el campo, siempre y cuando no sea null
debe poner vacio "" como valor para iniciar la regla
Si uno quiere que la regla se inicie si el campo no fue completado, el valor deseado para ejecutar la regla debe ser null

Agregar items a la regla
~~~~~~~~~~~~~~~~~~~~~~~~
Estos items, que son otros campos del formulario, seran los que se convertiran en requeridos o no segun el valor del campo
de la regla
myVal.addItem (nombre del campo) -> agrega este campo a la regla

Orden de los mensajes de error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ya que cada campo puede tener una validacion por muchos tipos de errores y un mensaje distinto por c/u de ellos,
dada una circunstancia determinada, puede que en un div tenga mas de un mensaje para mostrar, lo cual no seria viable visualmente.
entonces el validador junto con las reglas organizan una cola FILO respetada por todos los metodos salvo isnull(), por lo que el mensaje del ultimo metodo que no tenga datos satisfactorios
sera mostrado, siempre y cuando no se haya producido un error en isnull.
Ej:
myVal.initValidation ('Password','pas');
	myVal.minChars (7,'El Password debe tener como mínimo 7 caracteres');
	myVal.isnull ('Debe completar un password');
	myVal.password ('Los password deben coincidir');
	myVal.login ('Debe completar un password valido [a-z] [A-Z] [0-9] "-" "_"');
myVal.endValidation();

si el valor del campo Password es "" -> se mostrara 'Debe completar un password'
si el valor del campo Password es "a" -> se mostrara 'El Password debe tener como mínimo 7 caracteres'
si el valor del campo Password es "*" -> se mostrara 'Debe completar un password valido [a-z] [A-Z] [0-9] "-" "_"'
si el valor del campo Password es "1" y rePassword es "2" -> se mostrara 'Los password deben coincidir'
*/
//Deteccion del navegador
var ns4 = (document.layers); 
var ie4 = (document.all && !document.getElementById);
var ie5 = (document.all && document.getElementById);
var ns6 = (!document.all && document.getElementById);

function isArray(obj)
	{
	if (ns4)
		{
		if (eval("obj.type"))
			{
			if (obj.type=='select-one')
				return true;
				else
				return false;
			}
			else
			return true;
		}
		else
		return(typeof(obj.length)=="undefined")?false:true;
	}
function attach(id)
	{
	var obj
	if(ns4) obj = document.layers[id];
		else if(ie4) obj = document.all[id];
			else if(ie5 || ns6) obj = document.getElementById(id);
	return obj;
	}
	
//class principal
function Validator(intForm)
	{
	this.ObjForm		= document.forms[intForm];
	this.classTextError	= '';
	this.classInputError	= '';
	this.classInputDefault	= '';
	this.allOK		= true;
	this.firstTime		= true;
	this.Verificado		= '';
	this.inputValue		= '';
	this.ObjArrayForm 	= new Array();
	this.divArrayError	= new Array();
	this.inputArrayError	= new Array();
	this.Trim		= true;
	
	function initValidation (strInput,strDiv,boolRequired)
		{
		this.nameInput	= String(strInput);
		this.idDiv	= String(strDiv);
		this.validationOK=null;
		this.Message	= new Array();
		
		if (boolRequired==undefined)
			this.isRequired	= false;
			else
			this.isRequired	= boolRequired;
		if (this.nameInput.length==0 || this.idDiv.length==0)
			{
			alert ('Datos mal ingresados para la validación de '+strInput);
			this.allOK=false;
			return false;
			}
		if (this.testDatosIngresados())
			{
			this.Verificado=true;
			this.loadData();
			}
			else
			this.Verificado=false;
		}

	function isnull (strMessage)
		{
		// isnull: En caso de ser vacio, muestra el mensaje de error
		this.Message[this.Message.length] = String(strMessage);
		
		if (this.Verificado)
			{
			this.isRequired	= false;
			intLengthValue=this.inputValue.length;
			if (intLengthValue<1)
				this.validationOK=this.Message.length-1;
			}
		}
	function minChars(intMinChars,strMessage)
		{
		// minChars: verifica que el campo tenga mas o igual caracteres que el minimo requerido
		this.Message[this.Message.length] = String(strMessage);
		
		if (this.Verificado)
			{
			intLengthValue=this.inputValue.length;
			if (this.isRequired)
				{
				if (intLengthValue<intMinChars)
					this.validationOK=this.Message.length-1;
				}
				else
				if (intLengthValue>0 && intLengthValue<intMinChars)
					this.validationOK=this.Message.length-1;
			}
		}
	function login (strMessage)
		{
		this.Message[this.Message.length] = String(strMessage);
		var Fl=true;
		if (this.Verificado)
			{
			strValue=this.inputValue;
			for (var i=0; i<strValue.length; i++)
				{
				if ((strValue.charCodeAt(i)>47 && strValue.charCodeAt(i)<58) || (strValue.charCodeAt(i)>96 && strValue.charCodeAt(i)<123) || (strValue.charCodeAt(i)>64 && strValue.charCodeAt(i)<91) || (strValue.charCodeAt(i)==95) || (strValue.charCodeAt(i)==45))
					{}
					else 
					this.validationOK=this.Message.length-1;
				}
			if (this.isRequired && strValue.length==0)
				this.validationOK=this.Message.length-1;
			}
		}
	function email(strMessage)
		{
		this.Message[this.Message.length] = String(strMessage);
		var flagb=0;
		if (this.Verificado)
			{
			strValue=this.inputValue;
			if (strValue.length>0)
				{
				for (var i=0; i<strValue.length; i++)
					{
					if ((strValue.charCodeAt(i)>47 && strValue.charCodeAt(i)<58) || (strValue.charCodeAt(i)>96 && strValue.charCodeAt(i)<123) || (strValue.charCodeAt(i)>64 && strValue.charCodeAt(i)<91) || (strValue.charCodeAt(i)==46) || (strValue.charCodeAt(i)==64) || (strValue.charCodeAt(i)==95) || (strValue.charCodeAt(i)==45))
						{}
						else
						this.validationOK=this.Message.length-1;
					}
				if (!strValue.match(/^.+\@.+\..+$/))
				   	this.validationOK=this.Message.length-1;
					else
					{
					for (q=0;q<strValue.length;q++)
						{
						if (strValue.substring(q, q+1)=="@")
							flagb=flagb+1
						}
					if (flagb>1)
						this.validationOK=this.Message.length-1;
					}
				}
				else if (this.isRequired)
					this.validationOK=this.Message.length-1;
			}
		}
	function password (strMessage)
		{
		this.Message[this.Message.length] = String(strMessage);
		if (this.Verificado)
			{
			if (!eval("this.ObjForm."+"re"+this.nameInput))
				{
				alert ("El TAG 're"+this.nameInput+"' para validar la coincidencia de passwords no existe")
				this.allOK=false;
				}
				else
				{
				strPass=this.inputValue
				strRePass=eval("this.ObjForm."+"re"+this.nameInput+".value")
				if (strPass!=strRePass)
					this.validationOK=this.Message.length-1;
					else if (this.isRequired && strPass.length==0)
						this.validationOK=this.Message.length-1;
				}
			}
		}
	function integer(strMessage)
		{
		var fl=0
		this.Message[this.Message.length] = String(strMessage);
		if (this.Verificado)
			{
			strValue = this.inputValue;
			intValue = parseInt(this.inputValue);
			if (this.isRequired && strValue.length==0)
				this.validationOK=this.Message.length-1;
				else if (strValue.length>0)
					{
					for (var i=0; i<strValue.length; i++)
						{
						if (strValue.charCodeAt(i)<48 || strValue.charCodeAt(i)>57)
							fl=1
						}
					if (fl==1)
						this.validationOK=this.Message.length-1;
					}
			}
		}
	function maxInt(intMax,strMessage)
		{
		this.Message[this.Message.length] = String(strMessage);
		if (this.Verificado)
			{
			intLength = this.inputValue.length;
			intValue = parseInt(eval("this.ObjForm."+this.nameInput+".value"));
			if (intValue!=NaN)
				if (intMax<intValue)
					this.validationOK=this.Message.length-1;
			}
		}
	function ffloat(strMessage)
		{
		this.Message[this.Message.length] = String(strMessage);
		if (this.Verificado)
			{
			strValue = this.inputValue
			intValue = parseFloat(this.inputValue)
			if (this.isRequired && strValue.length==0)
				this.validationOK=this.Message.length-1;
				else if (strValue.length>0)
					if (strValue!=String(intValue))
						this.validationOK=this.Message.length-1;
			}
		}
	function minInt(intMin,strMessage)
		{
		this.Message[this.Message.length] = String(strMessage);
		if (this.Verificado)
			{
			intLength = this.inputValue.length;
			intValue = parseInt(this.inputValue);
			if (intValue!=NaN)
				if (intMin>intValue)
					this.validationOK=this.Message.length-1;
			}
		}
	function maxChars(intMax,strMessage)
		{
		this.Message[this.Message.length] = String(strMessage);
		if (this.Verificado)
			{
			intLength = this.inputValue.length;
			if (intMax<intLength)
				this.validationOK=this.Message.length-1;
			}
		}
	function endValidation()
		{
		if (this.validationOK!=null)
			this.wrongData();
			else
			this.goodData();
		}
	function retorno()
		{
		return this.allOK;
		}
	this.endValidation=endValidation;
	this.minChars=minChars;
	this.isnull=isnull;
	this.initValidation=initValidation;
	this.retorno=retorno;
	this.login=login;
	this.email=email;
	this.password=password;
	this.integer=integer;
	this.maxInt=maxInt;
	this.flotante=ffloat;
	this.minInt=minInt;
	this.maxChars=maxChars;
	}
function loadData()
	{
	var Obj=eval("this.ObjForm."+this.nameInput)
	var val='';
	if (!isArray(Obj))
		{
		if (String(Obj.type)=='radio' || String(Obj.type)=='checkbox')
			{
			if (Obj.checked==true)
				val = Obj.value;
			}
			else
			val = Obj.value;
		}
		else if (String(Obj.type)=='select-one')
		{
		if (Obj.selectedIndex>=0)
			val = Obj.options[Obj.selectedIndex].value;
		}
		else
		{
		if (String(Obj[0].type)!='radio' && String(Obj[0].type)!='checkbox' && String(Obj.type)!='select-multiple')
			{
			alert ('El campo \''+this.nameInput+'\' no puede repetirse porque es type=\''+Obj[0].type+'\'');
			this.allOK=false;
			}
			else
			{
			for (i=0;i<Obj.length;i++)
				{
				if (Obj[i].checked==true)
					val=Obj[i].value;
				if (Obj[i].selected==true)
					val=Obj[i].value;
				
				}
			}
		}
	if (val==null)
		val='';
		else
		{
		if (this.Trim)
			{
			val=val.trim();
			Obj.value=val;
			}
		}
	this.inputValue=val;
	}
function testDatosIngresados()
	{
	var fl=true
	
	if (!eval("this.ObjForm."+this.nameInput))
		{
		alert ("El TAG de entrada '"+this.nameInput+"' no existe")
		fl=false
		this.allOK=fl;
		}
	if (!ns4)
		{
		if (attach(this.idDiv)==null)
			{
			alert ("El TAG DIV con id '"+this.idDiv+"' no existe")
			fl=false
			this.allOK=fl;
			}
		}
	return fl;
	}
function wrongData(intCase)
	{
	if (!ns4)
		{
		ObjDiv=attach(this.idDiv);
		ObjDiv.style.display='block';
		ObjDiv.innerHTML=this.Message[this.validationOK];
		if (this.classTextError.length>0)
			ObjDiv.className=this.classTextError;
		}
		else
		{
		
		}
	ObjInput=eval('this.ObjForm.'+this.nameInput);
	this.saveError()
	
	if (this.classInputError.length>0)
		ObjInput.className=this.classInputError;
	if (this.firstTime)
		{
		if (!isArray(ObjInput) || String(ObjInput.type)=='select-one')
			{
			if (String(ObjInput.type)!='hidden')
				{
				ObjInput.focus();
				if (ns4)
					alert (this.Message[this.Message.length-1].replace('&nbsp;',''))
				}
			}
			else
			ObjInput[0].focus();
		this.firstTime=false;
		}
	this.allOK=false;
	}
function goodData()
	{
	if (this.Verificado)
		{
		if (!ns4)
			{
			ObjDiv=attach(this.idDiv);
			if (!this.isErrorFound(this.idDiv,1))
				ObjDiv.style.display='none';
			}
		if (!this.isErrorFound(this.nameInput,2))
			{
			ObjInput=eval('this.ObjForm.'+this.nameInput);
			if (this.classInputDefault.length>0)
				ObjInput.className=this.classInputDefault;
			}
		}
	}
function saveError()
	{
	if (!this.isErrorFound(this.idDiv,1))
		this.divArrayError[this.divArrayError.length]=this.idDiv;
	if (!this.isErrorFound(this.nameInput,2))
		this.inputArrayError[this.inputArrayError.length]=this.nameInput;
	}
function isErrorFound(strNameVar,typeVar)
	{
	//isErrorFound: typevar=1 -> div / typevar=2 -> input
	var arrayLista;

	if (typeVar==1)
		arrayLista=this.divArrayError;
	if (typeVar==2)
		arrayLista=this.inputArrayError;
	for (i=0;i<arrayLista.length;i++)
		{
		if (arrayLista[i]==strNameVar)
			return true;
		}
	return false;
	}
function trim ()
	{
	var x=this;
	x=x.replace(/^\s*(.*)/, "$1");
	x=x.replace(/(.*?)\s*$/, "$1");
	return x;
	}
String.prototype.trim = trim;
Object.prototype.wrongData=wrongData;
Object.prototype.testDatosIngresados=testDatosIngresados;
Object.prototype.goodData=goodData;
Object.prototype.loadData=loadData;
Object.prototype.saveError=saveError;
Object.prototype.isErrorFound=isErrorFound;

//RULES
Object.prototype.initRule=initRule;
Object.prototype.addItem=addItem;
function initRule(strInput,strChkValue,strDivName,strMessage)
	{
	this.nameInput		= String(strInput);
	this.checkValue		= String(strChkValue);
	this.idDiv			= String(strDivName);
	this.Message		= new Array();
	this.Message[0]		= String(strMessage);
	this.inputValue		= '';
	this.chkRule		= false;
	this.validationOK	= 0;
	
	if (this.testDatosIngresados())
		{
		this.Verificado=true;
		this.loadData();
		if (this.inputValue==this.checkValue && this.checkValue.length>0)
			this.chkRule=true;
			else if (this.checkValue.length==0 && this.inputValue.length>0)
				this.chkRule=true;
				else if (this.checkValue=='null' && this.inputValue.length==0)
					this.chkRule=true;
		}
		else
		this.Verificado=false;
	}
function addItem(strInput)
	{
	this.nameInput	= String(strInput);
	if (this.testDatosIngresados() && this.Verificado)
		{
		this.loadData();
		if (this.chkRule)
			{
			if (this.inputValue.length==0)
				this.wrongData();
				else
				this.goodData();
			}
		}
		else
		this.Verificado=false;
	}
function MaxChars(Msg,Max,Chr,NumForm)
	{
	if (!NumForm)
		NumForm=1
	/*alert (document.forms[1].elements.length)
	for (i=0;i<document.forms[1].elements.length;i++)
	{
		alert (document.forms[1].elements[i].name)
	}*/
	var TxtObj=eval("document.forms["+NumForm+"]."+Msg);
	var Txt=eval("document.forms["+NumForm+"]."+Msg+".value");
	var Chr=eval("document.forms["+NumForm+"]."+Chr)
	if (Txt.length>Max)
		TxtObj.value=Txt.substring(0,Max);
	Chr.value=a=Txt.length;
	}