
var FormValidator = function()
{
	this.Controls = new Array();
	this.DoSubmitControl = null;	
};
var IsValidForm = false;
FormValidator.prototype = 
{
	OnCorrect : null,
	OnError : null,
	AddControls : function(elementID)
	{
		var element = document.getElementById(elementID);
		if(!element){alert("no find control!");return;}
		if(element.tagName.toLowerCase() != "input" && element.tagName.toLowerCase() != "textarea" && element.tagName.toLowerCase() != "select")
		{
			alert("no support control!");
		}
		var validatorControl = new ValidatorControl(element);
		validatorControl.Parent = this;
		var index = this.Controls.push(validatorControl);
		return validatorControl;
	},

	BindSubmitButton : function(buttonID)
	{
		if(buttonID)
		{
			var button = document.getElementById(buttonID);
			if(button)
			{
				this.Button = button;
				this.Button.onclick = Function.CreateDelegate(this,this.DoValidation);
				return;
			}
		}
	},
	
	DoValidation : function()
	{
		var _control = null;
		var _isValid = true;
		
		for(var i = 0;i<this.Controls.length;i++)
		{
			_control = this.Controls[i];
			_control.DoValidation();
			if(_isValid)
			{
			    _isValid = _control.IsValid();
			}
		}	
		IsValidForm =_isValid 
		return _isValid;
	}
}


var ValidatorControl = function(element)
{
	this.Element = element;
	this.Executor = new ValidatorExecutor();
	this.Executor.Parent = this;
}
ValidatorControl.prototype = 
{
	Element : null,
	Parent : null, //parent control
	ToolTip : null,
	CorrectMessage : "",
	OldValue : null,
	OnCorrect : null, //function
	OnError : null,//function
	Executor : null, //ValidatorExecutor
	HasAjaxValidator : false,
	Init : function(_options)
	{
//		var setting = 
//		{
//		//	ToolTipId : "",
//			CorrectMessage : "",
//		//	oncorrect : null, //function
//		//  onerror : null, //function
//		//	onfocus : null, //function
//		//	onblur : null //function
//		};
		var ops = _options || {};
		if(ops.ToolTipId)
		{
			if(document.getElementById(ops.ToolTipId))
			{
				this.ToolTip = document.getElementById(ops.ToolTipId);
			}
			else
			{
				alert("need toolTipId attribute");
			}
		}
		else
		{
			alert("need toolTipId attribute");
		}
		if(ops.onfocus)
		{
			this.Element.onfocus  = ops.onfocus;
		}
		if(ops.onBlur)
		{
			//this.Element.onblur  = ops.onblur;
		}
		if(ops.CorrectMessage)
		{
			this.CorrectMessage = ops.CorrectMessage;
		}
		if(ops.oncorrect)
		{
			this.OnCorrect = Function.CreateDelegate(this.Element,ops.oncorrect);
		}
		if(ops.onerror)
		{
			this.OnError = Function.CreateDelegate(this.Element,ops.onerror);
		}
		
		this.BindEvent();
		return this.Executor;
	},
	BindEvent : function()
	{
		this.Element.onblur = Function.CreateDelegate(this,this.DoEventValidation);
	},
	DoEventValidation : function()
	{
		return this._DoValidation();
	},
	DoValidation : function()
	{
		return this._DoValidation();
	},
	_DoValidation : function()
	{
		var _result = this.Executor.DoValidation();

		if(_result == true)
		{
		    return true;
		}
		
		return false;
	},
	ShowMessage : function(isValid,message,isLoad)
	{
		if(message == null)
		{
			this.ToolTip.className = "";
			this.ToolTip.innerHTML = "";
			return;
		}
		var cssClass = "";
		
		if(isLoad)
		{
			cssClass = "onLoad";
		}
		else
		{
			if(isValid)
			{
				cssClass = "onCorrect";
			}
			else
			{
				cssClass = "onError";
			}
		}
		this.ToolTip.className = cssClass;
		this.ToolTip.innerHTML = message;
	},
	
	IsValid : function()
	{
        return this.Executor.IsValid;
	}
}

var ValidatorExecutor = function(validationControl)
{
	this.Parent = validationControl;
	this.Validators = new Array();
	this.AjaxValidators = new Array();
}
ValidatorExecutor.prototype = 
{
	Parent : null, //parent control
	IsValid : false,
	InputSet : function(_options)
	{
		var setting = 
		{
			Type : "size", //size,number 
			Min : 1,
			Max : null,
			ErrorMessage : "InputError"
		};
		var ops = _options || {};
		this.SetSettings(setting,ops);
		var inputValidator = new InputValidator(this.Parent.Element,setting);
		inputValidator.Parent = this;
		this.Validators.push(inputValidator);
		return this;
	},
    CompareSet : function(_options)
    {
	    var setting = 
	    {
		    TargetId : "", 
		    Operateor : "=", //=,!=,>,>=,<,<=
		    ErrorMessage : "CompareError"
	    };
	    var ops = _options || {};
	    this.SetSettings(setting,ops);
	    var compareValidator = new CompareValidator(this.Parent.Element,setting);
	    compareValidator.Parent = this;
	    this.Validators.push(compareValidator);
	    return this;
    },
    
    RegexSet : function(_options)
	{
		var setting = 
		{
			RegExpress : "", 
			Param : "i", 
			DataType : "string", //string or enum
			ErrorMessage : "regexError"
		};
		var ops = _options || {};
		this.SetSettings(setting,ops);
		var regexValidator = new RegexValidator(this.Parent.Element,setting);
	    regexValidator.Parent = this;
	    this.Validators.push(regexValidator);
		return this;
	},
	
	FunctionSet : function(_options)
	{
	    var setting = 
		{
			Fun : function(){return false;}, 
			ErrorMessage : ""
		};
		var ops = _options || {};
		this.SetSettings(setting,ops);
		var functionValidator = new FunctionValidator(this.Parent.Element,setting);
	    functionValidator.Parent = this;
	    this.Validators.push(functionValidator);
		return this;
	},
	
	AjaxSet : function(_options)
	{
		var setting = 
		{
			Method : "GET", 
			Url : window.location, //=,!=,>,>=,<,<=
			ServerErrorMessage : "服务器没有返回数据，可能服务器忙，请重试",
			ErrorMessage : "Error",
			LoadingMessage : "正在执行验证，请稍等...",
			onResponse : null
		};

		var ops = _options || {};
		this.SetSettings(setting,ops);
		var ajaxValidator = new AjaxValidator(this.Parent.Element,setting);
		ajaxValidator.Parent = this;
		this.AjaxValidators.push(ajaxValidator);
		return this;
	},
	SetSettings : function(setting,joinArr)
	{
		for (prop in setting)
		{
			if(joinArr[prop])
			{
				setting[prop]=joinArr[prop];
			}
		}
	},
	DoValidation : function()
	{
		var _isValid = true;
		var _validator;
		for(var i = 0 ;i < this.Validators.length;i++)
		{
			_validator = this.Validators[i];
			_isValid = _validator.DoValidation();

			if(!_isValid)
			{
			    this.IsValid = false;
				this.OnError();
				return false;
			}
		}

		if(this.AjaxValidators.length > 0)
		{
		    _isValid = this.DoAjaxValidation();
			if(_isValid == false)
			{
			    this.IsValid = false;
			    return false;
			}
			else if(_isValid == null)
			{
			    this.IsValid = false;
			    return null;
			}
		}		
		this.IsValid = true;
		this.Parent.ShowMessage(true,this.Parent.CorrectMessage,false);
		this.OnCorrect();
		return true;
	},
	DoAjaxValidation : function()
	{
		var _ajaxvalidator;
		var _isValid = true;
		for(var i = 0 ;i < this.AjaxValidators.length;i++)
		{
			_ajaxvalidator = this.AjaxValidators[i];
			if(_isValid)
			{
			    _isValid = _ajaxvalidator.DoValidation();
			}
		}
		
		return _isValid;
	},

	OnCorrect : function()
	{
	    if(this.Parent.OnCorrect)
	    {
	        this.Parent.OnCorrect();
	    }
	},
	OnError : function()
	{
	    if(this.Parent.OnError)
	    {
	        this.Parent.OnError();
	    }
	}
};

var InputValidator = function(element,setting)
{
	this.Element = element;
	this.Setting = setting;
}

InputValidator.prototype = 
{
	Parent : null, //parent control
	Setting : null, 
	Element : null, //element
	IsValid : false,
	
	DoValidation : function()
	{
		return this._Validation();
	},
	_Validation : function()
	{
		var value;
		var type = this.Element.type;
		var hasError = false;
		
		switch(this.Setting.Type)
		{
			case "size":
				value = this.Element.value.length;
				break;
			case "number":
				value = this.Element.value;
				value = (new Number(value)).valueOf();
				hasError = isNaN(value);
				break;
  		}

		if(hasError)
		{
			this.IsValid = false;
			this.Parent.Parent.ShowMessage(false,this.Setting.ErrorMessage,false);
			return false;
		}
		this.IsValid = true;
		if(value < this.Setting.Min)
		{
			this.IsValid = false;
			this.Parent.Parent.ShowMessage(false,this.Setting.ErrorMessage,false);
		}
		else  if(this.Setting.Max!=null)
		{
			if(value > this.Setting.Max)
			{
				this.IsValid = false;
				this.Parent.Parent.ShowMessage(false,this.Setting.ErrorMessage,false);
			}
		}
		return this.IsValid;
	}
}

var CompareValidator = function(element,setting)
{
	this.Element = element;
	this.Setting = setting;
	
//	if(document.attachEvent)
//	{
//		document.getElementById(this.Setting.TargetId).attachEvent("onblur",Function.CreateDelegate(this,this._Validation));
//	}
//	else
//	{
//		document.getElementById(this.Setting.TargetId).addEventListener("blur",Function.CreateDelegate(this,this._Validation),false);
//	}
};
CompareValidator.prototype = 
{
	Parent : null, //parent control
	Setting : null, 
	Element : null, //element
	IsValid : false,

	DoValidation : function()
	{
		return this._Validation();
	},
	_Validation : function()
	{
		var value = this.Element.value;
	    var targetValue = document.getElementById(this.Setting.TargetId).value;
		var _isValid = false;
		switch(this.Setting.Operateor)
	    {
	        case "=":
	            _isValid = value == targetValue;
				break;
	        case "!=":
				_isValid = value != targetValue;
				break;
	        case ">":
	            _isValid = value > targetValue;
				break;
	        case ">=":
	            _isValid = value >= targetValue;
				break;
	        case "<": 
	            _isValid = value < targetValue;
				break;
	        case "<=":
	            _isValid = value <= targetValue;
				break;
			default:
				_isValid = false;
				break;
	    }
		this.IsValid = _isValid;
		if(!_isValid)
		{
		    this.Parent.Parent.ShowMessage(false,this.Setting.ErrorMessage,false);
		}
		else
		{
		    this.Parent.Parent.ShowMessage(true,"",false);
		}
		return _isValid;
	}
};
//var setting = 
//{
//	RegExpress : "", 
//	Param : "i", 
//	DataType : "string", //string or enum
//	ErrorMessage : "regexError",
//};
var RegexValidator = function(element,setting)
{
	this.Element = element;
	this.Setting = setting;
};

RegexValidator.prototype = 
{
	Parent : null, //parent control
	Setting : null, 
	Element : null, //element
	IsValid : false,
	DoValidation : function()
	{
		return this._Validation();
	},
	_Validation : function()
	{
		var value = this.Element.value;
		var regExpress = this.Setting.RegExpress;
		if(this.Setting.DataType == "enum")
		{
			regExpress = regexEnum[regExpress];
		}
		
		if(regExpress == undefined || regExpress == "")
		{
		    alert("no find enum");
		    this.Parent.Parent.ShowMessage(false,this.Setting.ErrorMessage,false);
			return false;
		}
		
		this.IsValid = (new RegExp(regExpress, this.Setting.param)).test(value);
		
		if(!this.IsValid)
		{
		    this.Parent.Parent.ShowMessage(false,this.Setting.ErrorMessage,false);
		}
		
		return this.IsValid;
	}
};

//var setting = 
//{
//	Fun : null, 
//	ErrorMessage : "functionError",
//};
var FunctionValidator = function(element,setting)
{
	this.Element = element;
	this.Setting = setting;
};
FunctionValidator.prototype = 
{
    Parent : null, //parent control
	Setting : null, 
	Element : null, //element
	IsValid : false,
	
	DoValidation : function()
	{
		return this._Validation();
	},
	
	_Validation : function()
	{
	    var _isValid = this.Setting.Fun.call(this.Element);
	    if(!_isValid)
	    {
	        this.Parent.Parent.ShowMessage(false,this.Setting.ErrorMessage,false);
	    }
	    this.IsValid = _isValid;
	    return _isValid;
	}
};

var AjaxValidator = function(element,setting)
{
	this.Element = element;
	this.Setting = setting;
	this.Ajax = new Ajax();
	this.Ajax.Url = this.Setting.Url;
	this.Ajax.Method =this.Setting.Method;
	this.Ajax.RequestHeadKey = "x-stoneajax";
	this.Ajax.RequestHeadValue = "nothing";
	this.Ajax.OnLoad = Function.CreateDelegate(this,this.OnAjaxLoading);
	this.Ajax.OnError = Function.CreateDelegate(this,this.OnAjaxServerError);
	this.Ajax.OnComplete = Function.CreateDelegate(this,this.OnAjaxComplete);
}

AjaxValidator.prototype = 
{
    IsValidation : false,
	Parent : null,
	Setting : null, 
	Element : null,
	IsValid : false,
	Ajax : null,
	OldValue : null,
	OldMessage : null,
	
	OnAjaxLoading : function()
	{
		this.Parent.Parent.ShowMessage(true,this.Setting.LoadingMessage,true);
	},
	OnAjaxServerError : function()
	{
	    this.Element.disabled = false;
	    this.IsValidation = false;
	    this.IsValid = false;
	    this.Parent.OnError();
	    this.OldMessage = this.Setting.ServerErrorMessage;
		this.Parent.Parent.ShowMessage(true,this.Setting.ServerErrorMessage,true);
	},
	OnAjaxComplete : function(responseText)
	{
	    this.Element.disabled = false;
		this.IsValidation = false;
		if(this.Setting.onResponse)
		{
			this.IsValid = this.Setting.onResponse(responseText);
		}
		
		if(this.IsValid)
		{
		    //if(this.Parent.CheckIsAllValid())
		    //{
		        
		        this.Parent.IsValid = true;    
		        this.Parent.OnCorrect();
		    //}
		    this.OldMessage = this.Setting.CorrectMessage;
		    this.Parent.Parent.ShowMessage(true,this.Parent.Parent.CorrectMessage,false);
	    }
	    else
	    {
	        this.IsValid = false;
	        this.Parent.IsValid = false;
	        this.Parent.OnError();
	        this.OldMessage = this.Setting.ErrorMessage;
	        this.Parent.Parent.ShowMessage(false,this.Setting.ErrorMessage,false);
	    }
		
	},
	DoValidation : function()
	{
	    if(this.OldValue == this.Element.value)
	    {
	        this.Parent.Parent.ShowMessage(this.IsValid,this.OldMessage,false);
	        return this.IsValid;
	    }
	    this.OldValue = this.Element.value;
	    this.Element.disabled = true;
	    this.IsValidation = true;
        this.IsValid = false;
        
        var para  = "";
		para += this.Element.id + "=" + this.Element.value;
		this.Ajax.QueryString = para;
		this.Ajax.DoRequest.call(this.Ajax);
		return false;
	},
	_Validation : function()
	{
		return this.IsValid;
	}
};

Function.CreateDelegate = function(instance, method)
{
	return function()
	{
        return method.apply(instance, arguments);
    }
}

Function.CreateXMLHttpRequest = function()
{
    if (window.ActiveXObject)
    {
        return new ActiveXObject("Microsoft.XMLHTTP");
    }
    else if (window.XMLHttpRequest)
    {
        return new XMLHttpRequest();
    }
    else
    {
        return null;
    } 
}

