function Validator(errorHandle){
	this.errorHandle = errorHandle;	
}

Validator.prototype = {
		contructor : Validator,
		rules : {},
		addRules : function(ruleName, validFunction, errorFunction){
			this.rules[ruleName] = {
					validFunction : validFunction,
					errorFunction : errorFunction
			};
		},
		eventFunction : function(item){
			var self = this;
			$(item).die().live("blur", function(){
				self.validateItem(item);	
			});
		},
		bindingEvent : function(divId){
			var self = this;

			$("#" + divId).find("input").each(function(i, item){
				self.eventFunction(item);		
			});
			
			$("#" + divId).find("textarea").each(function(i, item){
				self.eventFunction(item);

			});
			
		},
		validateDiv : function(divId){
			var dtdList = [],
				self = this;
				
			//for( var r in this.rules){
				$("#" + divId).find("input").each(function(i, item){
					dtdList.push( self.validateItem(item) );
				});
				
				$("#" + divId).find("textarea").each(function(i, item){
					dtdList.push( self.validateItem(item) );
				});
				
			//}
				
				if ($("#" + divId).find("input").length == 0){
					var deferred = $.Deferred();
					deferred.resolve();
					dtdList.push(deferred);
				}
				
				if ($("#" + divId).find("textarea").length == 0){
					var deferred = $.Deferred();
					deferred.resolve();
					dtdList.push(deferred);
				}

			
			return $.when.apply(null, dtdList).fail(function(){
				if(self.errorHandle) {
					self.errorHandle.call(null, divId);					
				}
			});
			
			
			
		},
		validateItem : function(d){
			var self = this;
			var roleList = [];
			for(var r in this.rules){	
				if( $(d).is("[" + r + "]") ){
					roleList.push(r);
				}
			}
			var dtd = $.Deferred();
			var checked = function(){	
				if ( roleList.length >= 1 ){
					var ok = self.validate(d, roleList[0]);
					ok.done(function(){
						if(roleList.length >= 2){
							self.validate(d, roleList[1]);
						}
						roleList.shift();
						checked();
					}).fail(function(){
						dtd.reject();
					});
				} else {
					dtd.resolve();
				} ;
				//dtd.resolve();
				//return dtd;
			};
			checked();
			return dtd;
			
		},
		validate : function(d, rule){
			var value = $(d).val(),
		    	attributeValue = $(d).attr(rule),
	            f = this.rules[rule].validFunction,
	            self = this;
	        
	    
			var ok = f.call(null, d, value, attributeValue);

			
			return ok.fail(function(item){
				if($(item).siblings("[validationError]").length != 0 ){
			    	$(item).siblings("[validationError]").remove();					    	
			    }
				if(self.rules[rule].errorFunction){
					self.rules[rule].errorFunction(d, rule);
				}else {
					self.showErrorMessage(d, rule);					
				}
			}).done(function(item){
				if($(item).siblings("[validationError]").length != 0 ){
			    	$(item).siblings("[validationError]").remove();					    	
			    }
			});
		},
		showErrorMessage : function(item,rule){
			if($(item).siblings("div").find("[msgid='msg"+rule+"']").length == 0){
				var message = lang.messages["msg"+rule] || "Error Message";
				$(item).parent().append("<div validationError><label msgid='msg"+rule+"'>" + message + "</label></div>");				
			}
		}
};

//add default rule
Validator.prototype.addRules("required", function(d, value, attributeValue){
	var dtd = $.Deferred();
	var ok = !($.trim(value) == "" || value == null);
	if(ok){
		dtd.resolve(d);
	} else {
		dtd.reject(d);
	}
	return dtd.promise();
});

Validator.prototype.addRules("chineseLeng", function(d, value, attributeValue){
	var dtd = $.Deferred();
	var ok = (value.length <= attributeValue);
	if(ok){
		dtd.resolve(d);
	} else {
		dtd.reject(d, attributeValue);
	}
	return dtd.promise();
	
}, function(d, rule){
	if($(d).siblings("div").find("[msgid='msg"+rule+"']").length == 0){
		var message = lang.messages["msg"+rule] || "Error Message";
		var attributeValue = $(d).attr(rule);
		message = message.replace("{0}", attributeValue);
		$(d).parent().append("<div validationError><label msgid='msg"+rule+"'>" + message + "</label></div>");				
	}
});

Validator.prototype.addRules("maxLeng", function(d, value, attributeValue){
	var dtd = $.Deferred();
	var ok = (value.length <= attributeValue);
	if(ok){
		dtd.resolve(d);
	} else {
		dtd.reject(d, attributeValue);
	}
	return dtd.promise();
	
}, function(d, rule){
	if($(d).siblings("div").find("[msgid='msg"+rule+"']").length == 0){
		var message = lang.messages["msg"+rule] || "Error Message";
		var attributeValue = $(d).attr(rule);
		message = message.replace("{0}", attributeValue);
		$(d).parent().append("<div validationError><label msgid='msg"+rule+"'  errorMsgParam='"+attributeValue+"'>" + message + "</label></div>");				
	}
});

Validator.prototype.addRules("url", function(d, value, attributeValue){
	var dtd = $.Deferred(),
		ok = /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
	
	if(ok){
		dtd.resolve(d);
	} else {
		dtd.reject(d);
	}
	return dtd.promise();
});

Validator.prototype.addRules("requiredField", function(d, value, attributeValue){
	var dtd = $.Deferred();
	var ok = !($.trim(value) == "" || value == null);
	if(ok){
		dtd.resolve(d);
	} else {
		dtd.reject(d);
	}	
	return dtd;
},function(d, rule){
	if($(d).siblings("[msgid='msg"+"required"+"']").length == 0){
		var message = lang.messages["msg"+"required"] || "Error Message";
		$(d).parent().append("<label msgid='msg"+"required"+"' validationError>" + message + "</label>");				
	}
});

Validator.prototype.addRules("uniqueBpKey", function(d, value, attributeValue){
	var dtd = $.Deferred();
	if(value == null || $.trim(value) == "") {
		dtd.reject(d);
		return dtd;
	}
	var url = null;
	if($(d).siblings("input[type='hidden']").length != 0){
		url = app.EPRESTAPI_CONTEXT_ROOT + "clientSetup/unique/bpKey/"+value + "/" + $(d).siblings("input[type='hidden']").val();
	} else {
		url = app.EPRESTAPI_CONTEXT_ROOT + "clientSetup/unique/bpKey/"+value + "/-1";
	}
	
	ajaxCall({
		url : url,
		type : "GET",
		dataType : "JSON"			
	}).done(function(data){
		if(data.data.data) {
			dtd.resolve(d);
		} else {
			dtd.reject(d);
		}
	});
	
	return dtd;
},function(d, rule){
	if($(d).siblings("[msgid='msg"+rule+"']").length == 0){
		var message = lang.messages["msg"+rule] || "Error Message";
		$(d).parent().append("<label msgid='msg"+rule+"' validationError>" + message + "</label>");				
	}
});

Validator.prototype.addRules("BpKey", function(d, value, attributeValue){
	var dtd = $.Deferred();
	if(value == null || $.trim(value) == "") {
		dtd.reject(d);
		return dtd;
	}
	var url = null;
	if($(d).siblings("input[type='hidden']").length != 0){
		url = app.EPRESTAPI_CONTEXT_ROOT + "clientSetup/validate/bpKey/"+value + "/" + $(d).siblings("input[type='hidden']").val();
	} else {
		url = app.EPRESTAPI_CONTEXT_ROOT + "clientSetup/validate/bpKey/"+value + "/-1";
	}
	
	ajaxCall({
		url : url,
		type : "GET",
		dataType : "JSON"			
	}).done(function(data){
		if(data.data.data) {
			dtd.resolve(d);
		} else {
			dtd.reject(d);
		}
	});
	
	return dtd;
}, function(d, rule){
	if($(d).siblings("[msgid='msg"+rule+"']").length == 0){
		var message = lang.messages["msg"+rule] || "Error Message";
		$(d).parent().append("<label msgid='msg"+rule+"' validationError>" + message + "</label>");				
	}
});


Validator.prototype.addRules("UserId", function(d, value, attributeValue){
	var dtd = $.Deferred();
	if(value == null || $.trim(value) == "") {
		dtd.reject(d);
		return dtd;
	}	
	
	var url = null;
	if($(d).siblings("input[type='hidden']").length != 0){
		url = app.EPRESTAPI_CONTEXT_ROOT + "clientSetup/validate/userId/"+value + "/" + $(d).siblings("input[type='hidden']").val();
	} else {
		url = app.EPRESTAPI_CONTEXT_ROOT + "clientSetup/validate/userId/"+value + "/-1";
	}
	
	ajaxCall({
		url : url,
		type : "GET",
		dataType : "JSON"			
	}).done(function(data){
		if(data.data.data) {
			dtd.resolve(d);
		} else {
			dtd.reject(d);
		}
	});
	
	return dtd;
}, function(d, rule){
	if($(d).siblings("[msgid='msg"+rule+"']").length == 0){
		var message = lang.messages["msg"+rule] || "Error Message";		
		$(d).parent().append("<label msgid='msg"+rule+"' validationError>" + message + "</label>");				
	}
});

Validator.prototype.addRules("NotAllowed", function(d, value, attributeValue){
	var dtd = $.Deferred();
	if(attributeValue == "false") {
		dtd.resolve(d);
		return dtd;
	}
	var notAllowedValue = [lang.getMessage('managerLinkMarketInsightsEn'), lang.getMessage('managerLinkMarketInsightsSc'), lang.getMessage('managerLinkMarketInsightsTc')];
	for (var i = 0; i < notAllowedValue.length; i++){
		if( value == notAllowedValue[i] || /^\s*Market\s*Insights\s*$/i.test(value) ) {
			dtd.reject(d);
			return dtd;
		}
	}
	
	dtd.resolve(d);
	return dtd;
});

function checkEnglistContent(value){   
    //rule expression ie don't support multiple line,so......
    var lineArray = value.split("\n");
    var flag = true;
    for (var i= 0;i<lineArray.length;i++){
        if ($.trim(lineArray[i]).length == 0){
            continue;
        }
        var re = /^[a-zA-Z0-9\`\~\!\@\#\$\%\^\&\*\(\)\_\+\-\=\[\]\\\{\}\|\;\'\:\"\,\.\/\<\>\?\ ]+$/gm ;
        flag = re.test(lineArray[i]);
        if (!flag){
            break;
        }
    }
    return flag ;   
};





