var ValidationClass = new Class({

	timer: 0,
	formFields: new Array(),
	modelName: "",
	formId: "",
	loginRequest: "",
	emailRequest: "",
	loginRequestResult: true,
	emailRequestResult: true,
	ajaxRequestUrl: "users",
	
	initialize: function(){
		
	},

	hideMessage: function(tag)
	{
		this.hideSubmitMessage();
		d=$(tag+"Error")
		if (d)
		{
			$(tag+"Error").set('html', '');
			$(tag+"Error").setStyle('display', 'none');
		}	
	},
	
	showMessage: function(tag, message)
	{
		d=$(tag+"Error")
		if (d)
		{
			$(tag+"Error").set('html', '<div class="error-message">'+message+'</div>');
			$(tag+"Error").setStyle('display', 'block');
		}	
	},
	
	hideSubmitMessage: function()
	{
		d=$("SubmitFormError")
		if (d)
		{
			$("SubmitFormError").set('html', '');
			$("SubmitFormError").setStyle('display', 'none');
		}	
	},
	
	add: function(tag, message, rule, params) 
	{
		if($(tag))
		{
			a=new Array(5);
			a["tag"]=tag;
			a["message"]=message;
			a["rule"]=rule;
			a["params"]=params;
			a["validates"]=true;
	
			if (!this.formFields[tag])
				this.formFields[tag]=new Array();
			this.formFields[tag].push(a);		
			
			$(tag).addEvent("blur", function(){
				/*
				Validation.validateTag(tag);
				*/
			});		
			
		  	$(tag).addEvent("keyup", function(){
				/*
				if (Validation.timer)
					clearTimeout(Validation.timer);		
				Validation.timer=setTimeout(function(){
					Validation.validateTag(tag);
				},1000);
				*/
				
			});
	
		  	$(tag).addEvent("mouseup", function(){
				/*
				if (Validation.timer)
					clearTimeout(Validation.timer);		
				Validation.timer=setTimeout(function(){
					Validation.validateTag(tag);
				},1000);
				*/
				
			});
		}
	},
	
	init: function(formId, message, fn)
	{
		this.modelName=fn;
		this.formId=formId;
		
		if ($("ButtonSubmitForm"))
		{
			$("ButtonSubmitForm").disabled=false;
			$("ButtonSubmitForm").addEvent("click", function(){
				validation=true;
				var it;
				for (it in Validation.formFields)
				{
					if (Validation.formFields[it][0])
					{
						if (Validation.formFields[it][0]["tag"])
						{
							for(var i=0; i<	Validation.formFields[it].length; i++)
							{
								if (!Validation.doValidate(Validation.formFields[it][i]["tag"], Validation.formFields[it][i]["message"], Validation.formFields[it][i]["rule"], Validation.formFields[it][i]["params"]))
								{
									validation=false;
									Validation.formFields[it][i]["validates"]=false;
									break;
								}
							}
						}
					}
				}
				if($(Validation.formId))
				{
					if (validation==true)
					{
						Validation.hideSubmitMessage();	
						$("ButtonSubmitForm").disabled=true;
						$(formId).submit();
					}
					else
					{
						Validation.showMessage("SubmitForm",message);	
					}
				}					
			});
		}	
	},
	
	validateTag: function(tag)
	{
		validation=true;
		if (this.formFields[tag])
		{
			for(i=0; i<	this.formFields[tag].length; i++)
			{
				if (this.doValidate(this.formFields[tag][i]["tag"], this.formFields[tag][i]["message"], this.formFields[tag][i]["rule"], this.formFields[tag][i]["params"])==false)
				{
					validation=false;
					break;
				}
			}
		}
		return validation;
	},
	
	doValidate: function(tag, message, rule, params)
	{
		if (!this.validate(tag, rule, params, message))
		{
			this.showMessage(tag, message)
			return false;
		}
		else 
		{
			this.hideMessage(tag)	
			return true;
		}
	},
	
	validate: function(tag, rule, params, message)
	{
		el=$(tag);
		val="";
		if (el)
		{
			if (!el.type)
			{
				//radio
				e=el.getElements('input');
				if (e)
				{
					e.each(function(v){
							if ((v.type=="radio") && (v.checked))
								val=v.value;
					});
				}
	
				if (!val)
				{
					//date selector
					e=el.getElements('select');
					if (e)
					{
						if (e.length==3)
							val=e[0].value+"-"+e[1].value+"-"+e[2].value;
						else if (e.length==5)
							val=e[0].value+"-"+e[1].value+"-"+e[2].value+" "+e[3].value+":"+e[4].value;
					}
				}
			}
			else
			{
				switch(el.type)
				{
					case "checkbox":
						if (el.checked==true)
							val=1;
					break;
					case "select-one":
					case "select-multiple":
						if (el.value)
							val=el.value;
					break;
					default:
						if (el.value)
							val=el.value;
						else if (el.innerHTML)
							val=el.innerHTML;
					break;
				}
			}

			if (!val)
			{
				if ((rule=='required'))
					return false;
				else if (rule!='confirmPassword')
					return true;
			}
			
			switch(rule)
			{
				case 'between':
					return (((val.length)>=eval(params.param1)) && ((val.length)<=eval(params.param2))) ? true:false
				break;
				case 'comparison':
					if (isNaN(val))
						return false;
	
						switch(params.param1) {
							case 'isgreater':
							case '>':
								return (eval(val)>eval(params.param2))?true:false
							break;
							case 'isless':
							case '<':
								return (eval(val)<eval(params.param2))?true:false
							break;
							case 'greaterorequal':
							case '>=':
								return (eval(val)>=eval(params.param2))?true:false
							break;
							case 'lessorequal':
							case '<=':
								return (eval(val)>=eval(params.param2))?true:false
							break;
							case 'equalto':
							case '==':
								return (eval(val)==eval(params.param2))?true:false
							break;
							case 'notequal':
							case '!=':
								return (eval(val)!=eval(params.param2))?true:false
							break;
						}
				break;
				case 'alphaNumeric':
					return val.match(/[^\dA-Z]/i);
				break;
				case 'datetime':
					r=/^(?:(?:(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(\/|-|\.|\x20)(?:0?2\1(?:29)))|(?:(?:(?:1[6-9]|[2-9]\d)?\d{2})(\/|-|\.|\x20)(?:(?:(?:0?[13578]|1[02])\2(?:31))|(?:(?:0?[1,3-9]|1[0-2])\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\2(?:0?[1-9]|1\d|2[0-8])))) ([01]\d|2[0-3])(:[0-5]\d){0,2}$/
					return val.match(r);
				break;
				case 'date':
					r=/^(?:(?:(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(\/|-|\.|\x20)(?:0?2\1(?:29)))|(?:(?:(?:1[6-9]|[2-9]\d)?\d{2})(\/|-|\.|\x20)(?:(?:(?:0?[13578]|1[02])\2(?:31))|(?:(?:0?[1,3-9]|1[0-2])\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\2(?:0?[1-9]|1\d|2[0-8]))))$/
					return val.match(r);
				break;
				case 'time':
					return val.match(/^([01]\d|2[0-3])(:[0-5]\d){0,2}$/);
				break;
				case 'boolean':
					return val.match(/^0|1$/);
				break;
				case 'decimal':
					return val.match(/^[-+]?[0-9]*\.{1}[0-9]+(?:[eE][-+]?[0-9]+)?$/);
				break;
				case 'email':
					return this.validateEmail(val);
				break;
				case 'equalTo':
					return (val==params.param1)?true:false
				break;
				case 'extension':
					return val.match(params.param1);
				break;
				case 'ip':
					return val.match(/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/);
				break;
				case 'minLength':
					return (val.length<params.param1)?false:true
				break;
				case 'maxLength':
					return (val.length>params.param1)?false:true
				break;
				case 'numeric':
					return val.match(/^[-+]?[0-9]*\.{1}[0-9]+(?:[eE][-+]?[0-9]+)?$/);
				break;
				case 'phone':
					return val.match(/^\+[0-9]{11}$/);
				break;
				case 'postal':
					return val.match(/^[0-9]{2}-[0-9]{3}$/);
				break;
				case 'range':
					if (isNaN(val))
						return false;
					return (( eval(val)>eval(params.param1)) && (eval(val)<eval(params.param2))) ? true:false
				break;
				case 'inList':
					return val.match(params.param1);
				break;
				case 'login':
					return val.match(/^[a-zA-Z0-9_]*$/);
				break;
				case 'alpha':
					return val.match(/^[a-zA-Z]*$/);
				break;
				case 'smallalpha':
					return val.match(/^[a-z]*$/);
				break;
				case 'bigalpha':
					return val.match(/^[A-Z]*$/);
				break;
				case 'alphanumeric':
					return val.match(/^[a-zA-Z0-9]*$/);
				break;
				case 'smallalphanumeric':
					return val.match(/^[a-z0-9]*$/);
				break;
				case 'bigalphanumeric':
					return val.match(/^[A-Z0-9]*$/);
				break;
				case 'int':
					return val.match(/^[0-9]+$/);
				break;
				case 'float':
					return val.match(/^[0-9]+,[0-9]+$/);
				break;
				case 'tags':
					return val.match(/^[ ]*[\w ,]*[ ]*$/);
				break;
				case 'required':
					return val;
				break;
				case 'checked':
					return val
				break;
				case 'selected':
					return val
				break;
				case 'custom':
				case 'regex':
					return val.match(params.param1);
				break;			
				case 'url':
					return val.match(/^(?:(?:https?|ftps?|file|news|gopher):\/\/)?(?:(?:(?:25[0-5]|2[0-4]\d|(?:(?:1\d)?|[1-9]?)\d)\.){3}(?:25[0-5]|2[0-4]\d|(?:(?:1\d)?|[1-9]?)\d)|(?:[0-9a-z]{1}[0-9a-z\-]*\.)*(?:[0-9a-z]{1}[0-9a-z\-]{0,62})\.(?:[a-z]{2,6}|[a-z]{2}\.[a-z]{2,6})(?::[0-9]{1,4})?)(?:\/?|\/[\w\-\.,@?^=%&:;\/~\+#]*[\w\-\@?^=%&\/~\+#])$/i);
				break;			
				case 'uniqueLogin':
					return this.uniqueLogin(tag, message);
				break;			
				case 'uniqueEmail':
					return this.uniqueEmail(tag, message);
				break;			
				case 'confirmPassword':
					return this.confirmPassword(tag);
				break;			
				default:
					try
					{
						eval("this.rule="+rule);
						return this.rule(tag, params, message);
					}
					catch(err)
					{
					}
					return true;
				break;			
			}
		}
		return true;
	},
	
	validateEmail: function(email)
	{
		if(email.length<=0)
		{
			return true;
		}
		var splitted=email.match("^(.+)@(.+)$");
		if (splitted==null)
			return false;
		if(splitted[1]!=null)
		{
			var regexp_user=/^\"?[\w-_\.]*\"?$/;
			if(splitted[1].match(regexp_user)==null)
				return false;
		}
		if(splitted[2]!=null)
		{
			var regexp_domain=/^[\w-\.]*\.[A-Za-z]{2,4}$/;
			if(splitted[2].match(regexp_domain)==null)
			{
			var regexp_ip=/^\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\]$/;
			if(splitted[2].match(regexp_ip)==null)
				return false;
			}
			return true;
		}
		return false;
	},
	
	uniqueLogin: function(tag, message)
	{
		el=$(tag);
		val=el.value;

		if ((val) && (val!=this.loginRequest))
		{
			this.loginRequest=val;
			var req = new Request({'url': this.ajaxRequestUrl+'/check_login/'+val, 'onSuccess': function(text){
				if (text.match("err"))
				{
					Validation.showMessage(tag, message)
					Validation.loginRequestResult=false;	
				}
				else
				{
					Validation.hideMessage(tag)
					Validation.loginRequestResult=true;	
				}
			}});
			req.send();
		}
		else
			return Validation.loginRequestResult;	

		return true;
	},
	
	uniqueEmail: function(tag, message)
	{
		el=$(tag);
		val=el.value;

		if ((val) && (val!=this.emailRequest))
		{
			this.emailRequest=val;
			var req = new Request({'url': this.ajaxRequestUrl+'/check_email/'+val, 'onSuccess': function(text){
				if (text.match("err"))
				{
					Validation.showMessage(tag, message)
					Validation.emailRequestResult=false;	
				}
				else
				{
					Validation.hideMessage(tag)
					Validation.emailRequestResult=true;	
				}
			}});
			req.send();
		}
		else
			return Validation.emailRequestResult;
			
		return true;		
	},
	
	confirmPassword: function(tag)
	{
		if (($(tag).value)!=($(this.modelName+"Password").value))
			return false;
		return true;
	}	
});

var Validation=new ValidationClass();
