/********************************************************************
*	Created by : M. Gervais
*	Cyber Generation
*	Date : 2006-11-20
*
*   Modifications :
*
*   Author : Philippe Meunier
*   Date : March 7 2007
*   Description : Uniformised behaviour of some "check" functions to recieve the field ID instead of the
*                 field object itself. Also commented the "focus" on some Check functions because it can
*                 be confusing if more than one check function fails, to know where the focus should go.
********************************************************************/

/********************************************************************
* Constructor
********************************************************************/

function Validator(){
	this.init();	
}

/********************************************************************
* Core Functions
********************************************************************/

Validator.prototype.init = function () {
	this.NbErrors = 0;
	this.ErrorMessage = '';
	this.Header = 'Some required fields are missing...';
	
	this.UsernameMinLength = 4;
	this.UsernameMaxLength = 10;
	
	this.PasswordMinLength = 4;
	this.PasswordMaxLength = 10;

	this.PasswordAllowDigit = true;
	this.PasswordAllowLower = true;
	this.PasswordAllowUpper = true;
	
	this.PasswordMinOneDigit = true;
	this.PasswordMinOneLower = true;
	this.PasswordMinOneUpper = true;

	this.AllTextFieldsRequired = false;
	this.arrRequired = new Array();
	
	this.DefineRegexpWebColor = /[0-9A-F]{6}/gi;
	this.DefineRegexpPhoneNumber = /(\d{3}-\d{3}-\d{4})/gi;
	this.DefineRegexpUrl = /(https?:\/\/)/gi;
	this.DefineRegexpEmail = /([\w\_\.\-]+\@[\w\_\.\-]+\.[a-zA-Z]{2,5})/i;
	this.DefineCanadianPostalCode = /([ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ]\s\d[ABCEGHJKLMNPRSTVWXYZ]\d)/i;
}

Validator.prototype.Confirmation = function(sMsg) {
	var agree = false;
	agree = confirm(sMsg);
	if (agree)
		agree = true;

	return agree;
}

Validator.prototype.SetRequiredField = function (sFieldname, sMsg) {
	this.arrRequired.push(new Array(sFieldname, sMsg));
}

Validator.prototype.SetInitialMessage = function (sMsg) {
	var arrMsg = sMsg.split('###');
	
	for (var i=0 ; i < arrMsg.length ; i++)
		this.AddErrMsg(arrMsg[i]);
}

Validator.prototype.MissingFields = function () {
	var bReturn = false;
	var bFck = false;
	this.NbErrors = 0;
	this.ErrorMessage = '';
	
	if (this.AllTextFieldsRequired) {
		var field;
		
		for (var e = 0; e < document.forms[0].elements.length; e++)
		{
			field = document.forms[0].elements[e];
		
			if (field.type.toLowerCase() == 'text')
			{
				if (this.Trim(field.value) == ''){
					bReturn = true;
				}
			}
		}
	}
	else {
		for (var i=0 ; i < this.arrRequired.length ; i++) {
			
			bFck = false;
			
			if(typeof(FCKeditorAPI) != 'undefined'){
				if(FCKeditorAPI.GetInstance(this.arrRequired[i][0])){
					
					bFck = true;
					
					if(FCKeditorAPI.GetInstance(this.arrRequired[i][0]).GetXHTML().length == 0)
						this.AddErrMsg(this.arrRequired[i][1]);
				}
			}
			
			if (!bFck){
				if (this.Trim(document.getElementById(this.arrRequired[i][0]).value) == '')
					this.AddErrMsg(this.arrRequired[i][1]);
			}
		}
				
		if (this.NbErrors == 0)
			bReturn = false;
		else
			bReturn = true;
	}
	
	return bReturn;
}

Validator.prototype.GetErrorMessage = function () {
	if (this.ErrorMessage != '')
		return this.Header + '\n\n' + this.ErrorMessage;
	else
		return this.Header;
}

Validator.prototype.AddErrMsg = function (sMsg) {
	if (sMsg != '') {
		this.ErrorMessage = this.ErrorMessage + '- ' + sMsg + '\n';
		this.NbErrors = this.NbErrors + 1;
	}
}

/********************************************************************
* Validations Functions
********************************************************************/
Validator.prototype.IsDigit = function (ch) {
	return ((ch >= "0") && (ch <= "9"));
}

Validator.prototype.IsInteger = function (s) {
	
	var oRegexp = /^-?[0-9]+$/;
	var bReturn;
	
	bReturn = true;
		
	if(!oRegexp.test(s))
		{bReturn = false;}
	
	oRegexp = null;
	
	return bReturn;
}

Validator.prototype.IsCanadianPostalCode = function (s) {
	return this.DefineCanadianPostalCode.test(s);
}

Validator.prototype.IsEmpty = function (s) {
	return ((s == null) || (s.length == 0));
}

Validator.prototype.IsWebColor = function (sCode) {
	return sCode.match(this.DefineRegexpWebColor);
}

Validator.prototype.IsBetween = function (iValue, iMinBound, iMaxBound) { 
	var iValue = parseInt(iValue, 10);

	if (iValue >= iMinBound && iValue <= iMaxBound)
		return true;
	else
		return false;
}

Validator.prototype.IsDate = function (dtStr) {
	var oRegExp = new RegExp('^\\d{4}-\\d{1,2}-\\d{1,2}$');
	var bValid = false;
	var arrSplit;
	var iYear, iMonth, iDay;
	
	if(oRegExp.test(dtStr)) {
		arrSplit = dtStr.split('-');
		
		iYear = parseInt(arrSplit[0], 10);
		iMonth = parseInt(arrSplit[1], 10);
		iDay = parseInt(arrSplit[2], 10);
		
		if(iMonth >= 1 && iMonth <= 12) {
			if(iDay >= 1 && iDay <= this.GetDaysArray(iYear)[iMonth]) {
				bValid = true;
			}
		}
	}
	
	oRegExp = null;
	
	return bValid;
}

Validator.prototype.IsValidUsername = function (p_sUsr) {
	var re = /([a-zA-Z0-9]+)/;
	var iReturn = -1;

	str = p_sUsr;

	if (str != '')
	{
		if ( !str.match(re) || str.length < this.UsernameMinLength || str.length > this.UsernameMaxLength )
			iReturn = 0;
		else
			iReturn = 1;
	}

	return iReturn;
}

Validator.prototype.IsValidPassword = function (p_sPwd) {
	var bInvalid = false;
	
	var reDigit = /(\d+)/;
	var reLower = /([a-z]+)/;
	var reUpper = /([A-Z]+)/;
	var reSpace = /\s+/;

	var bFoundDigit = false;
	var bFoundLower = false;
	var bFoundUpper = false;
	
	var iReturn = -1;
	var str;

	str = p_sPwd;

	if (str != "")
	{
		bFoundDigit = str.match(reDigit);
		bFoundLower = str.match(reLower);
		bFoundUpper = str.match(reUpper);

		/* Length */
		if ( str.length < this.PasswordMinLength || str.length > this.PasswordMaxLength )
			bInvalid = true;

		/* Space */
		if ( str.match(reSpace) )
			bInvalid = true;
		
		/* Digit */
		if ( !bInvalid ) {
			if ( this.PasswordAllowDigit ) {
				if ( this.PasswordMinOneDigit ) {
					if ( !bFoundDigit )
						bInvalid = true;
				}
			}
			else {
				if ( bFoundDigit )
					bInvalid = true;
			}
		}
		
		/* Lower */
		if ( !bInvalid ) {
			if ( this.PasswordAllowLower ) {
				if ( this.PasswordMinOneLower ) {
					if ( !bFoundLower )
						bInvalid = true;
				}
			}
			else {
				if ( bFoundLower )
					bInvalid = true;
			}
		}
		
		/* Upper */
		if ( !bInvalid ) {
			if ( this.PasswordAllowUpper ) {
				if ( this.PasswordMinOneUpper ) {
					if ( !bFoundUpper )
						bInvalid = true;
				}
			}
			else {
				if ( bFoundUpper )
					bInvalid = true;
			}
		}

		if ( bInvalid )
			iReturn = 0;
		else
			iReturn = 1;
	}
	
	return iReturn;
}

Validator.prototype.IsStartDateLower = function (start, end) {
	if (start > end) return false;
	return true;
}

Validator.prototype.IsRangeInOneYear = function (start, end) {
	var diff  = new Date();
	var	timediff  = new Date();
	var days;

	diff.setTime(Math.abs(start.getTime() - end.getTime()));
	timediff = diff.getTime();
	days = Math.floor(timediff / (1000 * 60 * 60 * 24)); 
	timediff -= days * (1000 * 60 * 60 * 24);
	if (days > 365) return false;
	return true;
}

Validator.prototype.AreSameValue = function (p_value1, p_value2) {
	var iReturn = -1;
	
	if (document.getElementById)
	{
		var txtValue1 = document.getElementById(p_value1);
		var txtValue2 = document.getElementById(p_value2);
		
		if (txtValue1 != null && txtValue2 != null)
		{
			if (txtValue1.value == '' && txtValue2.value == '')
				iReturn = -1;
			else
				if ( (txtValue1.value == txtValue2.value) && (txtValue1.value != '' && txtValue2.value != '') )
					iReturn = 1;
				else
					iReturn = 0;
		}
	}
	
	return iReturn;
}

/********************************************************************
* Check Functions
********************************************************************/

Validator.prototype.CheckInteger = function (p_txtInteger, sMsg)
{
	var oRegexp = /^-?[0-9]+$/
	
	if (document.getElementById)
	{
		var txtInteger = document.getElementById(p_txtInteger);
		
		if (txtInteger != null)	
		{
			var s = txtInteger.value;
			
			if(!oRegexp.test(s))
				this.AddErrMsg(sMsg);
		}
	}
	
	oRegexp = null;
}

Validator.prototype.CheckIntegerRange = function (p_txtInteger, p_iLowerBound, p_iUpperBound, sMsg)
{
	var oRegexp = /^-?[0-9]+$/
	
	if (document.getElementById)
	{
		var txtInteger = document.getElementById(p_txtInteger);
		
		if (txtInteger != null)	
		{
			var s = txtInteger.value;
			
			if(!oRegexp.test(s)) {
				this.AddErrMsg(sMsg);
			}
			else if(!((parseInt(s, 10) >= p_iLowerBound || p_iLowerBound == null) && (parseInt(s, 10) <= p_iUpperBound || p_iUpperBound == null))) {
				this.AddErrMsg(sMsg);
			}
		}
	}
	
	oRegexp = null;
}

Validator.prototype.CheckFloat = function (p_txtFloat, sMsg) {
	
	if (document.getElementById)
	{
		var txtFloat = document.getElementById(p_txtFloat);
		
		if (txtFloat != null)	
		{
			var s = txtFloat.value;
			
			s = s.replace(",", ".");
			
			if (isNaN(s))
				this.AddErrMsg(sMsg);
			else
				txtFloat.value = s;
		}
	}
}

Validator.prototype.CheckPrice = function (p_txtPrice, sMsg) {
	
	if (document.getElementById)
	{
		var txtPrice = document.getElementById(p_txtPrice);
		
		if (txtPrice != null)	
		{
			var s = txtPrice.value;
			
			s = s.replace(",",".");
			
			if (isNaN(s))
				this.AddErrMsg(sMsg);
			else
				txtPrice.value = this.FormatCurrency(s);
		}
	}
}

Validator.prototype.CheckPhoneNumber = function (p_txtPhone, sMsg) {
	var str;
	var bool;
	
	if (document.getElementById)
	{
		var txtPhone = document.getElementById(p_txtPhone);
		if (txtPhone != null)	
		{
			str = txtPhone.value;
			bool = str.search(this.DefineRegexpPhoneNumber);
			if (bool != 0 && str != '')
			{
				this.AddErrMsg(sMsg);
				//document.getElementById(p_txtPhone).focus();
			}			
		}
	}
}

Validator.prototype.CheckWebColor = function (p_txtCode, sMsg) {
	var sRegEx = /[0-9A-F]{6}/gi;
	var str;
	var bool;
	
	if (document.getElementById)
	{
		var txtCode = document.getElementById(p_txtCode);
		if (txtCode != null)
		{
			str = txtCode.value;
			bool = str.search(this.DefineRegexpWebColor);
			if (bool != 0 && str != '')
			{
				this.AddErrMsg(sMsg);
				//txtCode.focus();
			}			
		}
	}
}

Validator.prototype.CheckUrl = function (p_txtEmail, sMsg) {
	var str;
	var bool;
	
	if (document.getElementById)
	{
		var txtEmail = document.getElementById(p_txtEmail);
		if (txtEmail != null)	
		{
			str = txtEmail.value;
			bool = str.search(this.DefineRegexpUrl);
			if (bool != 0 && str != '')
			{
				this.AddErrMsg(sMsg);
				//txtEmail.focus();
			}			
		}
	}
}

Validator.prototype.CheckEmail = function (p_txtEmail, sMsg) {
	var str;
	var bool;
	
	if (document.getElementById)
	{
		var txtEmail = document.getElementById(p_txtEmail);
		if (txtEmail != null)	
		{
			str = txtEmail.value;
			bool = str.search(this.DefineRegexpEmail);
			if (bool != 0 && str != '')
			{
				this.AddErrMsg(sMsg);
				//txtEmail.focus();
			}
		}
	}
}

Validator.prototype.CheckCanadianPostalCode = function (p_txtPostalCode, sMsg) {
	var str;
	var bool;
	
	if (document.getElementById)
	{
		var txtPostalCode = document.getElementById(p_txtPostalCode);
		if (txtPostalCode != null)	
		{
			str = txtPostalCode.value;
			bool = this.IsCanadianPostalCode(str);
			if (bool == false)
			{
				this.AddErrMsg(sMsg);
				//txtPostalCode.focus();
			}
		}
	}
}

Validator.prototype.CheckDate = function (p_txtDate, sMsg) {
	var str;
	var valid = false;
	
	if (document.getElementById)
	{
		var txtDate = document.getElementById(p_txtDate);
		if (txtDate != null)	
		{
			str = txtDate.value;
			
			valid = this.IsDate(str);
			if (!valid)
			{
				this.AddErrMsg(sMsg);
				//txtDate.focus();
			}
		}
	}
}

Validator.prototype.CheckFilename = function ( field, sMsg ) {
	var re = /^[A-Za-z0-9_-]+\.[A-Za-z0-9]+$/g;
	var sFilename = field.value;
	
	sFilename = sFilename.substring(sFilename.lastIndexOf('\\') + 1);
	
	if (re.test(sFilename) == false)
	{
		this.AddErrMsg(sMsg);
		//field.focus();
	}
}

Validator.prototype.CheckMaxLength = function (p_txtarea, p_maxlength, sMsg) {
	var bFck = false;
	
	if(typeof(FCKeditorAPI) != 'undefined'){
		if(FCKeditorAPI.GetInstance(p_txtarea)){
			if(FCKeditorAPI.GetInstance(p_txtarea).GetXHTML().length > p_maxlength){
				bFck = true;
				this.AddErrMsg(sMsg);
				//FCKeditorAPI.GetInstance(p_txtarea).Focus();
			}
		}
	}
	
	if(!bFck) {
		if (document.getElementById)
		{
			var field = document.getElementById(p_txtarea);
	
			if (field != null)
			{
				if (field.value.length > p_maxlength)
				{
					this.AddErrMsg(sMsg);
					if (field.type.toLowerCase() != 'hidden') {
						//field.focus();
					}
				}
			}
		}
	}
}

Validator.prototype.CheckUsername = function (p_txtUsr, sMsg) {
	if (document.getElementById)
	{
		var txtUsr = document.getElementById(p_txtUsr);
		if (txtUsr != null)
		{
			if (this.IsValidUsername(txtUsr.value) == 0)
			{
				this.AddErrMsg(sMsg);
				//document.getElementById(p_txtUsr).focus();
			}
		}
	}
}

Validator.prototype.CheckPassword = function (p_txtPwd, sMsg) {
	if (document.getElementById)
	{
		var txtPwd = document.getElementById(p_txtPwd);
		
		if (txtPwd != null)
		{
			if (this.IsValidPassword(txtPwd.value) == 0)
			{
				this.AddErrMsg(sMsg);
				//txtPwd.focus();
			}				
		}
	}
}

Validator.prototype.CheckDateRange = function (p_txtDate1, p_txtDate2, bCheckStartDateEndDate, sMsg) {

	var str1;
	var str2;
	var bool1;
	var bool2;
	var bool3;
	var bool4;
	
	if (document.getElementById)
	{
		var txtDate1 = document.getElementById(p_txtDate1);
		var txtDate2 = document.getElementById(p_txtDate2);
		if (txtDate1 != null && txtDate1.disabled != true && txtDate2 != null && txtDate2.disabled != true)	
		{
			str1 = txtDate1.value;
			bool1 = this.IsDate(str1);
			str2 = txtDate2.value;
			bool2 = this.IsDate(str2);
			bool3 = true;
			if (bCheckStartDateEndDate)
			{
				str1 = str1.replace('-','/');
				str1 = str1.replace('-','/');
				start = new Date(str1);
				
				str2 = str2.replace('-','/');
				str2 = str2.replace('-','/');
				end = new Date(str2);
				
				bool3 = this.IsStartDateLower(start, end);			
				bool4 = this.IsRangeInOneYear(start, end);				
			}
			if (bool1 == false || bool2 == false || bool3 == false || bool4 == false)
			{
				this.AddErrMsg(sMsg);
				//txtDate1.focus();
			}
		}
	}
}

/********************************************************************
* Utilities Functions
********************************************************************/

Validator.prototype.GetDaysInFebruary = function (year) {
	// February has 29 days in any year evenly divisible by four,
	// EXCEPT for centurial years which are not also divisible by 400.
	return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
}

Validator.prototype.GetDaysArray = function (iYear) {
	var arr = new Array();
	
	arr[1] = 31;
	arr[2] = this.GetDaysInFebruary (iYear);
	arr[3] = 31;
	arr[4] = 30;
	arr[5] = 31;
	arr[6] = 30;
	arr[7] = 31;
	arr[8] = 31;
	arr[9] = 30;
	arr[10] = 31;
	arr[11] = 30;
	arr[12] = 31;

	return arr;
}

Validator.prototype.StripCharsInBag = function (s, bag) {
	var i;
	var returnString = "";
	// Search through string's characters one by one.
	// If character is not in bag, append to returnString.
	for (i = 0; i < s.length; i++){   
		var c = s.charAt(i);
		if (bag.indexOf(c) == -1) returnString += c;
	}
	return returnString;
}

Validator.prototype.Trim = function (s)  {
	while (s.substring(0,1) == ' ')
	{
		s = s.substring(1, s.length);
	}
	while (s.substring(s.length-1, s.length) == ' ')
	{
		s = s.substring(0,s.length-1);
	}
	return s;
}

Validator.prototype.GetRandomNum = function (lbound, ubound) {
	return (Math.floor(Math.random() * (ubound - lbound)) + lbound);
}

Validator.prototype.GetRandomChar = function () {
	var numberChars = "0123456789";
	var lowerChars = "abcdefghijklmnopqrstuvwxyz";
	var upperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	
	var charSet = "";
	charSet += numberChars;
	charSet += lowerChars;
	charSet += upperChars;
	return charSet.charAt(this.GetRandomNum(0, charSet.length));
}

Validator.prototype.GetRandomPassword = function () {
	var rc;
	var pwd = '';
	var length = this.GetRandomNum(this.PasswordMinLength, this.PasswordMaxLength);
	
	do
	{
		rc = "";
		for (var idx = 0; idx < length; ++idx) {
			rc = rc + this.GetRandomChar();
		}
		pwd = rc;
	}
	while ( ! this.IsValidPassword(pwd) )
	
	return pwd;
}

Validator.prototype.FormatCurrency = function (num) {
	num = num.toString().replace(/\$|\,/g,'');
	if(isNaN(num))
	num = "0";
	sign = (num == (num = Math.abs(num)));
	num = Math.floor(num*100+0.50000000001);
	cents = num%100;
	num = Math.floor(num/100).toString();
	
	if(cents<10)
	cents = "0" + cents;
	
	for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
	num = num.substring(0,num.length-(4*i+3))+
	num.substring(num.length-(4*i+3));
	
	return (((sign)?'':'-') + num + '.' + cents);
}

Validator.prototype.GetCheckedValue = function (p_rdbtn) {
	var valReturn = '';

	if (document.getElementsByName)
	{
		var radiogroup = document.getElementsByName(p_rdbtn);
		if (radiogroup != null)
		{
			var length = radiogroup.length;
			if (length == 'undefined')
				valReturn = radiogroup.value
				
			for (var i=0; i<radiogroup.length ; i++)
			{
				if (radiogroup[i].checked)
					valReturn = radiogroup[i].value;
			}
		}
	}

	return valReturn;
}
