//***********************************************************************************************
//* 						-[formValidator.class]-												
//*																								
//* [DescripciÃ³n]
//* - Reglas de validaciÃ³n centralizadas
//* - ValidaciÃ³n post-submit y en tiempo real
//* - EspecificaciÃ³n de estilos para los errores: 
//* 	Si no se especifica ninguno utiliza los siguientes estilos 
//*		- text: textValidateError
//*		- textArea: textAreaValidateError
//*		- selectOne: selectOneValidateError
//* 	- selectMultiple: selectMultipleValidateError
//*		- radioButton: rbValidateError
//*		- checkBox: chkValidateError
//* - ValidaciÃ³n de campos mÃºltiples (telefono[0], telefono[1].....,telefono[n])
//*	- Valida los siguientes tipos de campos:
//*		- text
//*		- radioButtons y RadioButton Areas
//*		- checkBoxes
//*		- textArea
//*		- selects (Multiples y simples)
//* - ValidaciÃ³n de datos mediante una funciÃ³n externa: 
//*   Esto permite validaciones mÃ¡s complicadas como campos anidados o mÃ¡scaras especiales
//*	  
//* - Utiliza expresiones regulares para optimizar la velocidad
//*
//* [Atributos]
//* - preError:	html que va antes de cada error. Sirve para poner alguna imagen detrÃ¡s
//* - summary: id del div donde se mostrarÃ¡ el resumen de errores ej: 'summary'
//* - summaryTitle: tÃ­tulo del resumen ej: 'Resumen de errores del formulario'
//* - styles: Objeto literal con los estilos para cada tipo de validaciÃ³n
//*				ej: {input:'',textArea:'',select:'', radioButton:'', checkBox:''}
//* 
//* [MÃ©todos]
//* - Principales:
//* 	- addRule(parÃ¡metros de validaciÃ³n (objeto literal)): Agrega una regla de validaciÃ³n
//*			- id: Id del objeto a validar. Normalmente un objeto de formulario.
//*			- required: Booleano. Especifica si es requerido o no
//*			- validate: Especifica que el contenido del objeto se ha de validar con respecto algun formato
//*				- Number: El campo solo puede contener numeros enteros
//*				- date: El contenido es una fecha.
//*				- mail: El contenido es una direccion de correo
//*				- floatWithFormat:Numero con decimales al que se plica formato de miles ( Ej56.2358.487,08)
//* 	- validateFields(): Valida todo los campos y muestra el resumen de errores
//* 	- validateField('fieldId','div'[opcional]): 
//*				Valida solo el campo especificado y muestra el error junto al mismo 
//*				o en el div especificado
//* 
//****************************************************************************************************
var Class = {
        create: function() {
                return function() {
                        this.initialize.apply(this, arguments);
                }
        }
}
 
function getValue(s){return document.getElementById(s).value}
 
var formValidator = Class.create();
formValidator.prototype = {
        
		/*--------------------------------------------------------------------------*/
        initialize:function(){
                // **** Publicas  ****
				this.showSummary = true;				// Indica si se debe mostrar el resumen de errores
				this.showFieldErrors = true;			// Indica si se debe mostrar o no la validaciÃ³n en cada campo
				
				// Layout
				this.summaryTitle = ""; 				// String con el tÃ­tulo del div ej: 'Resumen de errores del formulario'
				this.summary = "";						// id del div donde se mostrarÃ¡ el resumen de errores ej: 'summary'
				this.preError = ""; 					// HTML que se concatena antes de los mensajes de error del div
				this.errorStyle = "fontValidateError"; 	// Estilo del error a mostrar
				this.styles = {
					error: {text:'fv_text_error', textarea:'fv_textarea_error', select_one:'fv_select-one_error', select_multiple:'fv_select-multiple_error', radio:'fv_radio_error', checkbox:'fv_checkbox_error', file:'fv_file_error'},
					valid: {text:'fv_text_valid', textarea:'fv_textarea_valid', select_one:'fv_select-one_valid', select_multiple:'fv_select-multiple_valid', radio:'fv_radio_valid', checkbox:'fv_checkbox_Valid', file:'fv_file_Valid'}
					}; // Objeto literal de estilos por defecto
				
				// **** Privadas ****
				this.rules_array = [];					// Array con las reglas de los campos
				this.error_array = [];					// Array con el resumen de errores
				this.error_control_array = []; 			// Contiene las posiciones de los errores asociados a su id para poder quitarlos cuando se valida el campo con validateField
				this.pres = 50; 						// PresisiÃ³n de busqueda de htmlArrays (Cuanto mas grande el numero mÃ¡s presiciÃ³n) 50 default
        },
        /*--------------------------------------------------------------------------*/
        hasValidChars:function(s, characters, caseSensitive){
                function escapeSpecials(s){
                        return s.replace(new RegExp("([\\\\-])", "g"), "\\$1");
                }
                return new RegExp("^[" + escapeSpecials(characters) + "]+$",(!caseSensitive ? "i" : "")).test(s);
        },
        /*--------------------------------------------------------------------------*/
        isSimpleIP:function(ip){
                ipRegExp = /^(([0-2]*[0-9]+[0-9]+)\.([0-2]*[0-9]+[0-9]+)\.([0-2]*[0-9]+[0-9]+)\.([0-2]*[0-9]+[0-9]+))$/
                return ipRegExp.test(ip);
        },
        /*--------------------------------------------------------------------------*/
        isAlphaLatin:function(string){
                alphaRegExp = /^[0-9a-z]+$/i
                return alphaRegExp.test(string);
        },
        /*--------------------------------------------------------------------------*/
        isNotEmpty:function (string){
                return /\S/.test(string);
        },
        /*--------------------------------------------------------------------------*/
        isEmpty:function(s){
                return !/\S/.test(s);
        },
        /*--------------------------------------------------------------------------*/
        isIntegerInRange:function(n,Nmin,Nmax){
                var num = Number(n);
                if(isNaN(num)){
                        return false;
                }
                if(num != Math.round(num)){
                        return false;
                }
                return (num >= Nmin && num <= Nmax);
        },
        /*--------------------------------------------------------------------------*/
        isNum:function(number){
                numRegExp = /^[0-9]+$/
                return numRegExp.test(number);
        },
        /*--------------------------------------------------------------------------*/
        isEMailAddr:function(string){
                emailRegExp = /^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.([a-z]){2,4})$/
                return emailRegExp.test(string);
        },
        /*--------------------------------------------------------------------------*/
        isZipCode:function(zipcode,country){
                if(!zipcode) return false;
                if(!country) format = 'US';
                switch(country){
                        case'US': zpcRegExp = /^\d{5}$|^\d{5}-\d{4}$/; break;
                        case'MA': zpcRegExp = /^\d{5}$/; break;
                        case'CA': zpcRegExp = /^[A-Z]\d[A-Z] \d[A-Z]\d$/; break;
                        case'DU': zpcRegExp = /^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/; break;
                        case'FR': zpcRegExp = /^\d{5}$/; break;
                        case'Monaco':zpcRegExp = /^(MC-)\d{5}$/; break;
                }
                return zpcRegExp.test(zipcode);
        },
        /*--------------------------------------------------------------------------*/
        isDate:function(date,format){
                if(!date) return false;
                if(!format) format = 'FR';
                
                switch(format){
                        case'FR': RegExpformat = /^(([0-2]\d|[3][0-1])\/([0]\d|[1][0-2])\/([2][0]|[1][9])\d{2})$/; break;
                        case'US': RegExpformat = /^([2][0]|[1][9])\d{2}\-([0]\d|[1][0-2])\-([0-2]\d|[3][0-1])$/; break;
                        case'SHORTFR': RegExpformat = /^([0-2]\d|[3][0-1])\/([0]\d|[1][0-2])\/\d{2}$/; break;
                        case'SHORTUS': RegExpformat = /^\d{2}\-([0]\d|[1][0-2])\-([0-2]\d|[3][0-1])$/; break;
                        case'dd MMM yyyy':RegExpformat = /^([0-2]\d|[3][0-1])\s(Jan(vier)?|FÃ©v(rier)?|Mars|Avr(il)?|Mai|Juin|Juil(let)?|Aout|Sep(tembre)?|Oct(obre)?|Nov(ember)?|Dec(embre)?)\s([2][0]|[1][19])\d{2}$/; break;
                        case'MMM dd, yyyy':RegExpformat = /^(J(anuary|u(ne|ly))|February|Ma(rch|y)|A(pril|ugust)|(((Sept|Nov|Dec)em)|Octo)ber)\s([0-2]\d|[3][0-1])\,\s([2][0]|[1][9])\d{2}$/; break;
                }
                
                return RegExpformat.test(date);
        },
        /*--------------------------------------------------------------------------*/
        isMD5:function(string){
                if(!string) return false;
                md5RegExp = /^[a-f0-9]{32}$/;
                return md5RegExp.test(string);
        },
        /*--------------------------------------------------------------------------*/
        isURL:function(string){
                if(!string) return false;
                string = string.toLowerCase();
                urlRegExp = /^(((ht|f)tp(s?))\:\/\/)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/
                return urlRegExp.test(string);
        },
        /*--------------------------------------------------------------------------*/
        isGuid:function(guid){//guid format : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx or xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
                if(!guid) return false;
                GuidRegExp = /^[{|\(]?[0-9a-fA-F]{8}[-]?([0-9a-fA-F]{4}[-]?){3}[0-9a-fA-F]{12}[\)|}]?$/
                return GuidRegExp.test(guid);
        },
        /*--------------------------------------------------------------------------*/
        isISBN:function(number){
                if(!number) return false;
                ISBNRegExp = /ISBN\x20(?=.{13}$)\d{1,5}([- ])\d{1,7}\1\d{1,6}\1(\d|X)$/
                return ISBNRegExp.test(number);
        },
        /*--------------------------------------------------------------------------*/
        isSSN:function(number){//Social Security Number format : NNN-NN-NNNN
                if(!number) return false;
                ssnRegExp = /^\d{3}-\d{2}-\d{4}$/
                return ssnRegExp.test(number);
        },
        /*--------------------------------------------------------------------------*/
        isDecimal:function(number){// positive or negative decimal
                if(!number) return false;
                decimalRegExp = /^-?(0|[1-9]{1}\d{0,})(\.(\d{1}\d{0,}))?$/
                return decimalRegExp.test(number);
        },
        /*--------------------------------------------------------------------------*/
        isplatform:function(platform){
                //win, mac, nix
                if(!platform) return false;
                var os;
                winRegExp = /\win/i
                if(winRegExp.test(window.navigator.platform)) os = 'win';
                
                macRegExp = /\mac/i
                if(macRegExp.test(window.navigator.platform)) os = 'mac';
                
                nixRegExp = /\unix|\linux|\sun/i
                if(nixRegExp.test(window.navigator.platform)) os = 'nix';
                
                if(platform == os) return true;
                else return false;
        },
        /*--------------------------------------------------------------------------*/
        isFloatWithFormat: function(number){
			var malFormed = false;
			
			tmp = number.replace(/[.]/g,"");
			tmp = tmp.replace(/[,]/g,"");
			if (number.indexOf('-') != -1 && number.indexOf('-') != 0 ) malFormed = true;
			tmp = tmp.replace(/[-]/g,"");
			if (malFormed){ return false; } else { return this.isNum(tmp); }
        },
        /*--------------------------------------------------------------------------*/
        isIntegerWithFormat: function(number){
			var malFormed = false;
			tmp = number.replace(/[.]/g,"");
			if (number.indexOf('-') != -1 && number.indexOf('-') != 0 ) malFormed = true;
			tmp = tmp.replace(/[-]/g,"");
			if (malFormed){ return false; } else { return this.isNum(tmp); }
        },		
        /*--------------------------------------------------------------------------*/
        isFormulaCorte: function(number){
			tmp = number.replace(/[(]/g,"");
			tmp = tmp.replace(/[)]/g,"");
			
			tmp = tmp.replace(/[[]/g,"");
			tmp = tmp.replace(/[]]/g,"");

			tmp = tmp.replace(/[{]/g,"");
			tmp = tmp.replace(/[}]/g,"");

			tmp = tmp.replace(/[+]/g,"");
			tmp = tmp.replace(/[-]/g,"");
			tmp = tmp.replace(/[\/]/g,"");
			tmp = tmp.replace(/[*]/g,"");
			
			tmp = tmp.replace(/[ ]/g,"");
			
			tmp = tmp.replace(/[H]/g,"");
			tmp = tmp.replace(/[h]/g,"");
			
			tmp = tmp.replace(/[L]/g,"");
			tmp = tmp.replace(/[l]/g,"");

			if (tmp != "") { return this.isFloatWithFormat(tmp); } else { return true;}
        },
		/*--------------------------------------------------------------------------*/
		isParametro: function(param){
			
			tmp = param.replace(/[H]/g,"");
			tmp = tmp.replace(/[L]/g,"");
			
			tmp = tmp.replace(/[ ]/g,"");
			
			if (tmp == "") { return true; } else { return false; }
			
		},
        /*--------------------------------------------------------------------------*/
        getValue:function(id){
                document.getElementById(id).value;
        },
        /*--------------------------------------------------------------------------*/
        addRule:function(rules){
			   // CÃ³digo html pre-error
				if (this.preError != "" && typeof(this.preError) != "undefined") 
					{ 
					if (typeof(rules.required) != "undefined") rules.requiredMsg = this.preError + rules.requiredMsg;
					if (typeof(rules.validate) != "undefined") rules.validateMsg = this.preError + rules.validateMsg;
					if (typeof(rules.unique) != "undefined") rules.uniqueMsg = this.preError + rules.uniqueMsg;
					}
					
				// Agrega la regla de validaciÃ³n al array de reglas	
				this.rules_array.push(rules);
        },
		// agregar un metodo quitar regla para utilizar en tiempo real y validaciones dinÃ¡micas
        /*--------------------------------------------------------------------------*/
		check:function(rules){
				// Flag que controla si ocurriÃ³ algun error durante el chequeo de todos los elementos
				var check_error 		= false;  // false = OperaciÃ³n ok | true = OperaciÃ³n con errores
				var tmp_error_control 	= [];
				var tmp_error 			= [];
				
				// ************** RECORRIDO DE REGLAS DE VALIDACION **************
				for(i=0; i<rules.length; i++)
					{
					// RevalidaciÃ³n de uno o varios campos: Vacia todos los errores asociados a este id
					if (this.error_array.length > 0)
						{
						var cont = this.error_array.length;
						for(x=0; x<this.error_array.length; x++) 
							{
							if (this.error_control_array[x] != rules[i].id) 
								{ 
								tmp_error_control.push(this.error_control_array[x]);
								tmp_error.push(this.error_array[x]);
								//this.error_array.splice(x,1);
								//this.error_control_array.splice(x,1);
								}
							}
						this.error_array 			= tmp_error;
						this.error_control_array 	= tmp_error_control;
						}
						
					// Elemento a analizar
					var field = document.getElementById(rules[i].id);
					
					// Flag que controla si en este elemento ocurriÃ³ algÃºn error
					var field_error = false; 
						
						/*---------------------------[VALIDACIÃ“N DE REQUERIDO]---------------------------*/
							if (typeof(rules[i].required) != "undefined" && rules[i].required) 
							{
							// Tipo de campos
							switch(field.type) 
								{
								
								/*-----------------------------------------------------------------*/
								case "select-one":
									// Comprueba si el valor actual coincide con el valor por default especificado en la regla
									defaultValue = false;
									if (typeof(rules[i].defaultValue) != "undefined") 
										{ 
										for(p=0; p<rules[i].defaultValue.length; p++)
											{
											if (rules[i].defaultValue[p] == field.value) defaultValue = true;
											}
										}
									
									if (field.options[0].selected || defaultValue) {   
										this.error_array.push(rules[i].requiredMsg);
										this.error_control_array.push(rules[i].id);
										field_error = true;
									}
								break;
								/*-----------------------------------------------------------------*/
								case "select-multiple":
									
									// Completar									
									
								break;
								/*-----------------------------------------------------------------*/
								case "radio":
									// Comprueba si tiene algÃºn radio seleccionado
									elem_rb = document.getElementsByName(rules[i].id);
									var gotCheked = false;
									for (x=0;x< elem_rb.length ; x++) { 
										if (elem_rb[x].checked) gotCheked = true;
									} 

									if (!gotCheked) {   
										this.error_array.push(rules[i].requiredMsg);
										this.error_control_array.push(rules[i].id);
										field_error = true;
									}
								break;
								/*-----------------------------------------------------------------*/
								case "checkbox":
									if (!field.checked) {
										this.error_array.push(rules[i].requiredMsg);
										this.error_control_array.push(rules[i].id);
										field_error = true;
										}
								break;
								/*-----------------------------------------------------------------*/
								case "textarea":
									// Comprueba si el valor actual coincide con el valor por default especificado en la regla
									defaultValue = false;
									if (typeof(rules[i].defaultValue) != "undefined") if (rules[i].defaultValue == field.value) defaultValue = true;
									
									if (this.isEmpty(field.value) || defaultValue) {
											this.error_array.push(rules[i].requiredMsg);
											this.error_control_array.push(rules[i].id);
											field_error = true;
									}
								break;
								/*-----------------------------------------------------------------*/
								case "text":
									defaultValue = false;
									
									if (typeof(rules[i].defaultValue) != "undefined") 
										{ 
										for(p=0; p<rules[i].defaultValue.length; p++)
											{
											if (rules[i].defaultValue[p] == field.value) defaultValue = true;
											}
										}

									if (this.isEmpty(field.value) || defaultValue)
										{
										this.error_array.push(rules[i].requiredMsg);
										this.error_control_array.push(rules[i].id);
										field_error = true;
										}
								break;
								/*-----------------------------------------------------------------*/
								case "hidden":
									defaultValue = false;
									
									if (typeof(rules[i].defaultValue) != "undefined") 
										{ 
										for(p=0; p<rules[i].defaultValue.length; p++)
											{
											if (rules[i].defaultValue[p] == field.value) defaultValue = true;
											}
										}

									if (this.isEmpty(field.value) || defaultValue)
										{
										this.error_array.push(rules[i].requiredMsg);
										this.error_control_array.push(rules[i].id);
										field_error = true;
										}
								break;
								} // fin switch

							} // Fin validaciÃ³n de requerido
						/*-------------------------------------------------------------------------------*/
						
						/*------------------------[VALIDACIÃ“N POR FUNCION EXTERNA]-----------------------*/
							if( typeof(rules[i].validateFunction) != "undefined") { 
								field_error = rules[i].validateFunction(field);
							}
						/*-------------------------------------------------------------------------------*/
						
						/*-----------------------------[VALIDACIÃ“N DE CAMPO ÃšNICO]---------------------------*/
							if( typeof(rules[i].unique) != "undefined") { 
								var id			= field.id;
								var flagError 	= false;
								
								// Recorro todos los campos del array y compruebo que ninguno tenga el mismo valor que este
								
								// Obtengo el indice del campo
									if (id.lastIndexOf("]") !=  -1) fin = id.lastIndexOf("]");
									if (id.lastIndexOf("[",fin) ) ini = id.lastIndexOf("[",fin);
																						 
									if (fin != null) 
										{
										index = id.substr(ini+1,(fin - ini)-1); 
										id = id.replace("["+index+"]","");
										}
								
								// Multiple formularios (Arrays)
								var cant_fields = 0;
								var actual = 0;
								var last = 0;
								var ids = new Array();
								var values = new Array();
								
								// BÃºsqueda por presiciÃ³n para obtener la cantidad de campos y los ids correspondientes
								while ( actual - last < this.pres )
									{
									tmpField = document.getElementById(id+'['+actual+']');
									if (tmpField != null) 
										{ 
										ids[cant_fields] = actual;
										values[cant_fields] = tmpField.value;
										
										if (field.value == tmpField.value &&  field.id != tmpField.id )
											{ 
											flagError = true;
											}
										
										// /*DEBUG*/ alert("ID: "+ids[cant_fields]+"| VALUE: "+values[cant_fields]);
										cant_fields++; 
										last = actual; 
										}
									actual++;
									}	
								
								if (flagError) {
									field_error = true;
									this.error_array.push(rules[i].uniqueMsg);
									this.error_control_array.push(rules[i].id);
									}
								}
						/*-------------------------------------------------------------------------------*/
						
						
						/*-----------------------------[VALIDACIÃ“N POR REGLAS]---------------------------*/
							defaultValue = false;
							if (typeof(rules[i].defaultValue) != "undefined") 
										{ 
										for(p=0; p<rules[i].defaultValue.length; p++)
											{
											if (rules[i].defaultValue[p] == field.value) defaultValue = true;
											}
										}
							
							if( typeof(rules[i].validate) != "undefined" && this.isNotEmpty(field.value) && !defaultValue) {
								// Flag que indica si esta validaciÃ³n especifica da o no algun error	
								var flag_validate = false; 
								
								switch(rules[i].validate) {
									/*--------------------------------------------------------------------------*/
										case'ValidChars':
											if( !this.hasValidChars(field.value, rules[i].chars, false) ) flag_validate = true;
										break;
										/*--------------------------------------------------------------------------*/
										case'AlphaLatin':
											if ( this.isAlphaLatin(field.value) ) flag_validate = true;
										break;
										/*--------------------------------------------------------------------------*/
										case'integerRange':
											if ( !this.isIntegerInRange(field.value, rules[i].Min, rules[i].Max) ) flag_validate = true;
										break;
										/*--------------------------------------------------------------------------*/
										case'Number':
											if ( !this.isNum(field.value) ) flag_validate = true;
										break;
										/*--------------------------------------------------------------------------*/
										case'integerWithFormat':
											if ( !this.isIntegerWithFormat(field.value) ) flag_validate = true;
										break;
										/*--------------------------------------------------------------------------*/
										case'notNumber':
											if ( this.isNum(field.value) ) flag_validate = true;
										break;
										/*--------------------------------------------------------------------------*/
										case'email':
											if ( !this.isEMailAddr(field.value) ) flag_validate = true;
										break;
										/*--------------------------------------------------------------------------*/
										case'zipCode':
											if ( !this.isZipCode(field.value,rules[i].country) ) flag_validate = true;
										break;
										/*--------------------------------------------------------------------------*/
										case'date':
											if( !this.isDate(field.value,rules[i].format) ) flag_validate = true;
										break;
										/*--------------------------------------------------------------------------*/
										case'url':
											if( !this.isURL(field.value) ) flag_validate = true;
										break;
										/*--------------------------------------------------------------------------*/
										case'Decimal':
											if( !this.isDecimal(field.value) ) flag_validate = true;
										break;
										/*--------------------------------------------------------------------------*/
										case'floatWithFormat':
											if( !this.isFloatWithFormat(field.value) ) flag_validate = true;
										break;
										/*--------------------------------------------------------------------------*/
										case'formulaCorte':
											if( !this.isFormulaCorte(field.value) ) flag_validate = true;
										break;
										/*--------------------------------------------------------------------------*/
										case'parametro':
											if( !this.isParametro(field.value) ) flag_validate = true;
										break;


										/*--------------------------------------------------------------------------*/
									} //fin switch
								
								if (flag_validate)
									{ 
									this.error_array.push(rules[i].validateMsg);
									this.error_control_array.push(rules[i].id);
									field_error = true;
									}
	
							} // fin validacion especifica
						/*-------------------------------------------------------------------------------*/
						
						// Activa o desactiva los mensajes de error para esta campo
						if(this.showFieldErrors) this.refreshFieldErrorMsg(field,field_error);
						if(this.showSummary) this.refreshSummary();
						
						// Si algÃºn elemento tiene errores entonces la operaciÃ³n de chequeo devolverÃ¡ false
						// Si todos los field_error son false entonces check_error serÃ¡ false tambiÃ©n y la operacion devolverÃ¡ true
						if(field_error) check_error = field_error;
					
                	} // Fin del for de reglas de validaciÃ³n
					return check_error;
        },
		/*--------------------------------------------------------------------------*/
		 refreshFieldErrorMsg:function(field,show){
			var id = field.id; // Id del objeto
				var val = document.getElementById(id+'_validator_class_msg'); // Tag con el mensaje de validaciÃ³n
				
				// Crea el <SPAN> si no estÃ¡ creado
				if (val == null)
					{
					// Crea un span junto al objeto
					var span = document.createElement('span');
					span.setAttribute('id',id+'_validator_class_msg');
					span.setAttribute('class',this.errorStyle);
					field.parentNode.appendChild(span);
					}
				// Vuelve a tomar el tag validador una vez que ya fue creado
				val = document.getElementById(id+'_validator_class_msg');

				// Arma el array temporal con los errores del campo especifico
				var tmp_array = [];
				for(y=0; y<this.error_array.length; y++)
					{
					if(this.error_control_array[y] == id) tmp_array.push(this.error_array[y]);
					}
					
				// Muestra u oculta el mensaje de error
				switch(field.type) {
					/*-------------------------------------------------------------------------------*/
					case "text":
						if(show) { field.className = this.styles.error.text; val.innerHTML = "<span class='"+this.errorStyle+"' ><br>"  +tmp_array.toString().replace(/\,/gi,"<br/>")+  "</span>"; }
						else{ field.className = this.styles.valid.text; val.innerHTML = ""; }
					break;
					/*-------------------------------------------------------------------------------*/
					case "select-one":
						if(show) { field.className = this.styles.error.select_one; val.innerHTML = "<span class='"+this.errorStyle+"' ><br>"  +tmp_array.toString().replace(/\,/gi,"<br/>")+  "</span>"; }
						else { field.className = this.styles.valid.select_one; val.innerHTML = ""; }
					break;
					
					/*-------------------------------------------------------------------------------*/
					case "select-multiple":
						if(show) { field.className = this.styles.error.select_multiple; val.innerHTML = "<span class='"+this.errorStyle+"' ><br>"  +tmp_array.toString().replace(/\,/gi,"<br/>")+  "</span>"; }
						else { field.className = this.styles.valid.select_multiple; val.innerHTML = ""; }
					break;
					/*-------------------------------------------------------------------------------*/
					case "radio":
						if(show) { 
							elem_rb = document.getElementsByName(field.id);
							for (x=0;x< elem_rb.length ; x++) elem_rb[x].className = this.styles.error.radio; 
							val.innerHTML = "<span class='"+this.errorStyle+"' ><br>"  +tmp_array.toString().replace(/\,/gi,"<br/>")+  "</span>";
						}
						else { 
							elem_rb = document.getElementsByName(field.id);
							for (x=0;x< elem_rb.length ; x++) elem_rb[x].className = this.styles.valid.radio;
							val.innerHTML = "";
						}
					break;
					/*-------------------------------------------------------------------------------*/
					case "checkbox":
						if(show) { field.className = this.styles.error.checkbox; val.innerHTML = "<span class='"+this.errorStyle+"' ><br>"  +tmp_array.toString().replace(/\,/gi,"<br/>")+  "</span>"; }
						else { field.className = this.styles.valid.checkbox; val.innerHTML = ""; }
					break;
					/*-------------------------------------------------------------------------------*/
					case "textarea":
						if(show) { field.className = this.styles.error.textarea; val.innerHTML = "<span class='"+this.errorStyle+"' ><br>"  +tmp_array.toString().replace(/\,/gi,"<br/>")+  "</span>"; }
						else { field.className = this.styles.valid.textarea; val.innerHTML = ""; }
					break;
					/*-------------------------------------------------------------------------------*/
					case "file":
						if(show) { field.className = this.styles.error.file; val.innerHTML = "<span class='"+this.errorStyle+"' ><br>"  +tmp_array.toString().replace(/\,/gi,"<br/>")+  "</span>"; }
						else { field.className = this.styles.valid.file; val.innerHTML = ""; }
					break;
					/*-------------------------------------------------------------------------------*/
				}
		 },
		/*--------------------------------------------------------------------------*/
		refreshSummary:function() {
			var summ = document.getElementById(this.summary); // Summary object
			
			// Titulo del resumen de errores
			if (this.summaryTitle) { summ.innerHTML = this.summaryTitle; }
			else { summ.innerHTML = ""; }
								
			// Recumen de errores
			summ.innerHTML = summ.innerHTML + this.error_array.toString().replace(/\,/gi,"<br/>");
						
			// Muestra u oculta el resumen de errores
			if (this.error_array.length != 0) { summ.style.display = ""; } else { summ.style.display = "none"; }
		},
		
        /*--------------------------------------------------------------------------*/
        validateFields:function(){
			// RevalidaciÃ³n completa: Vacia todos los errores
			this.error_array = [];
			this.error_control_array = [];
			var opState = true;

			for(o=0; o<this.rules_array.length; o++) 
				{ 
				state = this.validateField(this.rules_array[o].id);
				if (!state) opState = false;
				}
			return opState;
        },
        /*--------------------------------------------------------------------------*/
        validateField:function(id){
			var rules 	= new Array;
			var fin 	= null;
			var ini 	= null;
			var index 	= null;
			var pos 	= -1;
			var isArray = false;
			
			// Obtiene el id y la posiciÃ³n dentro de las reglas de validaciÃ³n
			if (typeof(id) != "undefined" && typeof(id) == "string" && id != "" ) 
				{
				// Obtiene la posiciÃ³n del campo pasado en el array de reglas siempre y cuando no sea un array
				for(x=0; x<this.rules_array.length; x++) 
					{ 
					if (this.rules_array[x].id == id && typeof(this.rules_array[x].array) == "undefined" ) { pos=x; isArray = false; }
					}
				
				// Si no pudo encontrar concordancia comprueba con arrays
				if (pos == -1)
					{
					// Detecta si es o no array el campo comparando su id quitando el contador de ids del array 
					// ej: si el campo es id_familia[0] compararÃ¡ con las reglas de id_familia para ver si es array 
					if (id.lastIndexOf("]") !=  -1) fin = id.lastIndexOf("]");
					if (id.lastIndexOf("[",fin) ) ini = id.lastIndexOf("[",fin);
																		 
					if (fin != null) 
						{
						index = id.substr(ini+1,(fin - ini)-1); 
						id = id.replace("["+index+"]","");
						}
					
					// Vuelve a comprobar
					for(x=0; x<this.rules_array.length; x++)
						{
						if (this.rules_array[x].id == id && this.rules_array[x].array) { pos=x; isArray = true; }
						}
					}
				}
			
			if ( pos != -1 ) {
				// Array
				if(isArray) {

				// Multiple formularios (Arrays)
				var cant_fields = 0;
				var actual = 0;
				var last = 0;
				var ids = new Array();
				
				// BÃºsqueda por presiciÃ³n para obtener la cantidad de campos y los ids correspondientes
				while ( actual - last < this.pres )
					{
					field = document.getElementById(this.rules_array[pos].id+'['+actual+']');
					if (field != null) 
						{ 
						ids[cant_fields] = actual;
						cant_fields++; 
						last = actual; 
						}
					actual++;
					}
				
				// Si index es != null entonces no es una validacion completa
				if (index != null) 
					{
					cant_fields = 1;
					ids[0] = index;
					}
				
				
				// CreaciÃ³n de las reglas adaptadas
				var baseid = this.rules_array[pos].id;
				var newObj = [];

				for(x=0; x<cant_fields; x++) {
					// Clona el objeto y luego acualiza el id
					newObj = new this.cloneObject(this.rules_array[pos]);
					rules.push(newObj);
					rules[x].id = rules[x].id + "["+ids[x]+"]";
					}
					
				} else {
					rules[0] = this.rules_array[pos];
				}
			}
			
			return !this.check(rules);
        },
		/*--------------------------------------------------------------------------*/
		cloneObject:function(what){
			for (i in what) this[i] = what[i];

		},
		/*--------------------------------------------------------------------------*/
		addEvent: function(elmId, evType, fn, useCapture) {
				var elm = document.getElementById(elmId);
				
				if ( elm != null ) {
				
					if (elm.addEventListener) {
						elm.addEventListener(evType, fn, useCapture);
						return true;
					}
					else if (elm.attachEvent) {
						var r = elm.attachEvent('on' + evType, fn);
						return r;
					}
					else {
						elm['on' + evType] = fn;
					}
				}
		}
		
		
}
