// JavaScript Document
var Validator = Class.create(
{
	initialize:function(ele,options){
		this.ele = $(ele);
		
		this.handlers=[
			this.validRequiredField,
			this.validEmailField,
			this.validPasswordField,
			this.validUniqueField
		];
		this.is_stop=false;
		
	},
	valid:function(returnHandler){
		
		if(!returnHandler) returnHandler=Prototype.emptyFunction;
		document.fire("validator:beforeValidResult");
		
		$$(".validator-error").invoke("removeClassName","validator-error");
		
		if(this.is_stop) return true;
		var is_valid=true;
		var valid_return_count=this.handlers.length;
		
		this.handlers.each(
			function(h){
					
				h.bind(this)(function(r){
								
					 --valid_return_count;
					 
					 if(is_valid && !r) is_valid=false;
					 
					 if(valid_return_count==0) {
						
						returnHandler(is_valid);
						
					}
				  }.bind(this));
				
				
			}.bind(this)
		);
		document.fire("validator:afterAllValidation");
		return is_valid;
	},
	addValidHandler:function(handler){
		this.handlers.push(handler);
	},
	stopValid:function(){
		this.is_stop=true;
	},
	validRequiredField:function(returnHandler){
		
		is_valid=true;
		Element.select(this.ele,"select.validator-required, input.validator-required, textarea.validator-required").each(
			function(input){
				
				if(!input.disabled && input.visible() && !input.present()){
					if(ele_container=Element.up(input,".validator-group-require-one")){
						is_valid=!!Element.select(ele_container,".validator-required").find(Form.Element.present);
						if(!is_valid){
							this.afterValidFail(input,this.ele.readAttribute("validator:error_msg_required"),"validRequiredField");
						}
					}else{
						is_valid=false;
						
						this.afterValidFail(input,this.ele.readAttribute("validator:error_msg_required"),"validRequiredField");
					}
				}
			}.bind(this)
		);
		
		returnHandler(is_valid);
	},
	validEmailField:function(returnHandler){
		var  is_valid=true;
		Element.select(this.ele,"input.validator-email").each(
			function(input){
				if(!$F(input).isEmail() && input.present() && input.visible()){
					is_valid=false;
					this.afterValidFail(input,this.ele.readAttribute("validator:error_msg_email"));
				}
			}.bind(this)
		);
		returnHandler(is_valid);
		//return is_valid;
	},
	validPasswordField:function(returnHandler){
		var is_valid=true;
		var dict={};
		var input=null;
		Element.select(this.ele,"input.validator-password").each(
			function(input){
				
				if(input.present()){
					if(attr_password_range = input.readAttribute("validator:password_range")){
						prange = attr_password_range.split("-");
						if($F(input).length<prange[0] || $F(input).length>prange[1]){
							this.afterValidFail(input,this.ele.readAttribute("validator:error_msg_password_format"));
						}
					}
					if(attr_password_regex = input.readAttribute("validator:password_regex")){
						if($F(input).match(attr_password_regex)!=$F(input)){
							this.afterValidFail(input,this.ele.readAttribute("validator:error_msg_password_format"));
						}
					}
				}
				
				if(!dict[input.name]){
					dict[input.name]=$F(input);
				}else{
					if(dict[input.name]!=$F(input) && input.visible()){
						is_valid=false;
						this.afterValidFail(input,this.ele.readAttribute("validator:error_msg_password"));
					}
				}
			}.bind(this)
		);
		returnHandler(is_valid);
		//return is_valid;
	},
	validUniqueField:function(returnHandler){
		var is_valid=true;
		//last_action = this.ele.action;
		//this.ele.action=this.ele.readAttribute("validator:exists_checking_url");
		elelist = Element.select(this.ele,".validator-unique");
		if(elelist.length==0){
			returnHandler(true);
			return;	
		}
		elelist.each(
			function(input){
				var url = input.readAttribute("validator:exists_checking_url") || this.ele.readAttribute("validator:exists_checking_url");
				if(url){
					new Ajax.Request(
						url,
						{
							parameters:this.ele.serialize(),
							onSuccess:function(t,r){
								if(!r){
									is_valid=true;
								}else{
									is_valid=false;
									this.validator.afterValidFail(this.input,this.validator.ele.readAttribute("validator:error_msg_exists"));
								}
								returnHandler(is_valid);
							}.bind({validator:this,input:input}),
							onComplete:function(t){
								
							}
						}
					);
				}
				/*if(r[input.readAttribute("name")]>0){
					is_valid=false;
					this.afterValidFail(input,this.ele.readAttribute("validator:error_msg_exists"));
					returnHandler(is_valid);
				}*/
			}.bind(this)
		);
		
		
		/*var url = this.ele.readAttribute("validator:exists_checking_url");
		if(url){
			new Ajax.Request(
				this.ele.readAttribute("validator:exists_checking_url"),
				{
					parameters:this.ele.serialize(),
					asynchronous:false,
					onSuccess:function(t,r){
						this.ele.select(".validator-unique").each(
							function(input){
								if(r[input.readAttribute("name")]>0){
									is_valid=false;
									this.afterValidFail(input,this.ele.readAttribute("validator:error_msg_exists"));
									returnHandler(is_valid);
								}
							}.bind(this)
						);
						if(is_valid) returnHandler(true);
					}.bind(this)
				}
			);
		}else{
			returnHandler(true);
		}*/
		/*this.ele.request(
			{
				onSuccess:function(t,r){
					this.ele.select(".validator-unique").each(
						function(input){
							if(r[input.readAttribute("name")]>0){
								is_valid=false;
								this.afterValidFail(input,this.ele.readAttribute("validator:error_msg_exists"));
								returnHandler(is_valid);
							}
						}.bind(this)
					);
					if(is_valid) returnHandler(true);
				}.bind(this)
			}
		);
		this.ele.action=last_action;*/
	},
	observe:function(eventname,handler){
		document.observe("validator:"+eventname,handler);
	},
	afterValidFail:function(input,msg){
		input.addClassName("validator-error");
		document.fire("validator:afterValidFail",{input:input,msg:msg.interpolate({title:input.readAttribute("title")})});
	},
	cancel:function(){
		this.is_cancelled=true;
	},
	submit:function(){
		this.is_cancelled=false;
		this.valid(function(is_valid){
			document.fire("validator:afterValidResult",is_valid);
			if(is_valid && !this.is_cancelled){
				this.ele.submit();
			}
		}.bind(this));
	},
	request:function(ajaxOptions){
		this.is_cancelled=false;
		this.valid(function(is_valid){
			document.fire("validator:afterValidResult",is_valid);
			if(is_valid && !this.is_cancelled){
				this.ele.request(ajaxOptions);
			}
		}.bind(this));
		
	}
}
);

Component.init("form.validator","Validator",{});
