/**
** Clase para validar formas en javascript
**/
var Validation =  Class.create();

Validation.prototype = {
	initialize: function(form){
			this.form = $(form);
			if(! this.form ) {
					alert("La forma con el id "+form+" no existe");
					return false;
			}
			
			this.elements = Form.getElements(form);
			this.rules = this.initRules();
			this.errors = 0;
			this.errorsMsg = new Array();
			this.firstError = null;
			
			this.form.onsubmit = this.validate.bindAsEventListener(this);

		},
		
	validate: function(e){
			Event.stop(e);
			this.getProps(e);
			this.errors = 0;
			this.errorsMsg = new Array();
			this.firstError = null;
			
			for(var i = 0; i < this.elements.length ; i++){
					this.isValid(this.elements[i]);
				}
			t = "";
			if(this.errors != 0){
				t +=  "Se encontraron errores en la forma \n\n";
			
				for(var i = 0; i < this.errors ; i++){
						t += "* "+ this.errorsMsg[i] + "\n";
				}
				alert(t);
				this.firstError.focus();
			}
			else{
				if( confirm("¿Deseas enviar la forma?") ) this.form.submit();
				
			}

		},
		
	isValid: function(ele){
		// Preprocesamiento 

		//Checa si esta vacio y si tiene la clase empty, en cuyo caso, ignora la validacion
		if( Element.hasClassName(ele, "empty") )
			if(ele.value.length == 0)
				return;
		// Checa si el elemento con el id igual al title de "ele" tiene el mismo valor				
		if( Element.hasClassName(ele, "dupe")){
			if( ! (other = $(ele.title) )) {
				alert("No se encuentra el elemento " +ele.title);
				return;
			}
			if( ele.value != other.value ){
				this.firstError = ele;
				if(ele.alt == "")
					this.errorsMsg.push("El elemento "+ele.name+" debe ser igual al elemento "+ other.name);
				else
					this.errorsMsg.push(ele.alt);			
				this.errors ++;
			}
			
		}
	
		// Procesado de reglas
		for(i = 0; i < this.rules.length; i++){
			if( Element.hasClassName(ele, this.rules[i].type) ){ // Si tiene la clase de la regla 

				if(ele.type == 'radio'){ // Si el elemento es un radio, busca todos los radios con el nombre y comprueba con el checked
					val = "";
					radios = Form.getInputs(this.form, "radio", ele.name);
					for(j = 0; j< radios.length; j++){
						if(radios[j].checked == true){
							val = radios[j].value;
							break;
						}
					}
	
				}
			
				if(ele.type == 'radio') 
					t = this.rules[i].checkValue(val);	
				else
					t = this.rules[i].checkValue(ele.value);					
				
				if ( t ){ //Si no es valido el regex

					if( this.firstError == null )
						this.firstError = ele;
					this.errorsMsg.push(this.getMessage(ele, this.rules[i] ));
					this.errors++;
				}
			}
		}
	},
	getMessage: function(ele, rule){
		if(typeof ele.alt != 'undefined' && ele.alt != ''){
			return ele.alt;
		}
		else{
			return rule.message.replace("XXXX", ele.name);	
		}
		
	},
	
	getProps: function(f){
		t = ""
		for(k in f){
			t += k + " => " + f[k] + "\n";
		}
		return t;

	},
	initRules: function(){

		a = new Array();
		a.push( new Rule("required", /./, "El objeto XXXX es requerido" ) );
		a.push( new Rule("digits",  /^\d+$/, "El objeto XXXX debe ser un numero" ) );
		a.push( new Rule("nonzero",  /^[1-9]\d*$/ , "El objeto XXXX debe ser un numero diferente de cero" ) );
		a.push( new Rule("chars",  /^[A-Za-z]+$/ , "El objeto XXXX debe tener solo caracteres" ) );
		a.push( new Rule("alpha", /^[A-Za-z0-9]+$/ , "El objeto XXXX debe ser un caracter alfanumerico (no simbolos)" ) );
		a.push( new Rule("email", /^([a-zA-Z0-9_.+-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,6})+$/ , "El objeto XXXX debe ser un email valido" ) );
		a.push( new Rule("date", /^(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$/ , "El objeto XXXX debe ser una fecha valida en el formato YYYY-MM-DD" ) );		

//	Para mas buenos ejemplos de validacion http://www.merlyn.demon.co.uk/js-valid.htm#Val

		return a;
	}
	
};


var Rule = Class.create();

Rule.prototype = {
	initialize: function (type, regexp, message){
		this.type = type;
		this.regexp = regexp;
		this.message = message;
		
		},
	
	checkValue: function(value){
		if(this.regexp.test(value))
			return false;
		else
			return true;
		
	}
	
	
};

