var Page_ValidationVer = "125";
var Page_IsValid = true;
var Page_BlockSubmit = false;
var TextAreaBlocker = false;


// "[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*"
// regular expression for code names, as above !!!!

//  ------------------------------------------------------------------------ //
// function:	 markAllRows(container_id, val)
// what it does: marks all the checkboxes in a container with val (true or false)
//  ------------------------------------------------------------------------ //


function markAllRows(container_id, val)
{
	var rows = document.getElementById(container_id).getElementsByTagName('tr');
	var unique_id;
	var checkbox;

// scan items ('tr', which contains the checkboxes)
	for (var i = 0; i < rows.length; i++) {
		checkbox = rows[i].getElementsByTagName('input')[0];
		if (checkbox && checkbox.type == 'checkbox') {
			if (checkbox.disabled == false) {
				checkbox.checked = val;
			}
		}
	}
	return(true);
}

//  ------------------------------------------------------------------------ //
// function:	 checkOneRowMarked(container_id)
// what it does: check if at least one row into a container is checked
//  ------------------------------------------------------------------------ //


function checkOneRowMarked(container_id)
{
	var rows = document.getElementById(container_id).getElementsByTagName('tr');
	var unique_id;
	var checkbox;

// scan items ('tr', which contains the checkboxes)
	for (var i = 0; i < rows.length; i++) {
		checkbox = rows[i].getElementsByTagName('input')[0];
		if (checkbox && checkbox.type == 'checkbox') {
			if (checkbox.disabled == false) {
				if (checkbox.checked) {
					return(true);
				}
			}
		}
	}
	return(false);		// arrive here then... nothing checked
}

//  ------------------------------------------------------------------------ //
// function:	 Page_ResetDisplay()
// what it does: reset a view after an error (can be called directly)
//  ------------------------------------------------------------------------ //
function Page_ResetDisplay()
{
	var	i;

// scan validators, reset variables and refresh display
	for (i = 0; i < Page_Validators.length; i++) {
		Page_Validators[i].isvalid = true;
		ValidatorUpdateDisplay(Page_Validators[i]);
	}
}

//  ------------------------------------------------------------------------ //
// function:	 ValidatorUpdateDisplay(val)
// what it does: refresh the appropriate span section (inner function)
//  ------------------------------------------------------------------------ //
function ValidatorUpdateDisplay(val)
{
// check all types of validators
	if (typeof(val.getAttribute("display")) == "string") {    
		if (val.getAttribute("display") == "None") {
			return;
		}
		if (val.getAttribute("display") == "Dynamic") {
			val.style.display = val.isvalid ? "none" : "inline";
			return;
		}
	}
	val.style.visibility = "hidden";
	val.style.visibility = val.isvalid ? "hidden" : "visible";
}

//  ------------------------------------------------------------------------ //
// function:	 ValidatorUpdateIsValid()
// what it does: check whether there is a value that is NOT valid
//  ------------------------------------------------------------------------ //
function ValidatorUpdateIsValid()
{
	var	i;

// scan validators
	for (i = 0; i < Page_Validators.length; i++) {
		if (!Page_Validators[i].isvalid) {
			Page_IsValid = false;
			return;
		}
	}
	Page_IsValid = true;
}

//  ------------------------------------------------------------------------ //
// function:	 ValidatorHookupControlID(controlID, val)
// what it does: hook up some functions to the events of the objects
//  ------------------------------------------------------------------------ //
function ValidatorHookupControlID(controlID, val)
{
// some checks
	if (typeof(controlID) != "string") {
		return;
	}

// assign the control
	var	ctrl = document.forms[Ui_Form_id].elements[controlID];
	if (typeof(ctrl) != "undefined") {
		ValidatorHookupControl(ctrl, val);
	} else {
		val.isvalid = true;
		val.enabled = false;
	}
}

//  ------------------------------------------------------------------------ //
// function:	 ValidatorHookupControl(control, val)
// what it does: hook up... continue
//  ------------------------------------------------------------------------ //
function ValidatorHookupControl(control, val)
{
       	var	i;

// some controls
	if (typeof(control.tagName) == "undefined" && typeof(control.length) == "number") {
	        for (i = 0; i < control.length; i++) {
			var inner = control[i];
            		if (typeof(inner.value) == "string") {
                		ValidatorHookupControl(inner, val);
			} 
		}
        	return;
    	} else if (control.tagName != "INPUT" && control.tagName != "TEXTAREA" && control.tagName != "SELECT") {
	        for (i = 0; i < control.children.length; i++) {
        		ValidatorHookupControl(control.children[i], val);
        	}
        	return;
    	} else {
		if (typeof(control.Validators) == "undefined") {
			control.Validators = new Array;
			var	ev;
			if (control.type == "radio") {
				ev = control.onclick;
            		} else {
				ev = control.onchange;
            		}
            		if (typeof(ev) == "function" ) {            
				ev = ev.toString();
				ev = ev.substring(ev.indexOf("{") + 1, ev.lastIndexOf("}"));
			} else {
                		ev = "";
			}
            		var	func = new Function("ValidatorOnChange('" + control.id + "'); " + ev);
			if (control.type == "radio") {
				control.onclick = func;
			} else {
				control.onchange = func;
			}
		}
		control.Validators[control.Validators.length] = val;
	}
}

//  ------------------------------------------------------------------------ //
// function:	 ValidatorSetValue(id, value)
// what it does: set a value due to some verified conditions in the script
//  ------------------------------------------------------------------------ //
function ValidatorSetValue(id, value)
{
	var	control;

// assign control and do some checks
	control = document.forms[Ui_Form_id].elements[id];
	if ((typeof(control.value) == "string") && (control.type != "radio")) {
		control.value = value;
	}
}

//  ------------------------------------------------------------------------ //
// function:	 ValidatorGetValue(id)
// what it does: get the compare value in the correct form according to the tag
//  ------------------------------------------------------------------------ //
function ValidatorGetValue(id)
{
	var	control;

// assign control and do some checks
	control = document.forms[Ui_Form_id].elements[id];
	if ((typeof(control.value) == "string") && (control.type != "radio")) {
		return control.value;
	}
	if (typeof(control.tagName) == "undefined" && typeof(control.length) == "number") {
		var	j;
		for (j = 0; j < control.length; j++) {
			var	inner = control[j];
			if (typeof(inner.value) == "string" && (inner.type != "radio" || inner.checked == true)) {
				return inner.value;
			}
		}
	} else {
		return ValidatorGetValueRecursive(control);
	}
	return "";
}

//  ------------------------------------------------------------------------ //
// function:	 ValidatorGetValueRecursive(control)
// what it does: like the above, but check for children
//  ------------------------------------------------------------------------ //
function ValidatorGetValueRecursive(control)
{
// check what type of control
	if (typeof(control.value) == "string" && (control.type != "radio" || control.status == true)) {
		return control.value;
	}
	var	i, val;
	for (i = 0; i<control.children.length; i++) {
		val = ValidatorGetValueRecursive(control.children[i]);
		if (val != "") {
			return val;
		}
	}
	return "";
}

//  ------------------------------------------------------------------------ //
// function:	 Page_ClientValidate()
// what it does: the event for our pushbuttons !
//  ------------------------------------------------------------------------ //
function Page_ClientValidate()
{
	var	i;

// scan validators in search of errors
	for (i = 0; i < Page_Validators.length; i++) {
		ValidatorValidate(Page_Validators[i]);
	}
	ValidatorUpdateIsValid();    
	ValidationSummaryOnSubmit();
	Page_BlockSubmit = !Page_IsValid;
	return Page_IsValid;
}

//  ------------------------------------------------------------------------ //
// function:	 ValidatorCommonOnSubmit()
// what it does: common onsubmit event
//  ------------------------------------------------------------------------ //
function ValidatorCommonOnSubmit()
{
	var result = !Page_BlockSubmit;

// assign some variables and return the permission tu submit
	Page_BlockSubmit = false;
//	event.returnValue = result;
	return result;
}

//  ------------------------------------------------------------------------ //
// function:	 ValidatorEnable(val, enable)
// what it does: switch on/off validity of each field
//  ------------------------------------------------------------------------ //
function ValidatorEnable(val, enable)
{
	val.enabled = (enable != false);
	ValidatorValidate(val);
	ValidatorUpdateIsValid();
}

//  ------------------------------------------------------------------------ //
// function:	 ValidatorOnChange(id)
// what it does: common onchange event
//  ------------------------------------------------------------------------ //
function ValidatorOnChange(id)
{
	var	el = document.getElementById(id);
	var	vals = el.Validators;
	var	i;

// scan validators for this event
	for (i = 0; i < vals.length; i++) {
		ValidatorValidate(vals[i]);
	}
	ValidatorUpdateIsValid();
}

//  ------------------------------------------------------------------------ //
// function:	 ValidatorValidate(val)
// what it does: core function to check a validator
//  ------------------------------------------------------------------------ //
function ValidatorValidate(val)
{
// set valid by default
	val.isvalid = true;

	if (val.enabled != false) {
		if (typeof(val.evaluationfunction) == "function") {
			val.isvalid = val.evaluationfunction(val);
		}
	}
	ValidatorUpdateDisplay(val);
}

//  ------------------------------------------------------------------------ //
// function:	 ValidatorOnLoad()
// what it does: "onload" event to preset the system for user interface
//  ------------------------------------------------------------------------ //
function ValidatorOnLoad()
{
// check if validators has been defined, then scan and "hook" them
	if (typeof(Page_Validators) == "undefined") {
		return;
	}


// yes, so scan them
	var	i, val;
	for (i = 0; i < Page_Validators.length; i++) {
		val = Page_Validators[i];

// assign the validation function to the object
		if (typeof(val.getAttribute("evaluationfunction")) == "string") {
			eval("val.evaluationfunction = " + val.getAttribute("evaluationfunction") + ";");
		}

// preset some additional attributes
		if (typeof(val.isvalid) == "string") {
			if (val.isvalid == "False") {
				val.isvalid = false;                                
				Page_IsValid = false;
			} else {
				val.isvalid = true;
			}
		} else {
			val.isvalid = true;
		}

// check if the span section is enabled or not
		if (typeof(val.enabled) == "string") {
			val.enabled = (val.enabled != "False");
		}

// hook functions, events and other stuff
		ValidatorHookupControlID(val.getAttribute("controltovalidate"), val);
		ValidatorHookupControlID(val.controlhookup, val);
	}

// ok, page activation is "enableable"...
	Page_ValidationActive = true;
}

//  ------------------------------------------------------------------------ //
// function:	 ValidatorConvert(op, dataType, val)
// what it does: convert a value in the correct type for validation
//  ------------------------------------------------------------------------ //
function ValidatorConvert(op, dataType, val)
{
// define annidated function (get year)
	function GetFullYear(year)
	{
        	return (year + parseInt(val.century)) - ((year < val.cutoffyear) ? 0 : 100);
	}

	var	num, cleanInput, m, exp;

// ok, convert types
	if (dataType == "Integer") {
		exp = /^\s*[-\+]?\d+\s*$/;
		if (op.match(exp) == null) {
			return null;
		}
		num = parseInt(op, 10);
		return (isNaN(num) ? null : num);
	} else if(dataType == "Double") {
		exp = new RegExp("^\\s*([-\\+])?(\\d+)?(\\" + val.getAttribute("decimalchar") + "(\\d+))?\\s*$");
		m = op.match(exp);
		if (m == null) {
            		return null;
		}
		if (typeof(m[1]) == "undefined") {
			m[1] = "";
		}
		if (typeof(m[2]) == "undefined") {
			m[2] = "";
		}
		if (typeof(m[3]) == "undefined") {
			m[3] = "";
		}
		if (typeof(m[4]) == "undefined") {
			m[4] = "";
		}
		cleanInput = m[1] + (m[2].length>0 ? m[2] : "0") + "." + m[4];
		num = parseFloat(cleanInput);
		return (isNaN(num) ? null : num);
	} else if (dataType == "Currency") {
		exp = new RegExp("^\\s*([-\\+])?(((\\d+)\\" + val.groupchar + ")*)(\\d+)"
			+ ((val.digits > 0) ? "(\\" + val.decimalchar + "(\\d{1," + val.digits + "}))?" : "")
			+ "\\s*$");
		m = op.match(exp);
		if (m == null) {
			return null;
		}
		var	intermed = m[2] + m[5] ;
		cleanInput = m[1] + intermed.replace(new RegExp("(\\" + val.groupchar + ")", "g"), "") + ((val.digits > 0) ? "." + m[7] : 0);
		num = parseFloat(cleanInput);
		return (isNaN(num) ? null : num);            
	} else if (dataType == "Date") {
		var	yearFirstExp = new RegExp("^\\s*((\\d{4})|(\\d{2}))([-/]|\\. ?)(\\d{1,2})\\4(\\d{1,2})\\s*$");
		m = op.match(yearFirstExp);
		var	day, month, year;
		if (m != null && (m[2].length == 4 || val.dateorder == "ymd")) {
			day = m[6];
			month = m[5];
			year = (m[2].length == 4) ? m[2] : GetFullYear(parseInt(m[3], 10))
		} else {
			if (val.dateorder == "ymd") {
				return null;		
			}
			var	yearLastExp = new RegExp("^\\s*(\\d{1,2})([-/]|\\. ?)(\\d{1,2})\\2((\\d{4})|(\\d{2}))\\s*$");
			m = op.match(yearLastExp);
			if (m == null) {
				return null;
			}
			if (val.dateorder == "mdy") {
				day = m[3];
				month = m[1];
			} else {
				day = m[1];
				month = m[3];
			}
			year = (m[5].length == 4) ? m[5] : GetFullYear(parseInt(m[6], 10))
		}
		month -= 1;
		var	date = new Date(year, month, day);
		return (typeof(date) == "object" && year == date.getFullYear() && month == date.getMonth() && day == date.getDate()) ? date.valueOf() : null;
	} else {
		return op.toString();
	}
}

//  ------------------------------------------------------------------------ //
// function:	 _comparemandatory(val)
// what it does: test if a comparing field is mandatory or not
//  ------------------------------------------------------------------------ //
function _comparemandatory(val)
{
// must be flagged as mandatory and with a joint field
	if (val.getAttribute("ismandatory") == "true") {
		if (val.getAttribute("jointfield") != null) {
			if (ValidatorTrim(ValidatorGetValue(val.getAttribute("jointfield"))) != "") {
				return(true);
			}
		} else {
			return(true);
		}
	}
	return(false);
}

//  ------------------------------------------------------------------------ //
// function:	 ValidatorCompare(operand1, operand2, operator, val)
// what it does: compare a validator against another using an operator
//  ------------------------------------------------------------------------ //
function ValidatorCompare(operand1, operand2, operator, val)
{
	var	dataType = val.getAttribute("type");
	var	op1, op2;

// execute comparision according to request
	if ((op1 = ValidatorConvert(operand1, dataType, val)) == null) {
		if (_comparemandatory(val)) {
			return false;
		} else {
			ValidatorSetValue(val.getAttribute("controltovalidate"), "");
			return true;
		}
	}
	if (operator == "DataTypeCheck") {
		ValidatorSetValue(val.getAttribute("controltovalidate"), ValidatorTrim(operand1));
		return true;
	}
	if ((op2 = ValidatorConvert(operand2, dataType, val)) == null) {
		return true;
	}

// operators converted, now check the operation request
	switch (operator) {

	case "NotEqual":		// must be !=
		return (op1 != op2);

	case "GreaterThan":		// must be >
		return (op1 > op2);

	case "GreaterThanEqual":	// must be >=
		return (op1 >= op2);

	case "LessThan":		// must be <
		return (op1 < op2);

	case "LessThanEqual":		// must be <=
		return (op1 <= op2);

	default:			// if nothing else above, =
		return (op1 == op2);
	}
}

//  ------------------------------------------------------------------------ //
// function:	 CompareValidatorEvaluateIsValid(val)
// what it does: span function: comparision
//  ------------------------------------------------------------------------ //
function CompareValidatorEvaluateIsValid(val)
{
	var	value = ValidatorGetValue(val.getAttribute("controltovalidate"));

// check if inserted something at first, if yes launch comparision
	if (ValidatorTrim(value).length == 0) {
		if (_comparemandatory(val)) {
			return false;
		} else {
			ValidatorSetValue(val.getAttribute("controltovalidate"), "");
			return true;
		}
	}

	var	compareTo = "";

// get element, compare operand and test it
	if (typeof(val.getAttribute("controltocompare")) != "undefined") {
		if (typeof(val.getAttribute("valuetocompare")) == "string") {
			compareTo = val.getAttribute("valuetocompare");
		} else {
			compareTo = ValidatorGetValue(val.getAttribute("controltocompare"));
		}
	}
	return ValidatorCompare(value, compareTo, val.getAttribute("operator"), val);
}

//  ------------------------------------------------------------------------ //
// function:	 CustomValidatorEvaluateIsValid(val)
// what it does: span function: custom validator (defined in SPAN section)
//  ------------------------------------------------------------------------ //
function CustomValidatorEvaluateIsValid(val)
{
	var	value = "";

// check type of validator
	if (typeof(val.getAttribute("controltovalidate")) == "string") {
		value = ValidatorGetValue(val.getAttribute("controltovalidate"));
		if (ValidatorTrim(value).length == 0) {
			return true;
		}
	}

	var	args = { Value:value, IsValid:true };
	if (typeof(val.clientvalidationfunction) == "string") {
		eval(val.clientvalidationfunction + "(val, args) ;");
	}
	return args.IsValid;
}

//  ------------------------------------------------------------------------ //
// function:	 RegularExpressionValidatorEvaluateIsValid(val)
// what it does: span function: evaluate against a regular expression
//  ------------------------------------------------------------------------ //
function RegularExpressionValidatorEvaluateIsValid(val)
{
	var	value = ValidatorGetValue(val.getAttribute("controltovalidate"));

// test type of validator
	if (ValidatorTrim(value).length == 0) {
		if (val.getAttribute("ismandatory") == "true") {
			return false;
		} else {
			ValidatorSetValue(val.getAttribute("controltovalidate"), ValidatorTrim(value));
			return true;
		}
	}
	ValidatorSetValue(val.getAttribute("controltovalidate"), ValidatorTrim(value));
	var	rx = new RegExp(val.getAttribute("validationexpression"));
	var	matches = rx.exec(ValidatorTrim(value));
	return (matches != null && ValidatorTrim(value) == matches[0]);
}

//  ------------------------------------------------------------------------ //
// function:	 ValidatorTrim(s)
// what it does: trim a string from trailing spaces and control chars
//  ------------------------------------------------------------------------ //
function ValidatorTrim(s)
{
	var	m = s.match(/^\s*(\S+(\s+\S+)*)\s*$/);
	return (m == null) ? "" : m[1];
}

//  ------------------------------------------------------------------------ //
// function:	 RequiredFieldValidatorEvaluateIsValid(val)
// what it does: span function: a field is required, whatever the content is
//  ------------------------------------------------------------------------ //
function RequiredFieldValidatorEvaluateIsValid(val)
{
	var	a = ValidatorTrim(ValidatorGetValue(val.getAttribute("controltovalidate")));
	var	b = ValidatorTrim(val.getAttribute("initialvalue"));
	var	result = (a != b);
	if (val.getAttribute("alternativecontrol") && (!result)) {
		a = ValidatorTrim(ValidatorGetValue(val.getAttribute("alternativecontrol")));
		result = (a != b);
	}
	return(result);
}

//  ------------------------------------------------------------------------ //
// function:	 RangeValidatorEvaluateIsValid(val)
// what it does: span function: a field must be in the indicated range
//  ------------------------------------------------------------------------ //
function RangeValidatorEvaluateIsValid(val)
{
	var	value = ValidatorGetValue(val.controltovalidate);

// check type and run comparision
	if (ValidatorTrim(value).length == 0) {
		return true;
	}
	return (ValidatorCompare(value, val.minimumvalue, "GreaterThanEqual", val) &&
		ValidatorCompare(value, val.maximumvalue, "LessThanEqual", val));
}

//  ------------------------------------------------------------------------ //
// function:	 ValidationSummaryOnSubmit()
// what it does: execute the error summary onto the page (span or div dynamic section)
//  ------------------------------------------------------------------------ //
function ValidationSummaryOnSubmit()
{
	if (typeof(Page_ValidationSummaries) == "undefined") {
		return;
	}
	var	summary, sums, s;
	for (sums = 0; sums < Page_ValidationSummaries.length; sums++) {
		summary = Page_ValidationSummaries[sums];
		summary.style.display = "none";
		if (!Page_IsValid) {			
			if (summary.getAttribute("showsummary") != "False") {
				summary.style.display = "";
				if (typeof(summary.getAttribute("displaymode")) != "string") {
					summary.displaymode = "BulletList";
				}
				switch (summary.displaymode) {

				case "List":
					headerSep = "<br>";
					first = "";
					pre = "";
					post = "<br>";
					_final = "";
					break;

				case "BulletList":
				default: 
					headerSep = "";
					first = "<ul>";
					pre = "<li>";
					post = "</li>";
					_final = "</ul>";
					break;

				case "SingleParagraph":
					headerSep = " ";
					first = "";
					pre = "";
					post = " ";
					_final = "<br>";
					break;
				}
				s = "";
				if (typeof(summary.headertext) == "string") {
					s += summary.headertext + headerSep;
				}
				s += first;
				for (i = 0; i < Page_Validators.length; i++) {
					if (!Page_Validators[i].isvalid && typeof(Page_Validators[i].errormessage) == "string") {
						s += pre + Page_Validators[i].errormessage + post;
					}
				}
				s += _final;
				summary.innerHTML = s; 
			}
			if (summary.getAttribute("showmessagebox") == "True") {
				s = "";
				if (typeof(summary.getAttribute("headertext")) == "string") {
					s += summary.getAttribute("headertext") + "<BR>";
				}
				for (i = 0; i < Page_Validators.length; i++) {
					if (!(Page_Validators[i].isvalid)) {
						switch (summary.getAttribute("displaymode")) {

						case "List":
							s += Page_Validators[i].getAttribute("errormessage") + "\n<BR>";
							break;

						case "BulletList":
						default:
							s += "  - " + Page_Validators[i].getAttribute("errormessage") + "\n<BR>";
							break;

						case "SingleParagraph":
							s += Page_Validators[i].getAttribute("errormessage") + " ";
							break;
						}
					}
				}
				span = document.createElement("SPAN");
				span.innerHTML = s;
				if (document.all) {		// FF workaround..... does not support innerText
					s = span.innerText;
				} else {
					s = span.textContent;
				}
				alert(s);
			}
		}
	}
}

