//-------------------------------------------------------------------------------
//@contents1 Page: Validator.js
//	A set of validation classes for forms and form elements. Depends on 
//	"validate.htm" for actual validations.
//
//		 1.	PatternValidator(sName, bRequired, sPattern, bAlert)
//		 2.	TextValidator(sName, bRequired, dtMinLen, dtMaxLen, bAlert, sRequiredMsg)
//		 3.	NumberValidator(sName, bRequired, fltMinValue, fltMaxValue, iMaxLen, bAlert)
//		 4.	DateValidator(sName, bRequired, dtMinValue, dtMaxValue, bAlert)
//		 5.	TimeValidator(sName, bRequired, dtMinValue, dtMaxValue, bAlert)
//		 6.	attachColor(oElement, sColor)
//		 7.	attachValidator(oElement, oValidator, fncOnValidated)
//		 8.	validateForm(oForm)
//		 9.	getValue(oElement)
//		10.	storeForm(oForm)
//		11.	isFormModified(oForm)
//
//Author:
//	Rob Ruijter
//
//History:
//	21/02/2001	RR	Created
//	
//@end
//-------------------------------------------------------------------------------
//@doc 

//Browser check
	var browsername = navigator.appName;
	var browserver = parseInt(navigator.appVersion);
	var browserNetscape = 0
	var browserIe = 1
	var version = null;
	if (browsername == 'Netscape' && browserver >= 3) version = browserNetscape;
	if (browsername == 'Microsoft Internet Explorer' && browserver >= 4) version = browserIe;

//@func | PatternValidator | Regular expression validations
//@parm char | sName |
//@parm bool | bRequired |
//@parm string | sPattern |

	function PatternValidator(sName, bRequired, sPattern, bAlert) {
		this.name = sName;
		this.required = bRequired;
		this.regexp = new RegExp(sPattern);
		this.alert = bAlert;

		this.format = function(sValue) {
			return sValue; 
		}

		this.initializeElement = function (oElement) {}

		this.validate = function (sValue, bAlert) {
			if (sValue.length == 0)
				return checkRequired(sValue, this.name, this.required, this.alert || bAlert);
			if (this.regexp.test(sValue))
				return true;
			if (this.alert || bAlert)
				alert('\"' + this.name + '\" heeft geen geldig formaat');
			return false;
		}
	}

//@func | TextValidator |
//@parm char | sName |
//@parm bool | bRequired |
//@parm date | dtMinLen |
//@parm date | dtMaxLen |

	function TextValidator(sName, bRequired, dtMinLen, dtMaxLen, bAlert, sRequiredMsg) {
		this.name = sName;
		this.required = bRequired;
		this.minLen = dtMinLen;
		this.maxLen = dtMaxLen;
		this.alert = bAlert;

		this.format = function(sValue) { 
			return sValue; 
		}

		this.initializeElement = function (oElement) {
			if (this.maxLen && (oElement.type == 'text' || oElement.type == 'password'))
				oElement.maxLength = this.maxLen;
		}

		this.validate = function (sValue, bAlert) {
			return checkString(sValue, this.name, this.required, 
				this.minLen, this.maxLen, this.alert || bAlert , sRequiredMsg);
		}
	}

//@func | NumberValidator | Numeric value validator object constructor
//@parm char | sName | Name to identify validated item in error messages.
//@parm bool | bRequired | Flags whether value is required
//@parm double | fltMinValue | Minimum allowed value.
//@parm double | fltMaxValue | Maximum allowed value.
//@parm int | iMaxLen | Maximum number of characters in value string.
//@parm Boolean | bAlert | Flags whether error message is shown on failed validation.

	function NumberValidator(sName, bRequired, fltMinValue, fltMaxValue, iMaxLen, bAlert) {
		this.name = sName;
		this.required = bRequired;
		this.minValue = fltMinValue;
		this.maxValue = fltMaxValue;
		this.maxLen = iMaxLen;
		this.alert = bAlert;

		this.format = function (sValue) {
			var iValue = parseNumeric(sValue);
			return (iValue != null ? iValue.toString().replace(/\./g, DECIMAL_SEPARATOR) : '');
		}

		this.initializeElement = function (oElement) {
			if (this.maxLen && (oElement.type == 'text' || oElement.type == 'password'))
				oElement.maxLength = this.maxLen;
		}

		this.validate = function (sValue, bAlert) {
			return checkNumeric(sValue, this.name, this.required, 
				this.minValue, this.maxValue, this.alert || bAlert);
		}
	}

//@func | DateValidator | TODO_BG commentaar
//
//@parm char | sName | TODO_BG commentaar
//@parm bool | bRequired | TODO_BG commentaar
//@parm date | dtMinValue | TODO_BG commentaar
//@parm date | dtMaxValue | TODO_BG commentaar

	function DateValidator(sName, bRequired, dtMinValue, dtMaxValue, bAlert) {
		this.name = sName;
		this.required = bRequired;
		this.minValue = dtMinValue;
		this.maxValue = dtMaxValue;
		this.alert = bAlert;

		this.format = function (sValue) {
			return formatDate(parseDate(sValue));
		}

		this.initializeElement = function (oElement) {
			if (oElement.type == 'text' || oElement.type == 'password')
				oElement.maxLength = 10;
		}

		this.validate = function (sValue, bAlert) {
			return checkDate(sValue, this.name, this.required, 
				this.minValue, this.maxValue, this.alert || bAlert);
		}
	}

//@func | TimeValidator | TODO_BG commentaar
//
//@parm char | sName | TODO_BG commentaar
//@parm bool | bRequired | TODO_BG commentaar
//@parm date | dtMinValue | TODO_BG commentaar
//@parm date | dtMaxValue | TODO_BG commentaar

	function TimeValidator(sName, bRequired, dtMinValue, dtMaxValue, bAlert) {
		this.name = sName;
		this.required = bRequired;
		this.minValue = dtMinValue;
		this.maxValue = dtMaxValue;	
		this.alert = bAlert;

		this.format = function (sValue) {
			return formatTime(parseTime(sValue));
		}

		this.initializeElement = function (oElement) {
			if (oElement.type == 'text' || oElement.type == 'password')
				oElement.maxLength = 5;
		}

		this.validate = function (sValue, bAlert) {
			return checkTime(sValue, this.name, this.required, 
				this.minValue, this.maxValue, this.alert || bAlert);
		}
	}

//
//Utility methods
//

	function attachColor(oElement, sColor) {
		if (version == browserIe) {
			oElement.style.color = sColor;
			if (oElement.type.substr(0,6) == 'select') {
				var iLen = oElement.options.length;
				for (var i=0; i < iLen; i++)
					oElement.options(i).style.color = sColor;
			}
		}
	}

//@func | attachValidator |Attaches validator object to input element. 
//	Causes validation when onblur event handler is fired.
//@parm object | oElement | Input element to which validator must be attached.
//@parm object | oValidator | Validator object to be attached to input element.
//@parm function | fncOnValidated | TODO_BG commentaar

	function attachValidator(oElement, oValidator, fncOnValidated) {
		oElement._valid = null;
		oElement.validator = oValidator;

		oValidator.initializeElement(oElement);

		oElement.getValue = function() {
			if (this.value != null)
				return this.value;
			if (this.type == 'select-one')
				return this.options[this.selectedIndex].value;
			return '';
		}
		oElement.validate = function (bAlert) {
		//prevent recursion
			if (this._validating)
				return this._valid;

		//initialise validation properties
			this._validating = true;
			if (this.beforevalidate)
				this.beforevalidate();

			if (this.validator){
				this._valid = this.validator.validate(this.getValue(), bAlert);
				attachColor(this, this._valid ? '' : 'red');
			};
			if (this._valid && this.onvalidated)
				this.onvalidated();

		//cleanup validation properties
			this._validating = null;
			return this._valid;
		}
		oElement.isValid = function () {
			return (this._valid == null ? this.validate() : this._valid);
		}

		oElement.onvalidated = fncOnValidated;
		oElement.onblur = function() {
			if (!this.validate()) return;
			if (this.value != null)	this.value = this.validator.format(this.getValue());
		}
	}
	
//@func | detachValidator |Detaches validator object to input element. 
//	Ceases validation of object
	function detachValidator(oElement) {
		//alert('detachValidator: ' + oElement.id + ' ' + oElement.validator)
		oElement.validator = null;
		oElement._valid = true;
		oElement._validating = null;
		oElement.beforevalidate=null;
	}

//@func bool | validateForm | Validates all form elements which have a validate() method.
//@parm object | oForm | Form to be validated.
//@rdesc Boolean indicating whether form exists and whether all form elements with validation 
//	were validated successfully.

	function validateForm(oForm) {
		var i, iLen;
		var oElement;

	//Check whether form exists.
		if (!oForm) return false;
	
	//Execute any validate methods on form elements
		iLen = oForm.elements.length;
		for (i=0; i < iLen; i++) {
			oElement = oForm.elements[i];
			
		//	//display if hidden DIV or SPAN
		//	if(oElement.tagName=="DIV" ||oElement.tagName=="SPAN"){
		//		oElement.style.display=""
		//	}
			
			//validate
			if (oElement.validate && !oElement.validate(true)) {
			//set focus if possible.
				if (!oElement.disabled && oElement.type != "hidden" ){
					try {oElement.focus()} catch(e) {}
				}
				return false;
			}
		}
	
	//validation is successful.
		return true;
	}

//@func bool | getValue | get values of element.
//@parm object | oElement | Element to value for.

	function getValue(oElement) {
		var t = oElement.type;
		if (t == "text" || t == "password" || t == "hidden") 
			return oElement.value;
		else if (t == "radio" || t == "checkbox")
			return oElement.checked;
		else if (t == "select-one")
			return oElement.selectedIndex;
		return "";
	}


//@func bool | storeForm | Stores all form elements.
//@parm object | oForm | Form to be stored.

	function storeForm(oForm) {
		var i, iLen;
		var oElement;
	
	//Check whether form exists.
		if (!oForm) return false;
	
	//Execute any validate methods on form elements
		iLen = oForm.elements.length;
		oForm.oldLength = iLen;
		for (i=0; i < iLen; i++) {
			oElement = oForm.elements[i];
			oElement.oldValue = getValue(oElement);
		}
		return true
	}

//@func bool | storeForm | Stores all form elements.
//@parm object | oForm | Form to be stored.

	function isFormModified(oForm) {
		var i, iLen;
		var oElement;
		var oValue;
	
	//Check whether form exists.
		if (!oForm) return false;
		if (oForm.oldLength == null) return false;
	
	//if number of elements changed, the form is considered modified.
		iLen = oForm.elements.length;
		if (oForm.oldLength != iLen) return true;
	
		for (i=0; i < iLen; i++) {
			oElement = oForm.elements[i];
			if (oElement.oldValue != null) {
				oValue = getValue(oElement);
				if (oElement.oldValue != oValue)
					return true;
			}
		}
		return false;
	}
