var Page_IsValid = true;
var Page_BlockSubmit = false;
var Date_CutOffYear = 29; // Years formatted as YY are considered 20th century above this value

function ValidatorUpdateDisplay(val) {
	if (val.wordCount) {
		val.validator.innerHTML = val.onblurerrormessage.replace(/WORDCOUNT/, val.wordCount);
	}
	val.validator.style.display = val.isvalid ? "none" : "inline";
}

function ValidatorUpdateIsValid() {
	for (var i = Page_Validators.length - 1; i >= 0; --i) {
		if (!Page_Validators[i].isvalid) {
			Page_IsValid = false;
			return;
		}
	}
	Page_IsValid = true;
}

function ValidatorHookupControl(control, val) {
	if(typeof(control.Validators) == "undefined") {
		control.Validators = new Array;
		addEvent(control, "change", ValidatorOnChange);
	}
	control.Validators[control.Validators.length] = val;
}

function ValidatorGetValue(control) {
	return control.value;
}

function Page_ClientValidate() {
	for (var i = Page_Validators.length - 1; i >= 0; --i) {
		ValidatorValidate(Page_Validators[i]);
	}
	ValidatorUpdateIsValid();
	ValidationSummaryOnSubmit();
	Page_BlockSubmit = !Page_IsValid;
	return Page_IsValid;
}

function ValidatorCommonOnSubmit() {
	var result = !Page_BlockSubmit;
	Page_BlockSubmit = false;
   return result;
}

function ValidatorOnChange(e) {
	if (!e) {
		var e = window.event;
	}
	var tg = (window.event) ? e.srcElement : e.target;
	var vals = tg.Validators;
	for (var i = vals.length - 1; i >= 0; --i) {
		ValidatorValidate(vals[i]);
	}
	ValidatorUpdateIsValid();
}

function ValidatorValidate(val) {    
	val.isvalid = true;
	if (typeof(val.evaluationfunction) == "function") {
		val.isvalid = val.evaluationfunction(val); 
	}
	ValidatorUpdateDisplay(val);
}

function ValidatorOnLoad() {
	if (typeof(Page_Validators) == "undefined")
		return;
	var val;
	for (var i = Page_Validators.length - 1; i >= 0; --i) {
		val = Page_Validators[i];
		ValidatorHookupControl(val.controltovalidate, val);
	}
}

function ValidatorConvert(op, dataType, val) {
	function GetFullYear(year) {
		return (year + 2000) - ((year < Date_CutOffYear) ? 0 : 100);
	}
	var num, m, exp;
	if (dataType == "Integer") {
		exp = /^\s*[-\+]?\d+\s*$/;
		if(op.match(exp) == null) 
			return null;
		num = parseInt(op);
		return (isNaN(num) ? null : num);
	}
	else if (dataType == "Date") {
		exp = /^\s*(?:(?:(\d{1,2})(?:[-\/]|\. ?))?(\d{1,2})(?:[-\/]|\. ?))?(\d{4}|\d{2})\s*$/;
		m = op.match(exp);
		var day, month, year;
		if (m == null)
			return null;
		/* Check for m[1] being null (FF) or empty (IE) */
		if (m[1] == null || m[1] == "") {
			if (val.includedateunderstanding.split(",").inArray("my") || val.includedateunderstanding.split(",").inArray("y")) {
				day = 1;
			} else {
				return null;
			}
		} else {
			day = m[1];
		}
		/* Check for m[2] being null (FF) or empty (IE) */
		if (m[2] == null || m[2] == "") {
			if (val.includedateunderstanding.split(",").inArray("y")) {
				month = 0;
			} else {
				return null;
			}
		} else {
			month = m[2] - 1;
		}
		year = (m[3].length == 4) ? m[3] : GetFullYear(parseInt(m[3]));
		var date = new Date(year, month, day);
		return (typeof(date) == "object" && year == date.getFullYear() && month == date.getMonth() && day == date.getDate()) ? date.valueOf() : null;
	}
	else if (dataType == "Time") {
		exp =/^\s*(\d{1,2})(:|\.)(\d{2})(\2(\d{2}))?\s*$/;
		m = op.match(exp);
		if (m == null)
			return null;
		var hour = m[1];
		var minute = m[3];
		var second = (m[5] != null) ? m[5] : 0;
		return (hour < 24 && minute < 60 && second < 60) ? true : null;
	}
	else {
		return op.toString();
	}
}

function ValidatorCompare(operand1, operand2, operator, val) {
	var dataType = val.type;
	var op1, op2;
	if ((op1 = ValidatorConvert(operand1, dataType, val)) == null)
		return false;    
	if (operator == "DataTypeCheck")
		return true;
	if ((op2 = ValidatorConvert(operand2, dataType, val)) == null)
		return true;
	switch (operator) {
		case "NotEqual":
			return (op1 != op2);
		case "GreaterThan":
			return (op1 > op2);
		case "GreaterThanEqual":
			return (op1 >= op2);
		case "LessThan":
			return (op1 < op2);
		case "LessThanEqual":
			return (op1 <= op2);
		default:
			return (op1 == op2);
	}
}

function CompareValidatorEvaluateIsValid(val) {
	var value = ValidatorGetValue(val.controltovalidate);
	if (ValidatorTrim(value).length == 0)
		return true;
	var compareTo = "";
  if (val.controltocompare) {
      compareTo = ValidatorGetValue(val.controltocompare);
  }
	return ValidatorCompare(value, compareTo, val.operator, val);
}

function RegularExpressionValidatorEvaluateIsValid(val) {
	var value = ValidatorGetValue(val.controltovalidate);
	if (ValidatorTrim(value).length == 0)
			return true;
	var rx = new RegExp(val.validationexpression, val.modifiers);
	var matches = rx.exec(value);
	return (matches != null && value == matches[0]);
}

function WordCountValidatorEvaluateIsValid(val) {
	var value = ValidatorGetValue(val.controltovalidate);
	if (ValidatorTrim(value).length == 0)
			return true;

	var wordCount = ValidatorTrim(value).replace(/\s+/g," ").split(" ").length;
	val.wordCount = wordCount;
	return wordCount <= parseInt(val.maxwords);
}

function ValidatorTrim(s) {
	var m = s.match(/^\s*(\S+(\s+\S+)*)\s*$/);
	return (m == null) ? "" : m[1];
}

function RequiredFieldValidatorEvaluateIsValid(val) {
	return (ValidatorTrim(ValidatorGetValue(val.controltovalidate)) != ValidatorTrim(val.initialvalue))
}

function RangeValidatorEvaluateIsValid(val) {
	var value = ValidatorGetValue(val.controltovalidate);
	if (ValidatorTrim(value).length == 0) 
		return true;
	return (ValidatorCompare(value, val.minimumvalue, "GreaterThanEqual", val) && ValidatorCompare(value, val.maximumvalue, "LessThanEqual", val));
}

function ValidationSummaryOnSubmit() {
	var s = "";
	if (!Page_IsValid) {
		var valLength = Page_Validators.length;
		for (var i = 0; i < valLength; ++i) {
			if (!Page_Validators[i].isvalid && typeof(Page_Validators[i].errormessage) == "string") {
				s += "- " + Page_Validators[i].errormessage + (Page_Validators[i].wordCount ? " (you have used " + Page_Validators[i].wordCount + " words)\n" : "\n");
			}
		}
		alert(s);
	}
}