//-------------------------------------------------------------------------------
//Page:	Validate.js
//
//Description:
//	A set of validation functions.
//		 1.	checkDate(sValue, sValueName, bRequired, dtMin, dtMax, bAlert)
//		 2.	checkTime(sValue, sValueName, bRequired, dtMin,dtMax, bAlert)
//		 3.	checkRequired(sValue, sValueName, bRequired, bAlert, sRequiredMsg)
//		 4.	checkString(sValue, sValueName, bRequired, iMinLen, iMaxLen, bAlert,sRequiredMsg)
//		 5.	checkNumeric(sValue, sValueName, bRequired, dblMin, dblMax, bAlert)
//		 6.	checkDateRange(sMinValue, sMaxValue, sMinValueName, sMaxValueName, bAlert)
//		 7.	parseNumeric(sValue)
//		 8.	parseDate(sValue)
//		 9.	parseTime(sValue)
//		10.	isLeapYear(iValue)
//		11.	isInteger(sValue)
//
//Author:
//	Rob Ruijter
//
//History:
//	21/02/2001	RR	Created
//	
//-------------------------------------------------------------------------------

//@doc

//@func	bool | checkDate | A date consists of a day,a month and a year.
//				This function returns true if the given parameter is a valid date, 
//				and if the date lies within the given dates dtMin and dtMax.
//@parm char | sValueName | The name of the uservariable to be checked.
//@parm char | sValue | The value of the uservariable to be checked. 
//				It is a string that contains a date. A date value consists of a 
//				concatenation of day, month and year.
//				The use of a separator in the string is optional.	
//@parm bool | bRequired | A boolean stating if checking is required.
//@parm date | dtMin | The minimal acceptable date.
//@parm date | dtMax | The maximal acceptable date.
//@rdesc A boolean that states whether the parameter is a valid Date and lies
//				within the given boundaries dtMin and dtMax.
//@flag true | if <p sValue> is a valid date, and if the date lies within the given
//				dates <p dtMin> and <p dtMax>.
//@flag false | In all other situations.


//Check date	

	function checkDate(sValue, sValueName, bRequired, dtMin, dtMax, bAlert){
		if (!checkRequired(sValue, sValueName, bRequired, bAlert))
			return false;
		else if (sValue.length == 0)
			return true;

		var dtValue = parseDate(sValue);
		if (dtValue == null) {
			if (bAlert) {
				alert('\"' + sValueName + '\" is geen datum');
			}
		return false;
		}
		else{
		//date is valid
			if ((dtMin != null) && (typeof(dtMin) == "object")){
				dtMin.setHours(0,0,0,0);//round to whole days
				if (dtValue < dtMin){
					if (bAlert) {
						alert('\"' + sValueName + '\" moet groter dan of gelijk zijn aan \"' +  dtMin.getDate() + "-" + 
								(dtMin.getMonth()+1) + "-"  + dtMin.getFullYear() + '\"');
					}
					return false;
				}
			}
			if ((dtMax != null) && (typeof(dtMax) == "object")){
				dtMax.setHours(0,0,0,0);//round to whole days
				if (dtValue > dtMax){
					if (bAlert) {
						alert('\"' + sValueName + '\" moet kleiner dan of gelijk zijn aan \"' + dtMax.getDate() + "-" + 
								(dtMax.getMonth()+1) + "-"  + dtMax.getFullYear() + '\"');
					}
					return false;
				}
			}
			return true;
		}
	}


//@func bool | checkTime | This function checks whether the given parameter string 
//				represents a valid time.  Examples are: 11:33:46, 1233, 1:30 or 14850
//@parm char | sValueName | The name of the uservariable to be checked.
//@parm char | sValue | The value of the uservariable to be checked. 
//				It is a string that contains a time. A time value consists of a 
//				concatenation of hours, minutes and optionally seconds.
//				The use of a separator in the string is optional.	
//@parm bool | bRequired | A boolean stating if checking is required.
//@parm date | dtMin | The minimal acceptable time.
//@parm date | dtMax | The maximal acceptable time.
//@rdesc A boolean that states whether the parameter is a valid time and lies within 
//				the given boundaries.
//@flag true| If <p sValue> is a valid time and lies within the given boundaries.
//@flag false| In all other situations.


//check time 				
	
	function checkTime(sValue, sValueName, bRequired, dtMin,dtMax, bAlert){
		if (!checkRequired(sValue, sValueName, bRequired, bAlert))
			return false;
		else if (sValue.length == 0)
			return true;

		var dtValue = parseTime(sValue);
		if (dtValue == null) {
			if (bAlert) {
				alert('\"' + sValueName + '\" is geen tijd');
			}
			return false;
		}
		else{
			//date is valid
			var iValueMillis = dtValue.valueOf();
			if ((dtMin != null) && (typeof(dtMin) == "object")){
				var iMinMillis = dtMin.valueOf();
				if (iValueMillis < iMinMillis){
					var sTime = dtMin.toString().substring(dtMin.toString().indexOf(":")-2,dtMin.toString().indexOf(":")+6);
					if (bAlert) {
						alert('\"' + sValueName + '\" moet groter dan of gelijk zijn aan \"' + sTime + '\"');
					}
					return false;
				}
			}
			if ((dtMax != null) && (typeof(dtMax) == "object")){
				var iMaxMillis = dtMax.valueOf();
				if (iValueMillis > iMaxMillis){
					var sTime = dtMax.toString().substring(dtMax.toString().indexOf(":")-2,dtMax.toString().indexOf(":")+6);
					if (bAlert) {
						alert('\"' + sValueName + '\" moet kleiner dan of gelijk zijn aan \"' + sTime + '\"');
					}
					return false;
				}
			}
			return true;
		}
	}


//@func bool | checkRequired | The function <f checkRequired> checks if the uservariable, 
//				if it is required, has a value.
//@parm char | sValueName | The name of the uservariable to be checked.
//@parm char | sValue | The value of the uservariable to be checked.
//@parm bool | bRequired | A boolean stating if checking is required.
//@rdesc A boolean returning true if <p sValue> contains a value. 
//				True is always returned if it is not required (<p bRequired> is false) to 
//				check the uservariable.
//@flag true | Is always returned if it is not required (<p bRequired> is false) to 
//				check the uservariable. 
//				Otherwise if <p sValue> contains a value.
//@flag false | In all other situations.


//Check required

	function checkRequired(sValue, sValueName, bRequired, bAlert, sRequiredMsg) {
		if (bRequired && (sValue.length == 0)) {
			if (bAlert) 
				alert(sRequiredMsg != null ? sRequiredMsg : 'U dient het veld \'' + sValueName + '\' nog in te vullen');
			return false;
		}
		return true;
	}


//@func bool | checkString | The function <f checkString> checks the given <p sValue> on it's  
//				minimum and maximum length. Return false if the string exceeds the given 
//				boundaries.
//@parm	char | sValueName | The name of the uservariable to be checked.
//@parm char | sValue | The value of the uservariable to be checked.
//@parm bool | bRequired | A boolean stating if checking is required.
//@parm int | iMinLen | The minimum acceptable length of the string.
//@parm int | iMaxLen | The maximum acceptable length of the string.
//@rdesc A boolean that states whether sValue is a valid string.
//@flag true | If <p sValue> is a valid string.
//@flag false | If <p sValue> is not a valid string.


//Check string

	function checkString(sValue, sValueName, bRequired, iMinLen, iMaxLen, bAlert,sRequiredMsg) {
		if (!checkRequired(sValue, sValueName, bRequired, bAlert, sRequiredMsg))
			return false;
		else if (sValue.length == 0)
			return true;
	
		if ((iMinLen != null) && (sValue.length < iMinLen)) {
			if (bAlert) {
				alert('\"' + sValueName + '\" moet minimaal \"' + iMinLen + '\" karakters bevatten');
			}
			return false;
		}
		else if ((iMaxLen != null) && (sValue.length > iMaxLen)) {
			if (bAlert) {
				alert('\"' + sValueName + '\" mag maximaal \"' + iMaxLen + '\" karakters bevatten');
			}
			return false;
		}
		return true;
	}


//@func bool | checkNumeric | The function <f checkNumeric> checks the given <p sValue> on 
//				it's minimum and maximureturns false if the numeric value exceeds the  
//				given boundaries.	
//@parm char | sValueName | The name of the uservariable to be checked.
//@parm char | sValue | The value of the uservariable to be checked.
//@parm bool | bRequired | A boolean stating if checking is required.
//@parm dbl | dblMin | The minimum acceptable length of the string.
//@parm dbl | dblMax | The maximum acceptable length of the string.
//@rdesc A boolean that states whether sValue is a valid numeric.
//@flag true | If <p sValue> is a valid numeric.
//@flag false | If <p sValue> is not a valid numeric.


//check numeric
	
	function checkNumeric(sValue, sValueName, bRequired, dblMin, dblMax, bAlert) {
		if (!checkRequired(sValue, sValueName, bRequired, bAlert))
			return false;
		else if (sValue.length == 0)
			return true;
	//transform value to a value that can be used in calculations
		var dblValue = parseNumeric(sValue);
		if (dblValue == null) {
			if (bAlert)
				alert('\"' + sValueName + '\" is niet numeriek');
			return false;
		}
		if ((dblMin != null) && (dblValue < dblMin)) {
			if (bAlert)
				alert('\"' + sValueName + '\" moet groter dan of gelijk zijn aan \"' + dblMin + '\"');
			return false;
		}
		else if ((dblMax != null) && (dblValue > dblMax)) {
			if (bAlert)
				alert('\"' + sValueName + '\" moet kleiner dan of gelijk zijn aan \"' + dblMax + '\"');
			return false;
		}
		return true;
	}


//@func bool | checkDateRange | Returns whether end date is greater than or equal to start date
//@parm char | sMinValue | Begin date string
//@parm char | sMaxValue | End data string
//@parm char | sMinValueName | Begin date name
//@parm char | sMaxValueName | End date name
//@parm bool | bAlert | A boolean stating if an alert should be given


// check date range
	
	function checkDateRange(sMinValue, sMaxValue, sMinValueName, sMaxValueName, bAlert) {
		var dtBegin = parseDate(sMinValue);
		var dtEnd  = parseDate(sMaxValue);

		if (dtBegin && dtEnd && (dtBegin > dtEnd)) {
			if (bAlert)
				alert('\"' + sMinValueName + '\" moet eerder zijn dan of gelijk zijn aan \"' + sMaxValueName + '\"');
			return false;
		}
		return true;
	}


//@func float | parseNumeric | Every value for which the function <f isNumeric> is True, 
//				can be parsed.
//@parm char | sValue | A string that contains a numeric value.
//@rdesc The numeric representation of the parameter string. 
//				If parsing is not possible, null is returned.


//parse numeric

	function parseNumeric(sValue){
		var reThousands = new RegExp('\\' + THOUSANDS_SEPARATOR, 'g');
		var reDecimals = new RegExp('\\' + DECIMAL_SEPARATOR, 'g');
		var reFloat = /^[\+-]?\d+\.?\d*$/

		var s = sValue.replace(reThousands, '').replace(reDecimals, '.');
		return (reFloat.test(s) ? parseFloat(s) : null);
	}

//@func date | parseDate |A date consists of a day, a month, and a year.
//				this function returns true if the given parameter is a valid date. 
//				Otherwise false is returned. 
//@parm	| sValue | A string that contains a date. A date consists of a day,
//				a month and a year.
//@rdesc A Date object for every valid date, null for an invalid date.
//				The hour,minute and second variables are not used.


//parse date

	function parseDate(sValue){
	//remove white spaces.
		sValue = trim(sValue);
		var sSeparator;
		var sDay = "";
		var sMonth = "";
		var sYear = "";
	
	//determine the separator if any.
		if (sValue.indexOf("/") != -1)
			sSeparator = "/";
		else if (sValue.indexOf(".") != -1)
			sSeparator = ".";
		else if (sValue.indexOf("-") != -1)
			sSeparator = "-";
		else
			sSeparator = "";
	
		if (sSeparator == ""){
		// there is no separator
			if (sValue.length == 4) {
				sDay = sValue.substring(0,1);
				sMonth = sValue.substring(1,2);
				sYear = sValue.substr(2);
			}
			else if (sValue.length == 5) {
				sDay = sValue.substring(0,1);
				sMonth = sValue.substring(1,3);
				sYear = sValue.substr(3);
			}
			else if (sValue.length == 6) {
				sDay = sValue.substring(0,2);
				sMonth = sValue.substring(2,4);
				sYear = sValue.substr(4);
			}
			else if (sValue.length == 7) {
				sDay = sValue.substring(0,1);
				sMonth = sValue.substring(1,3);
				sYear = sValue.substr(3);
			}
			else if (sValue.length == 8) {
				sDay = sValue.substring(0,2);
				sMonth = sValue.substring(2,4);
				sYear = sValue.substr(4);
			}
		}
		else{
		//there is a separator
			var firstSeparatorIndex = sValue.indexOf(sSeparator);
			var secondSeparatorIndex = sValue.lastIndexOf(sSeparator);
			sDay = sValue.substring(0,firstSeparatorIndex);
			if ((secondSeparatorIndex - firstSeparatorIndex) == 2 ||
				(secondSeparatorIndex - firstSeparatorIndex) == 3){
				sMonth = sValue.substring(firstSeparatorIndex+1,secondSeparatorIndex);
				sYear = sValue.substr(secondSeparatorIndex+1);
			}
			else
				return null;
		}
		var bDotsAndCommasAllowed = false
		if (!isInteger(sDay) || !isInteger(sMonth) || !isInteger(sYear))
			return null;
	
	//patch JavaScript handling of two-digit year strings
		if (sYear.length == 2) {
			var dtNow = new Date();
			if (parseInt(sYear) < 25){
				sYear = dtNow.getFullYear().toString().substring(0,2) + sYear;
			}
			else{
				/*sYear = (dtNow.getFullYear()-1).toString().substring(0,2) + sYear;*/
				sYear = "19" + sYear
			}
		}

		iDay = parseInt(sDay, 10);
		iMonth = parseInt(sMonth, 10);
		iYear = parseInt(sYear, 10);	
	
		if (iDay < 1 || iDay > 31 || iMonth < 1 || iMonth > 12 || iYear < 0 || iYear > 9999)
			return null;
		else if (iDay == 31 && (iMonth == 4 || iMonth == 6 || iMonth == 9 || iMonth == 11))
			return null;
		else if (iDay > 28 && iMonth == 2 && !isLeapYear(iYear))
			return null;
		else if (iDay > 29 && iMonth == 2)
			return null;
		else {
		//the date is correct. The Date object numbers it's months
		//0 to 11.
			return (new Date(iYear,(iMonth-1),iDay));
		}
		return null;
	}


//@func date | parseTime | This function checks whether the given parameter string 
//				represents a valid time and returns the time in a Date object.
//				Examples are: 11:33:46, 1233, 1:30 or 14850
//@parm char | sValue |	A string that contains a time. A time value is a 
//				concatenation of hours, minutes and optionally seconds.
//				The use of the separator (:) is optional.
//@rdesc A Date object for every valid time, null for an invalid time.


//parse time
	function parseTime(sValue){
		sValue = trim(sValue);
		var sSeparator;
		var sHours = "";
		var sMinutes = "";
		var sSeconds = "";
	
	//determine the separator if any.
		if (sValue.indexOf("/") != -1)
			sSeparator = "/";
		else if (sValue.indexOf(".") != -1)
			sSeparator = ".";
		else if (sValue.indexOf("-") != -1)
			sSeparator = "-";
		else if (sValue.indexOf(":") != -1)
			sSeparator = ":";
		else
			sSeparator = "";
		
		if (sSeparator == ""){
		//there is no separator
			if (sValue.length == 5){
				sHours = sValue.substring(0,1);
				sMinutes = sValue.substring(1,3);
				sSeconds = sValue.substring(3,5);
			}
			else if (sValue.length == 3){
				sHours = sValue.substring(0,1);
				sMinutes = sValue.substring(1,3);
				sSeconds = "0";
			}
			else if (sValue.length == 6){
				sHours = sValue.substring(0,2);
				sMinutes = sValue.substring(2,4);
				sSeconds = sValue.substring(4,6);
			}
			else if (sValue.length == 4){
				sHours = sValue.substring(0,2);
				sMinutes = sValue.substring(2,4);
				sSeconds = "0";
			}
			else
				return null;
		}
		else{
		//there is a separator
			var firstSeparatorIndex = sValue.indexOf(sSeparator);
			var secondSeparatorIndex = sValue.lastIndexOf(sSeparator);
	
			sHours = sValue.substring(0,firstSeparatorIndex);
			if (firstSeparatorIndex != secondSeparatorIndex){
			//there are 2 separators, try to distill both minute and second value
				if ((secondSeparatorIndex - firstSeparatorIndex) == 2 ||
					(secondSeparatorIndex - firstSeparatorIndex) == 3){
					sMinutes = sValue.substring(firstSeparatorIndex+1,secondSeparatorIndex);
					if (secondSeparatorIndex < (sValue.length-1))
					//seconds are encoded in sValue.
						sSeconds = sValue.substr(secondSeparatorIndex+1);
					else
					//second separator but no seconds added.
						return null;
				}
			}
			else{
				sMinutes = sValue.substr(firstSeparatorIndex+1);
				sSeconds = "0";
			}
		}
		var bDotsAndCommasAllowed = false;
		if (!isInteger(sHours) || !isInteger(sMinutes) || !isInteger(sSeconds))
			return null;

		if (sHours < 0 || sHours > 23 || sMinutes < 0 || sMinutes > 59 || 
			sSeconds < 0 || sSeconds > 59)
			return null;

		return (new Date(0,0,0,sHours,sMinutes,sSeconds));
	}


//@func bool | isLeapYear | This function determines whether the given parameter is 
//				a leapyear.
//				A year is a leapyear if:
//				it is divisible by 4, but not divisible by 100
//				A year is a leapyear if:
//				it is divisible by 400. So, the year 2000 is a leapyear!
//@parm int | iValue |An integer.
//@rdesc A boolean expression that states wether the parameter <p iValue> is a leap year.
//@flag true | If the parameter <p iValue> is a leapyear.
//@flag false | If the parameter <p iValue> is a non-leapyear.	


//leapyear (schrikkeljaar)
	function isLeapYear(iValue){
		if ((iValue%400)==0)
			return true;
		else if ((iValue%100)==0)
			return false;
		else if ((iValue%4)==0)
			return true;
		else 
			return false;
	}


//check integer	
	function isInteger(sValue) {
		var re = /^\d+$/;
		return re.test(sValue);
	}


//@func	bool | checkPattern |
//				This function returns true if the given value is valid against
//				the given regular expression.
//@parm char | sValueName | The name of the uservariable to be checked.
//@parm char | sValue | The value of the uservariable to be checked.
//@parm string | sPattern | The pattern (regular expression).
//@parm bool | bRequired | A boolean stating if checking is required.
//@flag true | if <p sValue> is valid against the given regular expression.
//@flag false | In all other situations.


//Check pattern	

	function checkPattern(sValue, sValueName, sPattern, bRequired, bAlert){
		var oRegExp;
		
		oRegExp = new RegExp(sPattern);
		
		if (sValue.length == 0)
			return checkRequired(sValue, sValueName, bRequired, bAlert);
		if (oRegExp.test(sValue))
			return true;
		if (bAlert)
			alert('\"' + sValueName + '\" heeft geen geldig formaat');
		return false;
	}
	

	// extra validator functions:
//@func | RadioValidator |
//@parm char | sName |
//@parm bool | bRequired |

	function RadioValidator(sName, bRequired, bAlert, sRequiredMsg) {
		this.name = sName;
		this.required = bRequired;
		this.alert = bAlert;

		this.format = function(sValue) { 
			alert("RadioValidator format")
			return sValue; 
		}

		this.initializeElement = function (oElement) {	
			alert("RadioValidator init");
		}

		this.validate = function (sValue, bAlert) {
			alert("RadioValidator validate")
			xxxxxxx
			return checkRadio(sValue, this.name, this.required, 
				this.alert || bAlert , sRequiredMsg);
		}
	}

	function checkRadio(sValue, sValueName, bRequired, bAlert,sRequiredMsg) {
		// not implemented yet
	}
	
	function checkLogin (objUserName, objPassword){
		if (objUserName.value == '' && objPassword.value == ''){
			alert('De gebruikersnaam en het wachtwoord mogen niet leeg zijn');
			return false;
		}
		if (objUserName.value == ''){
			alert('De gebruikersnaam mag niet leeg zijn');
			return false;
		}
		if (objPassword.value == ''){
			alert('Het wachtwoord mag niet leeg zijn');
			return false;
		}
		return true;
	}
