var Validation = {

	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)
		{
			d.html('');
			d.css('display', 'none');
		}	
	},
	
	showMessage: function(tag, message)
	{
		d=$("#"+tag+"Error")
		if (d)
		{
			d.html('<div class="error-message">'+message+'</div>');
			d.css('display', 'block');
		}	
	},
	
	hideSubmitMessage: function()
	{
		d=$("#SubmitFormError")
		if (d)
		{
			d.html('');
			d.css('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).blur(function(){
				Validation.validateTag(tag);
			});	
			
			
		  	$("#"+tag).keyup(function(){
				if (Validation.timer)
					clearTimeout(Validation.timer);		
				Validation.timer=setTimeout(function(){
					Validation.validateTag(tag);
				},1000);
			});
			
		  	$("#"+tag).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").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.attr("type"))
			{
				//radio
				e=el.find('input');
				if (e)
				{
					e.each(function(v){
							if ((Validation.attr("type")=="radio") && (Validation.attr("checked")))
								val=Validation.attr("value");
					});
				}
	
				if (!val)
				{
					//date selector
					e=el.find('select');
					if (e)
					{						
						if (e.length==3)
							val=e.eq(0).attr("value")+"-"+e.eq(1).attr("value")+"-"+e.eq(2).attr("value");
						else if (e.length==5)
							val=e.eq(0).attr("value")+"-"+e.eq(1).attr("value")+"-"+e.eq(2).attr("value")+" "+e.eq(3).attr("value")+":"+e.eq(4).attr("value");
					}
				}
			}
			else
			{
				switch(el.attr("type"))
				{
					case "checkbox":
						if (el.attr("checked")==true)
							val=1;
					break;
					case "select-one":
					case "select-multiple":
						if (el.attr("value"))
							val=el.attr("value");
					break;
					default:
						if (el.attr("value"))
							val=el.attr("value");
						else if (el.text())
							val=el.text();
					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.attr("value");
		
		if ((val) && (val!=this.loginRequest))
		{
			this.loginRequest=val;
			$.ajax({
				  url: this.ajaxRequestUrl+'/check_login/'+val+'/',
				  cache: false,
				  success: function(html){
						if (html.match("err"))
						{
							Validation.showMessage(tag, message)
							Validation.emailRequestResult=false;	
						}
						else
						{
							Validation.hideMessage(tag)
							Validation.emailRequestResult=true;	
						}				    
				  }
			});	
		}
		else
			return Validation.loginRequestResult;	

		return true;
	},
	
	uniqueEmail: function(tag, message)
	{
		el=$("#"+tag);
		val=el.attr("value");
		
		if ((val) && (val!=this.emailRequest))
		{
			this.emailRequest=val;

			$.ajax({
				  url: this.ajaxRequestUrl+'/check_email/'+val+'/',
				  cache: false,
				  success: function(html){
						if (html.match("err"))
						{
							Validation.showMessage(tag, message)
							Validation.emailRequestResult=false;	
						}
						else
						{
							Validation.hideMessage(tag)
							Validation.emailRequestResult=true;	
						}				    
				  }
			});	
			
		}
		else
			return Validation.emailRequestResult;
			
		return true;		
	},
	
	confirmPassword: function(tag)
	{
		if (($("#"+tag).attr("value"))!=($("#"+this.modelName+"Password").attr("value")))
			return false;
		return true;
	}	
};