var validator={	
	form : null,
	validators : new Object(),
	validatorsState : new Object(),

	
	init : function (formName){
	    this.form=document.forms[formName];
	},
	
	checkForm : function(){
		if(!document.getElementById("validators")){
			validatorsField=document.createElement("input");
			validatorsField.type="hidden";
			validatorsField.name="validators";
			validatorsField.id="validators";
			validatorsField.value=JSON.stringify(validator.validators);
			validator.form.appendChild(validatorsField);
		}
		validator.validateAll();
		return false;
	},
	
	addValidator: function(field, type){
		this.validators[field]=type;
		this.validatorsState[field]=false;
	},

	addExtraValidator: function(field, type){
		this.validators[field]=type;
		this.validatorsState[field]=false;
		if(this.form[field]){
			this.addListener("blur",this.form[field],this.validateElement);
		}
	},

	
	removeValidator: function (field){
		if(validator.validators[field])delete validator.validators[field];
		if(validator.validatorsState[field])delete validator.validatorsState[field];
		if(validator.form[field]){
			validator.removeListeners("blur", validator.form[field], this.validateElement);
			validator.hideError(validator.form[field]);
		}
		
	},
	
	attachToOnSubmit:function(){
		this.form.onsubmit = this.checkForm;
	},
	
	addListeners:function(){
		for (var fieldName in this.validators) {
			if(this.form[fieldName]){
				this.addListener("blur",this.form[fieldName],this.validateElement);
			}else{
				alert("Error en el validador de " + fieldName);
			}
		}
	},
	
	removeListeners:function(event, elem, func){
		if(window.removeEventListener){ // Mozilla, Netscape, Firefox
			elem.removeEventListener(event, func, false);
		} else { // IE
			elem.detachEvent('on' + event, func);
		}
	},
	
	addListener:function(event, elem, func) {
			if(window.addEventListener){ // Mozilla, Netscape, Firefox
				elem.addEventListener(event, func, false);
			} else { // IE
				elem.attachEvent('on' + event, func);
			}
	},
	
	getEventElement:function(evt){
		var el_out;
		var ie_var = "srcElement";
		var moz_var = "target";
		evt[moz_var] ? el_out=evt[moz_var] : el_out=evt[ie_var];
		return el_out;
	},
	
	getStyle:function(element, property){
		if(element){
			if (element.currentStyle)
				var y = element.currentStyle[property];
			else if (window.getComputedStyle)
				var y = document.defaultView.getComputedStyle(element,null).getPropertyValue(property);
			return y;
		}
	},
	
	isVisible:function(element){
		visible=true;
		if(validator.getStyle(element, "visibility")=="hidden")visible=false;
		if(element.type=="hidden")visible=false;
		return visible;
	},
	
	isDisabled:function(element){
		disabled=false;
		if(element.disabled)disabled=true;
		return disabled;
	},
	
	validateElement:function(evt){
			element=validator.getEventElement(evt);
			if(element){
				validator.validate(element);
			}
	},
	
	validateAll:function(){
		fieldValues=new Object();
		vals=new Object();
		for(var field in validator.validatorsState){
			el=document.getElementsByName(field);
			el=el[0];
			if(validator.isVisible(el)&&!validator.isDisabled(el)){
				fieldValues[field]=el.value;
				vals[field]=validator.validators[field];
			}
		}
		vals=JSON.stringify(vals);
		vals=vals.replace(/\"/g,"'");
		fieldValues=JSON.stringify(fieldValues);
		fieldValues=fieldValues.replace(/\"/g,"'");
		
		remoteObject=new AjaxQuery();
		remoteObject.name="Validator";
		remoteObject.method="getValidatorsReponses";
		remoteObject.callback="validator.getAllResults";
		remoteObject.validators=vals;
		remoteObject.fields=fieldValues;
		ajax=new AjaxClient();
		ajax.execute(remoteObject);
	},

	getAllResults:function(datos){
		var valid=true;
		for(var i in datos){
			if(valid)valid=false;
			element=document.getElementsByName(i);
			element=element[0];
			validator.showError(element, datos[i]);
		}
		if(valid)validator.form.submit();
	},	
	
	validate:function(element){
		if(!validator.isDisabled(element)&&validator.isVisible(element)){
			remoteObject=new AjaxQuery();
			remoteObject.name="Validator";
			remoteObject.method="validate";
			remoteObject.callback="validator.getResult";
			remoteObject.type=validator.validators[element.name];
			remoteObject.field=element.name;
			remoteObject.value=element.value;
			ajax=new AjaxClient();
			ajax.execute(remoteObject);
		}
	},
	addClass:function (element, value) {
		if(element.className.indexOf(value)<0){
			if(!element.className) {
				element.className = value;
			} else {
				newClassName = element.className;
				newClassName+= " ";
				newClassName+= value;
				element.className = newClassName;
			}
		}
	},
	
	removeClass:function (element, value){
		element.className=element.className.replace(value,"");
	},
	
	getResult:function (datos){
		if(datos){
			el=document.getElementsByName(datos.field);
			if(!datos.result){
				validator.validatorsState[el[0].name]=false;
				validator.showError(el[0],datos.msg);
			}else{
				validator.validatorsState[el[0].name]=true;
				validator.hideError(el[0]);
			}
		}
	},
	
	findPosX:function (obj){
	    var curleft = 0;
	    if(obj.offsetParent)
	        while(1) 
	        {
	          curleft += obj.offsetLeft;
	          if(!obj.offsetParent)
	            break;
	          obj = obj.offsetParent;
	        }
	    else if(obj.x)
	        curleft += obj.x;
	    return curleft;
	},
	
	findPosY:function (obj){
	    var curtop = 0;
	    if(obj.offsetParent)
	        while(1)
	        {
	          curtop += obj.offsetTop;
	          if(!obj.offsetParent)
	            break;
	          obj = obj.offsetParent;
	        }
	    else if(obj.y)
	        curtop += obj.y;
	    return curtop;
	  },

	  hideError:function (el){
		  divName='error-' + el.name;
		  validator.removeClass(el,"errorField");
		  div=document.getElementById(divName);
		  if(div){
		   document.body.removeChild(div);
		  }
	  },
	  
	  showError:function (el, msg){
		    divName='error-' + el.name;
		    div=document.getElementById(divName);
		    validator.addClass(el,"errorField");
		    if(!div){
				var oDv=document.createElement("div");
				oDv.id=divName;
				oDv.className="errorMessage";
				oDv.innerHTML=msg;
				oDv.style.width=msg.length*7 + "px";
				validator.positionError(oDv, el);
				document.body.appendChild(oDv); 
		    }			
	    },
	    
	    positionError:function(div, element){
			div.style.top=validator.findPosY(element) + "px";
			div.style.left=(validator.findPosX(element)+ element.offsetWidth+5) + "px";
	    },
	    
	    fixErrorMessages:function(){
	    	for(var field in validator.validators){
	    		if(validator.validatorsState[field]===false){
		    		errorDivName='error-' + field;
		    		errorDiv=document.getElementById(errorDivName);
		    		if(errorDiv){
		    			inputElement=document.getElementsByName(field);
		    			inputElement=inputElement[0];
		    			if(validator.isVisible(inputElement)){
			    			validator.positionError(errorDiv, inputElement);
		    			}else{
		    				validator.hideError(inputElement);
		    			}
		    		}
	    		}
	    		
	    	}
	    }
	    

};

