$package('com.trs.validator');

$import('com.trs.validator.ValidatorConfig');
$import('com.trs.validator.SystemValidator');
$import('com.trs.validator.MoreCustomValidator');
$import('com.trs.dialog.Dialog');
$importCSS('com.trs.validator.css.validator');

var ValidationFactory = Class.create();
ValidationFactory.makeValidator = function(_field){
	var eField = $(_field);
	var validatorIns = null;	
	try{
		eval("var validateObj = {" + eField.getAttribute("validation") + "}");
	}catch(err){
		alert('Validation\u5C5E\u6027\u521B\u5EFA\u5931\u8D25\uFF01\nfield[' 
			+ (eField.name || eField.id) + ']\nvalidation[' + eField.getAttribute('validation') + ']');
		return;
	}
	_field.setAttribute("_VALIDATEOBJ_", validateObj);
//	try{	
		if(validateObj[$ValidatorConfigs.TYPE] == undefined){
			validatorIns = new Abstract.Validator(_field);		
		}else{
			validatorIns = ValidationFactory._makeValidator(validateObj[$ValidatorConfigs.TYPE], _field);
		}
//	}catch(_error){
//		alert("ValidationFactory.makeValidator:" + _error.message);
//		return;
//	}	
	_field.setAttribute("_VALIDATORINS_", validatorIns);
	return validatorIns;
};

ValidationFactory._makeValidator = function(type, _field){
	var validatorIns = null;
	switch(type.toLowerCase()){
		case "int":
		case "float":
			validatorIns = new NumberValidator(_field);
			break;
		case "date":
			validatorIns = new DateValidator(_field);
			break;
		case "url":
			validatorIns = new URLValidator(_field);
			break;
		case "string":
			validatorIns = new StringValidator(_field);
			break;			
		case "ip":
		case "ipv4":
			validatorIns = new IPV4Validator(_field);
			break;
		case "email":
			validatorIns = new EmailValidator(_field);
			break;
		case "common_char":
			validatorIns = new CommonCharValidator(_field);
			break;
		default:
			eval("validatorIns = new Custom_" + type.toLowerCase() + "_Validator(_field)");
	}
	return validatorIns;
};

var ValidationHelper = Class.create();
ValidationHelper.doAlert = function(_sMsg, _func){
	_func = _func || Prototype.emptyFunction;
	try{
		$alert(_sMsg, function(){
			$dialog().hide();
			_func();
		});
	}catch (ex){
		alert(_sMsg);
	}
};

/*
*\u6DFB\u52A0\u9A8C\u8BC1\u5408\u6CD5\u65F6\u9700\u6267\u884C\u7684\u56DE\u8C03\u51FD\u6570
*callBackFun	\u56DE\u8C03\u51FD\u6570\u540D
*validationId	validation\u7F16\u53F7
*/
ValidationHelper.validFuns = {};
ValidationHelper.addValidListener = function(callBackFun, validationId){
	validationId = validationId || '$NoValidationId';
	if(!ValidationHelper.validFuns[validationId]){
		ValidationHelper.validFuns[validationId] = [callBackFun];
		return;
	}
	if(!ValidationHelper.validFuns[validationId].include(callBackFun)){
		ValidationHelper.validFuns[validationId].push(callBackFun);
	}
};

/*
*\u6DFB\u52A0\u9A8C\u8BC1\u4E0D\u5408\u6CD5\u65F6\u9700\u6267\u884C\u7684\u56DE\u8C03\u51FD\u6570
*callBackFun	\u56DE\u8C03\u51FD\u6570\u540D
*validationId	validation\u7F16\u53F7
*/
ValidationHelper.invalidFuns = {};
ValidationHelper.addInvalidListener = function(callBackFun, validationId){
	validationId = validationId || '$NoValidationId';
	if(!ValidationHelper.invalidFuns[validationId]){
		ValidationHelper.invalidFuns[validationId] = [callBackFun];
		return;
	}
	if(!ValidationHelper.invalidFuns[validationId].include(callBackFun)){
		ValidationHelper.invalidFuns[validationId].push(callBackFun);
	}
};

/*
*\u9012\u4EA4\u67D0\u4E2A\u8868\u5355\u65F6\u6267\u884C\u7684\u51FD\u6570
*/
ValidationHelper.doSubmit = function(_field){
	var sameValidationIdControls = ValidationHelper.getSameValidationIdControls(_field);
	for (var i = 0; i < sameValidationIdControls.length; i++){
		if(sameValidationIdControls[i].getAttribute("isValid") == false){
			//\u6267\u884C\u4E0D\u5408\u6CD5\u65F6\u7684\u56DE\u8C03\u51FD\u6570
			ValidationHelper.execInvalidFuns(_field);
			return false;
		}
	}
	//\u6267\u884C\u5408\u6CD5\u65F6\u7684\u56DE\u8C03\u51FD\u6570
	ValidationHelper.execValidFuns(_field);
	return true;
};

ValidationHelper.doSubmitAll = function(){
	var validateControlsSimpleClone = ValidationHelper.getCloneControls(ValidationHelper.validateControls);
	validateControlsSimpleClone.sort(ValidationHelper.sortFun);
	while(validateControlsSimpleClone.length > 0){
		var topObj = validateControlsSimpleClone.pop();
		if(!ValidationHelper.doSubmit(topObj)){
			while(validateControlsSimpleClone.length > 0){
				if(ValidationHelper.getControlValidationId(topObj) == 
						ValidationHelper.getControlValidationId(validateControlsSimpleClone.last()))
					validateControlsSimpleClone.pop();
				else break;
			}	
		}
	}
};

ValidationHelper.sortFun = function(_field1, _field2){
	var id1 = ValidationHelper.getControlValidationId(_field1);
	var id2 = ValidationHelper.getControlValidationId(_field2);
	if(id1 < id2)return -1;
	if(id1 > id2)return 1;
	return 0;
};

//\u5F97\u5230\u6570\u7EC4arrayObj\u7684\u7B80\u5355\u62F7\u8D1D
ValidationHelper.getCloneControls = function(arrayObj){
	var cloneArrayObj = [];
	for (var i = 0; i < arrayObj.length; i++){
		cloneArrayObj[i] = arrayObj[i];
	}
	return cloneArrayObj;
};

//\u67D0\u4E2A\u8868\u5355\u6821\u9A8C\u4E0D\u5408\u6CD5\u65F6\u6267\u884C\u7684\u56DE\u8C03\u51FD\u6570
ValidationHelper.execInvalidFuns = function(_field){
	var validationId = ValidationHelper.getControlValidationId(_field);
	if(ValidationHelper.invalidFuns[validationId]){
		ValidationHelper.invalidFuns[validationId].each(function(invalidFun){invalidFun();});
	}
	return false;
};

//\u67D0\u4E2A\u8868\u5355\u6821\u9A8C\u5408\u6CD5\u65F6\u6267\u884C\u7684\u56DE\u8C03\u51FD\u6570
ValidationHelper.execValidFuns = function(_field){
	var validationId = ValidationHelper.getControlValidationId(_field);
	if(ValidationHelper.validFuns[validationId]){
		ValidationHelper.validFuns[validationId].each(function(validFun){validFun();});
	}
	return false;
};

//\u5F97\u5230\u5177\u6709\u76F8\u540CValidationId\u7684\u63A7\u4EF6\u6570\u7EC4
ValidationHelper.getSameValidationIdControls = function(_field){
	var sameValidationIdControls = [];
	var validationId = ValidationHelper.getControlValidationId(_field);
	ValidationHelper.validateControls.each(function(element){
		if(element == null) throw $continue;
		var tempValidationId = ValidationHelper.getControlValidationId(element)
		if(validationId == tempValidationId){
			sameValidationIdControls.push(element);
		}
	});
	return 	sameValidationIdControls;
};

//\u5F97\u5230\u67D0\u4E2A\u63A7\u4EF6\u7684ValidationId\uFF0C\u4F18\u5148\u7EA7\uFF1A\u81EA\u8EABvalidationId\u3001\u8868\u5355validationId\u3001\u8868\u5355id\u3001\u8868\u5355\u540D\u3001'$NoValidationId',
ValidationHelper.getControlValidationId = function(_field){
	_field = $(_field);
	var validationId = _field.getAttribute("validationId");

	if(!validationId && _field.form){
		validationId = _field.form.getAttribute("validationId") || _field.form.id || _field.form.name;
	}
	return validationId ? validationId : '$NoValidationId';
};

//\u5F97\u5230\u63A7\u4EF6\u63D0\u793A/\u8B66\u544A\u4FE1\u606F\u683C\u5F0F\u5316\u540E\u7684\u5185\u5BB9
ValidationHelper.getReplaceInfoContent = function(info, infoType, desc, _args){
	var hintString = $ValidatorConfigs[infoType]["zh-cn"][info];
	hintString = hintString.replace('{0}', desc);

	if (_args == null) return hintString;

	if (typeof _args != 'object'){
		return hintString.replace('{1}', _args);
	}
	for (var i = 0; i < _args.length; i++){
		hintString = hintString.replace('{' + (i+1) + '}', _args[i]);
	}	
	return hintString;
};

//\u521D\u59CB\u5316\u63A7\u4EF6\u7684isValid\u5C5E\u6027
ValidationHelper.initIsValid = function(element){
	var isValid = element.getAttribute("_VALIDATORINS_").execute();
	element.setAttribute("isValid", isValid);
	if(isValid) {
		ValidationHelper.addBoardToDomTree(element, "MESSAGE");
	}else{
		ValidationHelper.addBoardToDomTree(element, "WARNING");
	}
};

//\u5FC5\u586B\u9879\u6837\u5F0F\u751F\u6210\u51FD\u6570
ValidationHelper.makeRequiredHint = function(_field, _Document){
	try{
		return;
		var validateObj = _field.getAttribute("_VALIDATEOBJ_");		
		if(validateObj[$ValidatorConfigs.REQUIRED] != undefined){
			var index = _field.getAttribute("_VALID_INDEX_");
			if(_field.style.position != 'absolute'){
				afterObj = "<span class='" + $ValidatorConfigs.REQUIREDCLASS + "' id='" + $ValidatorConfigs.PREFIX_HINT_SPAN_ID + index + "'>*</span>";
				new Insertion.After(_field, afterObj);
			}else{
				var requiredObj = (_Document || document).createElement("span");
				requiredObj.id = $ValidatorConfigs.PREFIX_HINT_SPAN_ID + index;
				requiredObj.innerHTML = "*";
				requiredObj.className = $ValidatorConfigs.REQUIREDCLASS;
				var offsets = Position.cumulativeOffset(_field);
				requiredObj.style.top    = offsets[1] + "px";
				requiredObj.style.left   = (offsets[0] + _field.offsetWidth + 1) + 'px';
				requiredObj.style.position    = "absolute";
				document.body.appendChild(requiredObj);			
			}
		}
	}catch(error){
		alert("ValidationHelper.makeRequiredHint:" + error.message);	
	}
};

//\u63D0\u793A/\u8B66\u544A\u4FE1\u606F\u6837\u5F0F\u751F\u6210\u51FD\u6570
ValidationHelper.makeInfoBoard = function(_field, _option, _Document){
	var sContent = _option.content;
	sContent = 
		  //'<img id="img_' + _option.id.trim() + '" src="' + _option.logoSrc + '" style="height:18px;" align="absmiddle">' +
		 '<span id="sp_' + _option.id.trim() + '">' + sContent + '</span>';
	var oInsertionNode = (_Document||document).createElement('span');
	oInsertionNode.style.textAlgin = 'justify';
	oInsertionNode.id = _option.id;
	oInsertionNode.className = _option.className;
	oInsertionNode.innerHTML = sContent;
	oInsertionNode.style.position = 'absolute';
	oInsertionNode.style.display = 'none';
	oInsertionNode.style.opacity = '0.85';
	oInsertionNode.style.filter = 'alpha(opacity=85)';
	return oInsertionNode;
};

/*
*\u5F97\u5230\u67D0\u79CD\u63A7\u4EF6\u67D0\u79CD\u7C7B\u578B\u7684option\u4FE1\u606F\u3002\u67D0\u79CD\u4E8B\u4EF6\uFF1AKEY,MOUSE;\u67D0\u79CD\u7C7B\u578B\uFF1AMESSAGE,WARNING
*/
ValidationHelper.getOption = function(element, _infoType, _eventType){
	var validatorIns = element.getAttribute("_VALIDATORINS_");
	var index = element.getAttribute("_VALID_INDEX_");
	return {
		id: $ValidatorConfigs["PREFIX_" + _infoType + "_SPAN_ID"] + _eventType + "_" + index, 
		content: _infoType == "MESSAGE" ? validatorIns.getMessage() : validatorIns.warning, 
		logoSrc: $ValidatorConfigs[_infoType + "_LOG_PATH"], 
		className: $ValidatorConfigs[_infoType + "_CLASSNAME_" + _eventType]			
	};
};

/*
*\u5C06\u5F97\u5230\u7684dom\u5BF9\u8C61\u6DFB\u52A0\u5230dom\u6811\u4E2D
*/
ValidationHelper.addBoardToDomTree = function(element, infoType){
	var _Document = DomTools.GetElementDocument(element)||document;
	var _Window = DomTools.GetDocumentWindow(_Document)||window;
	var validateObj = element.getAttribute("_VALIDATEOBJ_");			
	var showControlId = validateObj[$ValidatorConfigs.SHOWID];
	if(!showControlId && element.form){
		showControlId = element.form.getAttribute($ValidatorConfigs.SHOWID);
	}
	var option = ValidationHelper.getOption(element, infoType, "KEY");
	boardObj = ValidationHelper.makeInfoBoard(element, option, _Document);
	if(showControlId){
		if(typeof(showControlId) == 'function'){
			showControlId = showControlId();
		}else if(typeof(showControlId) == 'string'){
			showControlId = _Window.$(showControlId);
		}
		$removeChilds(showControlId);
		//showControlId.innerHTML = boardObj.outerHTML;
		showControlId.appendChild(boardObj);
		boardObj.style.position = 'static';
		var noClass = validateObj[$ValidatorConfigs.NO_CLASS];
		if(noClass == undefined && element.form){
			noClass = element.form.getAttribute($ValidatorConfigs.NO_CLASS);
		}
		if(noClass != undefined){
			boardObj.className = '';
		}
	}else{
		if(element.style.position=='absolute'){
			var offsets = Position.cumulativeOffset(element);
			boardObj.style.top    = offsets[1] + "px";
			boardObj.style.left   = (offsets[0] + element.offsetWidth + 5) + 'px';		
			_Document.body.appendChild(boardObj);
		}else{
			var afterElement = element;
			if(validateObj[$ValidatorConfigs.REQUIRED] != undefined){
				while(afterElement){
					afterElement = afterElement.nextSibling;
					if(afterElement==null||afterElement.nodeType==1)break;
				}
			}
			if(afterElement!=null){
				new _Window.Insertion.After(afterElement, boardObj.outerHTML);
				afterElement.nextSibling.style.position = 'static';
				return afterElement.nextSibling;			
			}
		}
	}
	return boardObj;
};

//\u63D0\u793A/\u8B66\u544A\u4FE1\u606F\u4E00\u76F4\u663E\u793A
ValidationHelper.showAllTime = function(element){
	var validatorIns = element.getAttribute("_VALIDATORINS_");
	var boardObjMessage = ValidationHelper.addBoardToDomTree(element, "MESSAGE");
	Element.show(boardObjMessage);
};

//target:fix a bug,
/*
\u5728\u8F93\u5165\u6846\u4E2D\u6309\u4E0B\u4E00\u4E2A\u5B57\u6BCD\u952E\uFF0C\u8F93\u5165\u51E0\u4E2A\u540E\uFF0C\u624B\u6307\u4E0D\u8981\u79BB\u5F00\u6309\u952E\uFF0C
\u7528\u9F20\u6807\u5728\u53E6\u4E00\u4E2A\u8F93\u5165\u6846\u4E2D\u70B9\u4E00\u4E0B\uFF0C\u539F\u63D0\u793A\u4FE1\u606F\u4E0D\u51C6\u786E\u3002
\u5982\uFF1A\u552F\u4E00\u6807\u8BC6\u63D0\u793A\u8BF4\u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u4F46\u4E8B\u5B9E\u4E0A\u662F\u6709\u503C\u7684\u3002
*/
ValidationHelper.keyDownEvent = function(element, event){
	var _Document = DomTools.GetElementDocument(element)||document;
	var _Window = DomTools.GetDocumentWindow(_Document)||window;
	event = event || _Window.event;
	if(event.keyCode == Event.KEY_TAB || event.keyCode == Event.KEY_RETURN){
		element.releaseCapture();
	}else{
		element.setCapture();
	}
};

ValidationHelper.keyUpEvent = function(element, event){
	var _Document = DomTools.GetElementDocument(element)||document;
	var _Window = DomTools.GetDocumentWindow(_Document)||window;
	event = event || _Window.event;
	element.releaseCapture();
	var validatorIns = element.getAttribute("_VALIDATORINS_");
	var index = element.getAttribute("_VALID_INDEX_");
	var boardObjWarning = _Window.$($ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "KEY_" + index);
	var boardObjMessage = _Window.$($ValidatorConfigs.PREFIX_MESSAGE_SPAN_ID + "KEY_" + index);
	var isValid = validatorIns.execute();
	element.setAttribute("isValid", isValid);

	if(isValid) {
		if(!boardObjMessage){
			boardObjMessage = ValidationHelper.addBoardToDomTree(element, "MESSAGE");
		}
		if($ValidatorConfigs.getShowAllMode() || $ValidatorConfigs.getFocusMode()){
			if(boardObjWarning) Element.hide(boardObjWarning);	
			Element.show(boardObjMessage);
		}
		changeBorderStyle(element);	
		return ValidationHelper.doSubmit(element);	
		ValidationHelper.doSubmit(element);	
	}else{
		if(!boardObjWarning){
			boardObjWarning = ValidationHelper.addBoardToDomTree(element, "WARNING");
		}
		if(_Window.$('sp_' + $ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "KEY_" + index))
			_Window.$('sp_' + $ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "KEY_" + index).innerHTML = validatorIns.warning;
		if($ValidatorConfigs.getShowAllMode() || $ValidatorConfigs.getFocusMode()){
			if(boardObjMessage) Element.hide(boardObjMessage);	
			Element.show(boardObjWarning);
		}
		changeBorderStyle(element, $ValidatorConfigs["WARNING_BORDER"]);
		return ValidationHelper.execInvalidFuns(element);
		ValidationHelper.execInvalidFuns(element);
	}
};

ValidationHelper.changeEvent = function(element, _bNotChangeStyle){
	element = $(element);
	var _Document = DomTools.GetElementDocument(element)||document;
	var _Window = DomTools.GetDocumentWindow(_Document)||window;
	var validatorIns = element.getAttribute("_VALIDATORINS_");
	var isValid = validatorIns.execute();	

	var index = element.getAttribute("_VALID_INDEX_");	
	var boardObjWarning = _Window.$($ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "KEY_" + index);
	var boardObjMessage = _Window.$($ValidatorConfigs.PREFIX_MESSAGE_SPAN_ID + "KEY_" + index);
	if(isValid){//\u6267\u884C\u4E0E\u670D\u52A1\u5668\u7AEF\u4EA4\u4E92\u7684\u68C0\u9A8C
		var validateObj = element.getAttribute("_VALIDATEOBJ_");
		if(validateObj[$ValidatorConfigs.RPC]){
			ValidationHelper.currRPC = new Object();
			ValidationHelper.currRPC.element = element;
			eval(validateObj[$ValidatorConfigs.RPC] + "();");
		}else{
			if(!_bNotChangeStyle){
				changeBorderStyle(element);	
			}
			if(!boardObjMessage){
				boardObjMessage = ValidationHelper.addBoardToDomTree(element, "MESSAGE");
			}
			if($ValidatorConfigs.getShowAllMode() || $ValidatorConfigs.getFocusMode()){
				if(boardObjWarning) Element.hide(boardObjWarning);	
				Element.show(boardObjMessage);
			}
			element.setAttribute('isValid', true);
			ValidationHelper.doSubmit(element);				
		}
	}else{
		if(!_bNotChangeStyle){
			changeBorderStyle(element, $ValidatorConfigs["WARNING_BORDER"]);
		}
		if(!boardObjWarning){
			boardObjWarning = ValidationHelper.addBoardToDomTree(element, "WARNING");
		}
		if(_Window.$('sp_' + $ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "KEY_" + index)){
			_Window.$('sp_' + $ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "KEY_" + index).innerHTML = validatorIns.warning;
		}
		if($ValidatorConfigs.getShowAllMode() || $ValidatorConfigs.getFocusMode()){
			if(boardObjMessage) Element.hide(boardObjMessage);	
			Element.show(boardObjWarning);
		}
		element.setAttribute('isValid', false);
		ValidationHelper.execInvalidFuns(element);		
	}
};

//\u4E0E\u670D\u52A1\u5668\u7AEF\u4EA4\u4E92\u68C0\u9A8C,\u7ED3\u679C\u6210\u529F\u65F6\u6267\u884C\u7684\u56DE\u8C03\u51FD\u6570
ValidationHelper.successRPCCallBack = function(message){
	changeBorderStyle(ValidationHelper.currRPC.element);	
	ValidationHelper.currRPC.element.setAttribute("isValid", true);

	var index = ValidationHelper.currRPC.element.getAttribute("_VALID_INDEX_");
	var validateObj = ValidationHelper.currRPC.element.getAttribute("_VALIDATEOBJ_");
	var boardObjMessage = $($ValidatorConfigs.PREFIX_MESSAGE_SPAN_ID + "KEY_" + index);
	if(boardObjMessage && validateObj[$ValidatorConfigs["BLUR_SHOW"]] == undefined){
		Element.hide(boardObjMessage);
	}
	var boardObjWarning = $($ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "KEY_" + index);
	if(boardObjWarning){
		Element.hide(boardObjWarning);
	}
	return true;
};

//\u4E0E\u670D\u52A1\u5668\u7AEF\u4EA4\u4E92\u68C0\u9A8C,\u7ED3\u679C\u5931\u8D25\u65F6\u6267\u884C\u7684\u56DE\u8C03\u51FD\u6570
ValidationHelper.failureRPCCallBack = function(warning){
	changeBorderStyle(ValidationHelper.currRPC.element, $ValidatorConfigs["WARNING_BORDER"]);
	var index = ValidationHelper.currRPC.element.getAttribute("_VALID_INDEX_");
	var boardObjWarning = $($ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "KEY_" + index);
	var boardObjMessage = $($ValidatorConfigs.PREFIX_MESSAGE_SPAN_ID + "KEY_" + index);
	with(ValidationHelper.currRPC.element){
		setAttribute("isValid", false);
		getAttribute("_VALIDATORINS_").warning = warning;
	}
	if(!boardObjWarning){
		boardObjWarning = ValidationHelper.addBoardToDomTree(ValidationHelper.currRPC.element, "WARNING");
	}
	var index = ValidationHelper.currRPC.element.getAttribute("_VALID_INDEX_");
	$('sp_' + $ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "KEY_" + index).innerHTML = warning;
	if($ValidatorConfigs.getShowAllMode() || $ValidatorConfigs.getFocusMode()){
		if(boardObjMessage) Element.hide(boardObjMessage);	
		Element.show(boardObjWarning);
	}
	return ValidationHelper.execInvalidFuns(ValidationHelper.currRPC.element);
};

/*
*\u63A7\u4EF6\u5F97\u5230\u7126\u70B9\u65F6\u663E\u793A\u4FE1\u606F
*/
ValidationHelper.focusEvent = function(element){	
	var validatorIns = element.getAttribute("_VALIDATORINS_");
	var index = element.getAttribute("_VALID_INDEX_");
	var boardObjWarning = $($ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "KEY_" + index);
	var boardObjMessage = $($ValidatorConfigs.PREFIX_MESSAGE_SPAN_ID + "KEY_" + index);

	if(element.getAttribute("isValid") == false && element.style.border == $ValidatorConfigs["WARNING_BORDER"]){
		if(boardObjMessage) Element.hide(boardObjMessage);
		if(!boardObjWarning){
			boardObjWarning = ValidationHelper.addBoardToDomTree(element, "WARNING");
		}
		Element.show(boardObjWarning);	
		return;	
	}
	if(boardObjWarning) Element.hide(boardObjWarning);
	if(!boardObjMessage){
		boardObjMessage = ValidationHelper.addBoardToDomTree(element, "MESSAGE");
	}
	Element.show(boardObjMessage);
};

/*
*\u63A7\u4EF6\u5931\u53BB\u7126\u70B9\u65F6\u9690\u85CF\u4FE1\u606F
*/
ValidationHelper.blurEvent = function(element){
	element = $(element);
	var _Document = DomTools.GetElementDocument(element)||document;
	var _Window = DomTools.GetDocumentWindow(_Document)||window;
	var validatorIns = element.getAttribute("_VALIDATORINS_");
	//\u5904\u7406\u4E00\u4E9B\u76F4\u63A5\u7C98\u8D34\u7684bug
	var isValid = validatorIns.execute();
	element.setAttribute("isValid", isValid);

	var validateObj = element.getAttribute("_VALIDATEOBJ_");
	var index = element.getAttribute("_VALID_INDEX_");
	var boardObjWarning = _Window.$($ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "KEY_" + index);
	var boardObjMessage = _Window.$($ValidatorConfigs.PREFIX_MESSAGE_SPAN_ID + "KEY_" + index);

	if(element.getAttribute("isValid") == false){
		if(boardObjMessage) Element.hide(boardObjMessage);
		if(!boardObjWarning){
			boardObjWarning = ValidationHelper.addBoardToDomTree(element, "WARNING", _Document);
		}
		if(_Window.$('sp_' + $ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "KEY_" + index))
			_Window.$('sp_' + $ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "KEY_" + index).innerHTML = validatorIns.warning;
		Element.show(boardObjWarning);
		changeBorderStyle(element, $ValidatorConfigs["WARNING_BORDER"]);
	}else{
		if(boardObjWarning) Element.hide(boardObjWarning);
		changeBorderStyle(element);
		if(boardObjMessage && validateObj[$ValidatorConfigs["BLUR_SHOW"]] == undefined){
			Element.hide(boardObjMessage);
		}		
		ValidationHelper.doSubmit(element);		
		if(validateObj[$ValidatorConfigs.RPC]){
			ValidationHelper.currRPC = new Object();
			ValidationHelper.currRPC.element = element;
			eval(validateObj[$ValidatorConfigs.RPC] + "();");
		}else{	
/*			
			if(boardObjWarning) Element.hide(boardObjWarning);
			changeBorderStyle(element);
			if(boardObjMessage && validateObj[$ValidatorConfigs["BLUR_SHOW"]] == undefined){
				Element.hide(boardObjMessage);
			}		
			ValidationHelper.doSubmit(element);		
*/
		}
	}
};

/*
*\u9F20\u6807\u79FB\u5230\u63A7\u4EF6\u4E0A\u65F6\u663E\u793A\u4FE1\u606F
*/
ValidationHelper.mouseOverEvent = function(element, event){
	var _Document = DomTools.GetElementDocument(element)||document;
	var _Window = DomTools.GetDocumentWindow(_Document)||window;
	var validatorIns = element.getAttribute("_VALIDATORINS_");
	var index = element.getAttribute("_VALID_INDEX_");
	var boardObjMessage = _Window.$($ValidatorConfigs.PREFIX_MESSAGE_SPAN_ID + "MOUSE_" + index);
	var boardObjWarning = _Window.$($ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "MOUSE_" + index);
	if(element.getAttribute("isValid") == false){
		if(!boardObjWarning){
			var option = ValidationHelper.getOption(element, "WARNING", "MOUSE");
			boardObjWarning = ValidationHelper.makeInfoBoard(element, option, _Document);
			_Document.body.appendChild(boardObjWarning);
//			boardObjWarning.style.left = Event.pointerX(_Window.event || event);
//			boardObjWarning.style.top = Event.pointerY(_Window.event || event);	
			Position.clone(element, boardObjWarning, {
				setWidth	:false, 
				setHeight	:false,
				offsetLeft	:element.offsetWidth,
				offsetTop:element.offsetHeight
			});
		}		
		if(_Window.$('sp_' + $ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "MOUSE_" + index))
			_Window.$('sp_' + $ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "MOUSE_" + index).innerHTML = validatorIns.warning;
		if(boardObjMessage){
			Element.hide(boardObjMessage);
		}
		Element.show(boardObjWarning);
	}else{
		if(!boardObjMessage){
			var option = ValidationHelper.getOption(element, "MESSAGE", "MOUSE");
			boardObjMessage = ValidationHelper.makeInfoBoard(element, option, _Document);
			_Document.body.appendChild(boardObjMessage);
//			boardObjMessage.style.left = Event.pointerX(_Window.event || event);
//			boardObjMessage.style.top = Event.pointerY(_Window.event || event);	
			Position.clone(element, boardObjMessage, {
				setWidth	:false, 
				setHeight	:false,
				offsetLeft	:element.offsetWidth,
				offsetTop:element.offsetHeight
			});

		}
		if(boardObjWarning){
			Element.hide(boardObjWarning);
		}	
		if(boardObjMessage.innerText.trim().length > 0){
			Element.show(boardObjMessage);
		}
	}
};

/*
*\u9F20\u6807\u79FB\u51FA\u63A7\u4EF6\u65F6\u9690\u85CF\u4FE1\u606F
*/
ValidationHelper.mouseOutEvent = function(element){
	var _Document = DomTools.GetElementDocument(element)||document;
	var _Window = DomTools.GetDocumentWindow(_Document)||window;
	var validatorIns = element.getAttribute("_VALIDATORINS_");
	var index = element.getAttribute("_VALID_INDEX_");
	var boardObjMessage = _Window.$($ValidatorConfigs.PREFIX_MESSAGE_SPAN_ID + "MOUSE_" + index);
	var boardObjWarning = _Window.$($ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "MOUSE_" + index);
	if(boardObjMessage){
		Element.hide(boardObjMessage);
	}
	if(boardObjWarning){
		Element.hide(boardObjWarning);
	}
};

ValidatorHelper = ValidationHelper;

/**
*\u5BF9\u4F20\u5165\u7684\u63A7\u4EF6ID/\u5BF9\u8C61\u5E8F\u5217\u8FDB\u884C\u6821\u9A8C
*\u5F53\u4F20\u5165\u4E00\u4E2A\u63A7\u4EF6ID/\u5BF9\u8C61\uFF0C\u5219\u8FD4\u56DE\u4E00\u4E2A\u5BF9\u8C61
*\u5426\u5219\uFF0C\u8FD4\u56DE\u4E00\u4E2A\u6570\u7EC4
*/
ValidationHelper.valid = function(){
	var arrRetVal = [];
	for(var i=0;i<arguments.length;i++){
		var element = arguments[i];
		element = $(element);
		//wenyh@2007-06-21 \u5982\u679C\u5143\u7D20\u6307\u5B9A\u4E86forceValid=true,\u5219\u603B\u662F\u6821\u9A8C
		if(element.getAttribute("forceValid") != "true" && (element.disabled || element.style.display == 'none')) continue;
		if(element.getAttribute("validation") == undefined) continue;
		var validatorIns = ValidationFactory.makeValidator(element);
		var isValid = validatorIns.execute();
		element.setAttribute("isValid", isValid);
		if(isValid){
			changeBorderStyle(element);			
		}else{
			changeBorderStyle(element, $ValidatorConfigs["WARNING_BORDER"]);
		}
		var validInfo = new Object();
		validInfo.getMessage = function(){
			return this.getMessage() || '';
		}.bind(validatorIns);
		validInfo.getWarning = function(){
			return this.warning || '';
		}.bind(validatorIns);
		validInfo.isValid = function(){
			return this.isValid;
		}.bind({isValid:isValid});
		//ge gfc add @ 2007-6-6 15:27 \u52A0\u5165id\u4FE1\u606F\uFF0C\u4EE5\u4FBF\u53EF\u4EE5\u901A\u8FC7\u8BE5\u6807\u8BC6\u627E\u5230\u5BF9\u5E94\u7684element
		validInfo['id'] = element.id || element.name;

		arrRetVal.push(validInfo);
	}
	return (arrRetVal.length==0)?null:(arrRetVal.length==1)?arrRetVal[0]:arrRetVal;
};

ValidationHelper.forceValidSet = function(_sValidationId, _bNotChangeStyle){
	var arrValidators = ValidationHelper.validateControls;
	for(var i=0;i<arrValidators.length;i++){
		ValidationHelper.forceValid(arrValidators[i], _bNotChangeStyle);
	}
};

ValidationHelper.validSet = function(_sValidationId){
	var arrValidators = ValidationHelper.validateControls;
	var arrRetVal = [];
	for(var i=0;i<arrValidators.length;i++){
		var element = arrValidators[i];
		if(element.getAttribute("validationId", 2)!=_sValidationId)continue;
		//wenyh@2007-06-21 \u5982\u679C\u5143\u7D20\u6307\u5B9A\u4E86forceValid=true,\u5219\u603B\u662F\u6821\u9A8C
		if(element.getAttribute("forceValid") != "true" && (element.disabled || element.style.display == 'none')) continue;
		if(element.getAttribute("validation") == undefined) continue;
		var validatorIns = ValidationFactory.makeValidator(element);
		var isValid = validatorIns.execute();
		element.setAttribute("isValid", isValid);
		if(isValid){
			changeBorderStyle(element);			
		}else{
			changeBorderStyle(element, $ValidatorConfigs["WARNING_BORDER"]);
		}
		var validInfo = new Object();
		validInfo.getMessage = function(){
			return this.getMessage() || '';
		}.bind(validatorIns);
		validInfo.getWarning = function(){
			return this.warning || '';
		}.bind(validatorIns);
		validInfo.isValid = function(){
			return this.isValid;
		}.bind({isValid:isValid});
		//ge gfc add @ 2007-6-6 15:27 \u52A0\u5165id\u4FE1\u606F\uFF0C\u4EE5\u4FBF\u53EF\u4EE5\u901A\u8FC7\u8BE5\u6807\u8BC6\u627E\u5230\u5BF9\u5E94\u7684element
		validInfo['id'] = element.id || element.name;
		arrRetVal.push(validInfo);
	}
	return arrRetVal;
};


ValidatorHelper.validAndDisplay = function(){
	var validInfo = ValidationHelper.valid.apply(ValidationHelper, arguments);
	if(!Array.isArray(validInfo)){
		validInfo = [validInfo];
	}
	var result = true;
	var warning = '';
	var firstInvalid = null;
	validInfo.each(function(element){
		if(!element.isValid()){
			result = false;
			warning += element.getWarning() + "<br>";
			if(firstInvalid == null) {
				firstInvalid = element;
			}
		}
	});
	if(!result){
		$alert(warning, function(){
			$dialog().hide();
			if(firstInvalid != null) {
				try{
					$(firstInvalid['id']).select();
					$(firstInvalid['id']).focus();					
				}catch(err){
					//alert(err.message);
					//just skip it
				}

			}
		});
	}
	return result;
};

ValidatorHelper.forceValid = function(element, _bNotChangeStyle){
	element = $(element);
	if(element.getAttribute("validation") == undefined) return;
	var validatorIns = element.getAttribute("_VALIDATORINS_");
	if(validatorIns == undefined){
		ValidationHelper.registerValidation(element);
	}
	ValidationHelper.changeEvent(element, _bNotChangeStyle);
};

/**
*@param		parentId \u8981\u6821\u9A8C\u63A7\u4EF6\u7684\u7236\u7EA7ID\u6216Dom Object
*
*@return	\u5982\u679C\u6240\u6709\u9700\u8981\u6821\u9A8C\u7684\u63A7\u4EF6\u6EE1\u8DB3\u6821\u9A8C\u6761\u4EF6\uFF0C\u8FD4\u56DEtrue;
*			\u5426\u5219\uFF0C\u8FD4\u56DEfalse
*/
ValidationHelper.doValid = function(parentId, _fDoAfterValidate){
	var parentControl = $(parentId);
	var inputArray = $A(parentControl.getElementsByTagName("INPUT"));
	var textAreaArray = $A(parentControl.getElementsByTagName("TEXTAREA"));
	var selectArray = $A(parentControl.getElementsByTagName("SELECT"));
	var warning = "";
	var flag = false;
	var allControls = inputArray.concat(textAreaArray, selectArray);
	var firstInValidControl = null;
	for (var i = 0; i < allControls.length; i++){
		var validInfo = ValidationHelper.valid(allControls[i]);
		if(!validInfo)continue;
		if(!validInfo.isValid()){
			if(flag == false) firstInValidControl = allControls[i];
			flag = true;
			warning += validInfo.getWarning() + "<br>";			
		}
	}
	if(flag){
		if(_fDoAfterValidate && typeof(_fDoAfterValidate) == 'function') {
			_fDoAfterValidate(warning, firstInValidControl);
			return;
		}
		$alert(warning, function(){
			$dialog().hide();
			firstInValidControl.focus();
			if(firstInValidControl.select){//wenyh@2007-02-26 select\u5143\u7D20\u4F3C\u4E4E\u6CA1\u6709select\u65B9\u6CD5,\u6545\u5224\u65AD\u4E00\u4E0B
				firstInValidControl.select();
			}
			return false;
		});
	}
	return !flag;
};

//Validation\u7EC4\u4EF6\u521D\u59CB\u5316
ValidationHelper.validateControls = [];
ValidationHelper.initValidation = function(){
	var inputArray = $A(document.getElementsByTagName("INPUT"));
	var textAreaArray = $A(document.getElementsByTagName("TEXTAREA"));
	var selectArray = $A(document.getElementsByTagName("SELECT"));

	inputArray.concat(textAreaArray, selectArray).each(function(element){
		if(element.disabled || element.style.display == 'none')
			throw $continue;
		if(element.tagName.toLowerCase() == "input" && element.getAttribute('type').toLowerCase() == "hidden")
			throw $continue;
		ValidationHelper.registerValidation(element);		
	});
	ValidationHelper.doSubmitAll();
};

//\u5BF9\u5355\u4E2A\u63A7\u4EF6\u6CE8\u518CValidation
ValidationHelper.registerValidation = function(element){
	element = $(element);
	if(element.getAttribute("validation") == undefined) return;
	if(ValidationHelper.validateControls.include(element)) return;
	var index = ValidationHelper.validateControls.length;
	element.setAttribute("_VALID_INDEX_", index);
	ValidationHelper.validateControls.push(element);
	var validatorIns = ValidationFactory.makeValidator(element);	

	if($ValidatorConfigs.getRequiredHint()){
		ValidationHelper.makeRequiredHint(element);	
	}
	ValidationHelper.initIsValid(element);

	element.bindMethod = {};
	element.bindMethod.keyUpEvent = ValidationHelper.keyUpEvent.bind(ValidationHelper, element);
	element.bindMethod.keyDownEvent = ValidationHelper.keyDownEvent.bind(ValidationHelper, element);
	//element.bindMethod.changeEvent = ValidationHelper.changeEvent.bind(ValidationHelper, element);
	if(element.tagName == 'INPUT' || element.tagName == 'TEXTAREA' || element.tagName == 'SELECT'){
		Event.observe(element, 'keydown', element.bindMethod.keyDownEvent, false); 
		Event.observe(element, 'keyup', element.bindMethod.keyUpEvent, false); 
	}
	else{
		//FIXME \u9700\u8981\u5728\u6539\u53D8innerHTML\u65F6\u4F5C\u8F83\u9A8C
		element.onpropertychange = function(event){
			event = window.event || event;
			if(event && event.propertyName=='innerHTML'){
				ValidationHelper.changeEvent(element);
			}
		}
	}
	//Event.observe(element, 'change', element.bindMethod.changeEvent, false); 

	if($ValidatorConfigs.getShowAllMode()){
		ValidationHelper.showAllTime(element);
	}else if($ValidatorConfigs.getFocusMode()){
		element.bindMethod.blurEvent = ValidationHelper.blurEvent.bind(ValidationHelper, element);	
		Event.observe(element, 'blur', element.bindMethod.blurEvent, false); 
		if(element.tagName.toUpperCase() == "SELECT"){
			element.bindMethod.changeEvent = ValidationHelper.changeEvent.bind(ValidationHelper, element);		
			Event.observe(element, 'change', element.bindMethod.changeEvent, false); 
		}else{
			element.bindMethod.focusEvent = ValidationHelper.focusEvent.bind(ValidationHelper, element);				
			Event.observe(element, 'focus', element.bindMethod.focusEvent, false); 
		}
	}
	if($ValidatorConfigs.getMouseMode()){
		if(element.tagName.toUpperCase() == "SELECT"){
			element.bindMethod.changeEvent = ValidationHelper.changeEvent.bind(ValidationHelper, element);		
			Event.observe(element, 'change', element.bindMethod.changeEvent, false); 
		}
		element.bindMethod.mouseOverEvent = ValidationHelper.mouseOverEvent.bind(ValidationHelper, element, event);
		element.bindMethod.mouseOutEvent = ValidationHelper.mouseOutEvent.bind(ValidationHelper, element, event);
		Event.observe(element, 'mouseover', element.bindMethod.mouseOverEvent, false); 
		Event.observe(element, 'mouseout', element.bindMethod.mouseOutEvent, false); 
	}
	return true;
};

/*
 *\u5C06\u67D0\u4E9B\u5143\u7D20\u6DFB\u52A0\u5230\u6821\u9A8C\u6570\u7EC4\u4E2D
 *\u53C2\u6570\uFF1A\u4F20\u5165\u5355\u4E2A\u5143\u7D20\u6216\u591A\u4E2A\u5143\u7D20
 */
ValidationHelper.pushElements = function(){
	var elementArray = $.apply($, arguments);
	if(elementArray.constructor != Array) elementArray = [elementArray];

	for (var i = 0; i < elementArray.length; i++){
		element = elementArray[i];
		var registerStatus = ValidationHelper.registerValidation(element);
		if(registerStatus && !element.getAttribute("isValid")){
			ValidationHelper.doSubmit(element);
		}
	}
};

/*
 *\u5C06\u67D0\u4E9B\u5143\u7D20\u4ECE\u6821\u9A8C\u6570\u7EC4\u4E2D\u5220\u9664
 *\u53C2\u6570\uFF1A\u4F20\u5165\u5355\u4E2A\u5143\u7D20\u6216\u591A\u4E2A\u5143\u7D20
 */
ValidationHelper.popElements = function(){
	var elementArray = $.apply($, arguments);
	if(elementArray.constructor != Array) elementArray = [elementArray];

	for (var i = 0, length = ValidationHelper.validateControls.length; i < length; i++){
		var element = ValidationHelper.validateControls[i];
		if(elementArray.include(element)){
			ValidationHelper.validateControls[i] = null;
			var index = element.getAttribute("_VALID_INDEX_");	

			//\u79FB\u9664dom\u8282\u70B9\u4FE1\u606F
			var removeDomArray = [];
			removeDomArray.push($($ValidatorConfigs.PREFIX_MESSAGE_SPAN_ID + "KEY_" + index));
			removeDomArray.push($($ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "KEY_" + index));
			removeDomArray.push($($ValidatorConfigs.PREFIX_MESSAGE_SPAN_ID + "MOUSE_" + index));
			removeDomArray.push($($ValidatorConfigs.PREFIX_WARNING_SPAN_ID + "MOUSE_" + index));
			removeDomArray.push($($ValidatorConfigs.PREFIX_HINT_SPAN_ID + index));
			for (var i = 0; i < removeDomArray.length; i++){
				if(removeDomArray[i]){
					Element.remove(removeDomArray[i]);
					removeDomArray[i] = null;
				}
			}

			//\u79FB\u9664\u6CE8\u518C\u7684\u4E8B\u4EF6
			for(var tempEvent in element.bindMethod){				
				Event.stopObserving(element, tempEvent.replace("Event", '').toLowerCase(), element.bindMethod[tempEvent], false);
				delete element.bindMethod[tempEvent];
			}
			element.bindMethod = null;
			element.removeAttribute("bindMethod");
			element._VALIDATORINS_ = null;
			element.removeAttribute("_VALIDATORINS_");
			element._VALIDATEOBJ_ = null;
			element.removeAttribute("_VALIDATEOBJ_", null);

			if(element.getAttribute("isValid") == false){
				ValidationHelper.doSubmit(element);
			}	
		}
	}
};

ValidationHelper.notify = function(){
	var elementArray = $.apply($, arguments);
	if(elementArray.constructor != Array) elementArray = [elementArray];
	for (var i = 0; i < elementArray.length; i++){
		var element = elementArray[i];
		if(element.disabled || element.style.display == 'none'){
			ValidationHelper.popElements(element);
		}else{				
			ValidationHelper.pushElements(element);
		}
	}
};

Event.observe(window, 'unload', function(){
	for (var i = 0; i < ValidationHelper.validateControls.length; i++){
		var element = ValidationHelper.validateControls[i];
		if(element == null || !element.bindMethod)continue;
		for (prop in element.bindMethod){
			delete element.bindMethod[prop];
		}
		element.bindMethod = null;
		element.removeAttribute("bindMethod");
		delete element._VALIDATORINS_.field;
		element._VALIDATORINS_ = null;
		element.removeAttribute("_VALIDATORINS_");
		element._VALIDATEOBJ_ = null;
		element.removeAttribute("_VALIDATEOBJ_", null);
	}
});

//\u6539\u53D8\u8F93\u5165\u6846\u7684\u6837\u5F0F\u3002\u672A\u6307\u5B9AnewBorder\u65F6\uFF0C\u5219\u4FEE\u6539\u4E3A\u539F\u6837\u5F0F
function changeBorderStyle(element, newBorder){
	if(element.getAttribute("borderNoChanged") == "true") return;
	if(element.getAttribute("_oldBorderStyle_") === null){
		var oldBorderWidth = Element.getStyle(element, "borderWidth") || '';
		var oldBorderStyle = Element.getStyle(element, "borderStyle") || '';
		var oldBorderColor = Element.getStyle(element, "borderColor") || '';
		element.setAttribute("_oldBorderWidth_", oldBorderWidth);
		element.setAttribute("_oldBorderStyle_", oldBorderStyle);
		element.setAttribute("_oldBorderColor_", oldBorderColor);
	}
	if(newBorder){
		//element.style.width = element.offsetWidth;
		BorderHelper.reserveBorder(element);
		element.style.border = newBorder;
		element._locked = true;
	}else{
		element._locked = false;
		if(element.tagName!='TEXTAREA' && element.getAttribute("_oldBorderStyle_") == 'none'){
			element.style.borderWidth = '';
			element.style.borderStyle = 'none';
			element.style.borderColor = '';
		}else{
			var borderWidth = element.getAttribute("_oldBorderWidth_");
			if(borderWidth.startsWith("0")){
				//element.style.borderWidth = '';
				element.style.borderWidth = borderWidth;
			}else{
				element.style.borderWidth = borderWidth;
			}
			var borderColor = element.getAttribute("_oldBorderColor_");
			var borderStyle = element.getAttribute("_oldBorderStyle_");
			if(borderColor=="#000000" && borderStyle.toLowerCase()=="inset"){
				element.style.borderColor = "#ffffff";
			}else{
				element.style.borderColor = element.getAttribute("_oldBorderColor_");
			}
			element.style.borderStyle = borderStyle;
		}		
	}
}

//Event.observe(window, 'load', ValidationHelper.initValidation, false);