/**
 * Utils.js
 *
 * This file contains some useful Javascript functions.
 *
 * Authors: Houssam Fawaz - Luc Rivet
 */

//> whitespace characters
var whitespace = " \t\n\r";


/**
 * Trim leading spaces
 * 
 * @param Field value
 * 
 * @author Houssam Fawaz - houssam.fawaz@cognicase.com
 */
function trimLeadingSpaces(str) {
	while ('' + str.charAt(0) == ' ')
		str = str.substring(1,str.length);
	return str;
}

/**
 * Trim trailing spaces
 * 
 * @param Field value
 * 
 * @author Houssam Fawaz - houssam.fawaz@cognicase.com
 */
function trimTrailingSpaces(str) {
	while('' + str.charAt(str.length - 1) == ' ')
		str = str.substring(0,str.length-1);
	return str;
}

/**
 * Trim leading and trailing spaces
 * 
 * @param Field value
 * 
 * @author Houssam Fawaz - houssam.fawaz@cognicase.com
 */
function trimSpaces(str) {	
	return trimLeadingSpaces(trimTrailingSpaces(str));
}

/**
 * Trim leading and trailing spaces
 * 
 * @param Field value
 * @delim Special Character to remove
 * 
 * @author Houssam Fawaz - houssam.fawaz@cognicase.com
 */
function cleanString(field, delim) {
	while ('' + field.charAt(0) == delim)
		field = field.substring(1,field.length);
	
	while('' + field.charAt(field.length-1) == delim)
		field = field.substring(0,field.length-1);		
	
	return field;
}
 
/**
 * Check whether string is empty
 * 
 * @param Field value
 * 
 * @author Houssam Fawaz - houssam.fawaz@cognicase.com
 */
function isEmpty(s) {
	return ((s == null) || (s.length == 0))
}

/**
 * Returns true if string s is empty or whitespace characters only.
 * 
 * @param Field value
 * 
 * @author Houssam Fawaz - houssam.fawaz@cognicase.com
 */
function isWhiteSpace (s) {
	
	var i;

	// Is s empty?
	if (isEmpty(s)) return true;

	 // Check whitespaces
	for (i = 0; i < s.length; i++) {
		// Check that current character isn't whitespace.
		var c = s.charAt(i);
		if (whitespace.indexOf(c) == -1) return false;
	}

	return true;
}

/**
 * Display a message in an alert box
 * 
 * @param text value
 * 
 * @author Houssam Fawaz - houssam.fawaz@cognicase.com
 */
function showMessage(strMessage) {
    alert(strMessage);
}

/**
 * Check the validity of a postal code (A9A 9A9)
 * 
 * @param Field Object
 * 
 * @author Houssam Fawaz - houssam.fawaz@cognicase.com
 */
function isValidPostalCode(pCodeObj) {
	
	var pCodeValue = pCodeObj.value.toLowerCase();	
	
	var digitSet = "1234567890";
	var charSet  = "abcdefghijklmnopqrstuvwxyz";
	var mustBeDigit = true;
	
	if (pCodeValue.length == 7) {
		// Length is 7.  It must have a space in the middle
		if (pCodeValue.charAt(3) != ' ')
			return false;
		else // remove middle space
			pCodeValue = (pCodeValue.substring(0,3) + pCodeValue.substring(4,7));   
	} else if (pCodeValue.length != 6)
		return false;
	
	// Check each character
	for (var i=0;i<6;++i) {
		// togle between digit and alpha
		mustBeDigit = !mustBeDigit;		
		
		if (!mustBeDigit) {
			// Why is indexOf does not work on Netscape 2.01 ???. Lucky that lastIndexOf does work. 
			if (charSet.lastIndexOf(pCodeValue.charAt(i),charSet.length-1) == -1)				
				return 0;			
		} else if (digitSet.lastIndexOf(pCodeValue.charAt(i),digitSet.length-1) == -1)
		 	return 0;		
	}
	
	pCodeValue = pCodeValue.toUpperCase();
	pCodeObj.value = pCodeValue.substring(0,3) + ' ' + pCodeValue.substring(3,6);

	return true;
}


/**
 * Check the format of the social insurance number.
 * 
 * @param 's' is a string that represent the field (ex: document.formName.fieldName)
 *
 * Return true if the social insurance number is valid
 *
 * @author Stefanie Lamoureux - stefanie.lamoureux@sibn.bnc.ca
 */
function NAS_isValid(s)
{
     field_Nas = s.value;
     
     var txt = "";
     for (i=0; i<field_Nas.length; i++)
     {   if( !isNaN(field_Nas.charAt(i)) )
	     txt += field_Nas.charAt(i);
     }
	 	   
     if( txt.length==9 )
     {   
         DgtTot=0;
         for(cpt=0; cpt<8; cpt++)
         {   
  	     if( (cpt%2)==0 )
	     {
	         DgtTot += parseInt(txt.charAt(cpt));
	     }
	     else
	     {   if (txt.charAt(cpt)<5)
	             DgtTot += parseInt(txt.charAt(cpt)) *2 ;
	         else
	             DgtTot += (parseInt(txt.charAt(cpt)) *2 - 9 );
	     }
	 }   
	 if ( (10 - (DgtTot % 10))%10 != parseInt(txt.charAt(8)) )
	     return false;
	 else
	     return true;
      }
      else
      {   
	  return false;
      }      
}


/**
 * Check the format of the phone number 
 * 
 * @param 's' is a string that represent the field (ex: document.formName.fieldName.value)
 * 
 * Return true if the phone IS NOT valid ( not 111-1111 or 1111111 )
 *
 * @author Stefanie Lamoureux - stefanie.lamoureux@sibn.bnc.ca
 */
function phoneNotValid(s) {
	var txt = "";
	var valid = true;
	
	//> Checks if each character is in (0,9) or = "-" only!
	var isGood = false;
	for (j=0; j<s.length; j++) {
		if ( (s.charAt(j) >= 0 && s.charAt(j) <= 9) || (s.charAt(j) == '-') ) {
			isGood=true;
	    } else {
	    	isGood = false;
	    	return true;
	    }
	} 
	
	//> for each caracter of the string
	for (i=0; i<s.length; i++) {
		if (valid) {   //recover each caracter in a new string if it's a number
			if ( !isNaN(s.charAt(i)) ) {
	  	     txt += s.charAt(i);
			} else if (i!=3 && s.charAt(i) == '-') {
				return true;	     	
			}
		}
	}
     
    if( !valid || txt.length!=7 ) //> the phone number is not valid
        return true;
    else
        return false;
}


/**
 * Check if an input value is numeric
 * 
 * @param Field Value
 * 
 * @author Houssam Fawaz - houssam.fawaz@cognicase.com
 * @author Luc Rivet - luc.rivet@cognicase.com
 */
function isNumericValue(vValue) {
	var strNegative  	= "-";
	var strDecimal  	= ".";
	var strValid    	= "0123456789.";
	
	vValue = trimSpaces(vValue);

	var iNegativePos	= vValue.indexOf(strNegative);
	var iDecimalPos 	= vValue.indexOf(strDecimal);
	var iLastPos    	= vValue.length - 1;
	var iMaxDecimal 	= vValue.length - 3;
	
	if ( vValue == "" )
		return false;
	// Negation seulement
	if ( vValue == strNegative )
		return false;
	// Point decimal seulement
	if ( vValue == strDecimal )
		return false;


	var startLoop = 0;
	// To skip de negative char
	if ( iNegativePos == 0 ) {
		startLoop = 1;
	}

	for (j=startLoop;j<vValue.length;j++) {
		if (strValid.indexOf(vValue.charAt(j))==-1)
			return false;
	}

	if (iDecimalPos > -1) {
		if (iDecimalPos != vValue.lastIndexOf(strDecimal))
			return false;

		if (iDecimalPos >= 0 && iDecimalPos < iMaxDecimal)
			return false;
	}

	return true;
}

/**
 * Check if an input value is numeric
 * 
 * @param Field Value
 * 
 * @author Houssam Fawaz - houssam.fawaz@cognicase.com
 * @author Luc Rivet - luc.rivet@cognicase.com
 */
function isNumericValueNoDecimalLimit(vValue) {
	var strNegative  	= "-";
	var strDecimal  	= ".";
	var strValid    	= "0123456789.";

	vValue = trimSpaces(vValue);
		
	var iNegativePos	= vValue.indexOf(strNegative);
	var iDecimalPos 	= vValue.indexOf(strDecimal);
	var iLastPos    	= vValue.length - 1;
	var iMaxDecimal 	= vValue.length - 3;

	if (vValue == "")
		return false;
	// Negation seulement
	if ( vValue == strNegative )
		return false;
	// Point decimal seulement
	if ( vValue == strDecimal )
		return false;

	var startLoop = 0;
	// To skip de negative char
	if ( iNegativePos == 0 ) {
		startLoop = 1;
	}

	for (j=startLoop;j<vValue.length;j++) {
		if (strValid.indexOf(vValue.charAt(j))==-1)
			return false;
	}

	if (iDecimalPos > -1) {
		if (iDecimalPos != vValue.lastIndexOf(strDecimal))
			return false;
		
		//if (iDecimalPos >= 0 && iDecimalPos < iMaxDecimal)
		//	return false;
	}

	return true;
}

/**
 * Check if an input value is integer;
 * 
 * @param Field Value
 * 
 * @author Houssam Fawaz - houssam.fawaz@cognicase.com
 * @author Luc Rivet - luc.rivet@cognicase.com
 */
function isIntegerValue(vValue) {
	var strNegative  	= "-";
	var strValid    	= "0123456789";
	
	vValue = trimSpaces(vValue);
	
	var iNegativePos	= vValue.indexOf(strNegative);
	var iLastPos    	= vValue.length - 1;
	var iMaxDecimal 	= vValue.length - 3;

	if (vValue == "")
		return false;
	// Negation seulement
	if ( vValue == strNegative )
		return false;

	var startLoop = 0;
	// To skip de negative char
	if ( iNegativePos == 0 ) {
		startLoop = 1;
	}

	for (j=startLoop;j<vValue.length;j++) {
		if (strValid.indexOf(vValue.charAt(j))==-1)
			return false;
	}

	return true;
}

/**
 * Retourne si la valeur du champ est plus grand que 0.
 * 
 * @param Field Value
 * 
 * @author Luc Rivet - luc.rivet@cognicase.com
 */
function isGreatherThen0( vValue ) {	
	if ( vValue > 0 ) {
		return true;
	} else {
		return false;
	}
}


/**
 * Checks if a date is in the valid format : aaaa/mm/jj
 * 
 * @param Field Value
 * 
 * @author Houssam Fawaz - houssam.fawaz@cognicase.com
 */
function isDateValid(txtDate) {
	var strChar    = "";
	var strSep     = "/";
	var strValid   = "0123456789/";
	var iSepCount  = 0;
	var leap = 0;
	var iSepPos    = txtDate.indexOf(strSep);
	var iLastPos   = txtDate.length - 1;
	var iMaxSep    = txtDate.length - 3;

	var iYearCount  = 0;
	var iMonthCount  = 0;
	var iDayCount  = 0;

	var vYear  = "";
	var vMonth = "";
	var vDay  = "";
	
	if (txtDate.length < 10)
		return false;
		
	for (j=0;j<txtDate.length;j++) {
		strChar = txtDate.charAt(j);

		if (strValid.indexOf(strChar)==-1)
			return false;

		if (strChar == strSep)
			iSepCount += 1;
		else {
			if (iSepCount == 0) {
				iYearCount += 1;
			}
			else {
				if (iSepCount == 1)
					iMonthCount += 1;
				else
					iDayCount += 1;
			}
		}
	}


	if (iSepCount != 2)
		return false;

	if (iYearCount != 4 || iMonthCount == 0 || iMonthCount > 2 || iDayCount == 0 || iDayCount > 2)
		return false;


	var vStart = 0;
	var vEnd   = iYearCount;
	vYear  = txtDate.substring(vStart, vEnd);

	vStart = iYearCount + 1;
	vEnd   += (iMonthCount + 1);
	vMonth = txtDate.substring(vStart, vEnd);

	vStart = vEnd + 1;
	vEnd   += (iDayCount + 1);
	vDay   = txtDate.substring(vStart, vEnd);

	if (vMonth == 0 || vMonth > 12)	return false;

	if (vDay == 0)	return false;

	//> Validation leap-year / february / day	
	if ((vYear % 4 == 0) || (vYear % 100 == 0) || (vYear % 400 == 0)) {
		leap = 1;
	}

	if ( ( vYear < 1900 ) || ( vYear > 2050 )  ) {
		return false;
	}

	if ((vMonth == 2) && (leap == 1) && (vDay > 29)) {
		return false;
	}

	if ((vMonth == 2) && (leap != 1) && (vDay > 28)) {
		return false;
	}

	if ((vMonth == 4 || vMonth == 6 || vMonth == 9 || vMonth == 11) && vDay > 30)
		return false;
	else {
		if (vDay > 31) return false;
	}

	return true;
}

/**
 * Checks if a date is later than tha day's date
 * 
 * @param Field Value
 * 
 * @author Houssam Fawaz - houssam.fawaz@cognicase.com
 */
function isDateLaterDayDate(txtDate) {
	//> Get and format day's date as yyyymmdd
	var dayDate = new Date();
	var dayYear = dayDate.getYear();
	var dayMonth= dayDate.getMonth()+1;
	var dayDay  = dayDate.getDate();
	
	if (dayYear < 1900)	dayYear += 1900; 
	if (dayMonth < 10) dayMonth = "0" + dayMonth;
	if (dayDay < 10) dayDay = "0" + dayDay;
		
	var currDate= dayYear + dayMonth + dayDay; 
	
	if (isDateValid(txtDate)) {		
		//> Get and format input date as yyyymmdd
		var iSepPos = txtDate.indexOf("/");	
	
		var newDate = txtDate.substring(0,iSepPos); // Year
		txtDate = txtDate.substring(iSepPos+1, txtDate.length);
		iSepPos = txtDate.indexOf("/");	
	
		var month = txtDate.substring(0,iSepPos);
		if (month.length==1 && parseInt(month) < 10) month = "0" + month;		
		
		newDate += month;
	
		var day = txtDate.substring(iSepPos+1, txtDate.length);
		if (day.length==1 && parseInt(day) < 10) day = "0" + day;		
	
		newDate += day;
		
		if (newDate <= currDate)
			return false;
	} else
		return false;
	
	return true;
}

/**
 * Formats a currency..
 * 
 * @param vValue : Field Value
 * @param lang : locale value
 * 
 * @author Houssam Fawaz - houssam.fawaz@cognicase.com
 */
function formatCurrency(vValue, lang) {
	if (lang == "fr")
	   return vValue + " $";
	else
	   return "$ " + vValue;	
}

/**
 * Formater un nombre avec deux decimals.
 * 
 * @param	paramAmount		Le nombre a formater.
 * 
 * @return	- Retourne le format suivant xxxxxxx0.00
 * 			- Si monbre invalide, retourne "".
 * 
 * @author Luc Rivet - luc.rivet@cognicase.com
 */
function formatAmount( paramAmount ) {
	var stringMoney = paramAmount+"";

	if ( !isNaN( paramAmount ) && stringMoney != "" ) {

		money = paramAmount;
		money = "" + ( ( Math.round( money * 100 ) ) / 100 );
		dec = money.indexOf( "." );

		if ( dec != -1 ) {
			dollars = money.substring( 0, dec );
			cents = money.substring( dec+1, dec+3 );

			cents = ( cents.length < 2 ) ? cents + "0" : cents;
		} else {
			dollars = money;
			cents = "00"
		}
		money = dollars + "." + cents;
	} else {
		money = "";
	}

	return money;
}

/**
 * Checks if an email is in the valid format : name@domain_name.extension
 * 
 * @param vValue : Field Object
 * 
 * @author Houssam Fawaz - houssam.fawaz@cognicase.com
 */
 
 /**
 *function depreciee, cela est liee a un bogue lorsqu'on rentre une adresse d'email invalide de 60 caracteres
 */
/*function isEmailValid(txtEmail) {
	if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(txtEmail.value)) {
		return true;
	}
	
	return false;
}*/

function isEmailValid(txtEmail) 
	{
			emailStr = txtEmail.value;
			/* The following variable tells the rest of the function whether or not
			to verify that the address ends in a two-letter country or well-known
			TLD.  1 means check it, 0 means don't. */
			
			var checkTLD=1;
	
			/* The following pattern is used to check if the entered e-mail address
			fits the user@domain format.  It also is used to separate the username
			from the domain. */
			
			var emailPat=/^(.+)@(.+)$/;
			
			/* The following string represents the pattern for matching all special
			characters.  We don't want to allow special characters in the address. 
			These characters include ( ) < > @ , ; : \ " . [ ] */
			
			var specialChars="\\(\\)><@,;:\\\\\\\"\\.\\[\\]";
			
			/* The following string represents the range of characters allowed in a 
			username or domainname.  It really states which chars aren't allowed.*/
			
			var validChars="\[^\\s" + specialChars + "\]";
			
			/* The following pattern applies if the "user" is a quoted string (in
			which case, there are no rules about which characters are allowed
			and which aren't; anything goes).  E.g. "jiminy cricket"@disney.com
			is a legal e-mail address. */
			
			var quotedUser="(\"[^\"]*\")";
			
			/* The following pattern applies for domains that are IP addresses,
			rather than symbolic names.  E.g. joe@[123.124.233.4] is a legal
			e-mail address. NOTE: The square brackets are required. */
			
			var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;
			
			/* The following string represents an atom (basically a series of non-special characters.) */
			
			var atom=validChars + '+';
			
			/* The following string represents one word in the typical username.
			For example, in john.doe@somewhere.com, john and doe are words.
			Basically, a word is either an atom or quoted string. */
			
			var word="(" + atom + "|" + quotedUser + ")";
			
			// The following pattern describes the structure of the user
			
			var userPat=new RegExp("^" + word + "(\\." + word + ")*$");
			
			/* The following pattern describes the structure of a normal symbolic
			domain, as opposed to ipDomainPat, shown above. */
			
			var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");
			
			/* Finally, let's start trying to figure out if the supplied address is valid. */
			
			/* Begin with the coarse pattern to simply break up user@domain into
			different pieces that are easy to analyze. */
			
			var matchArray=emailStr.match(emailPat);
	
			if (matchArray==null) {
		
				/* Too many/few @'s or something; basically, this address doesn't
				even fit the general mould of a valid e-mail address. */
		
				return false;
			}
			var user=matchArray[1];
			var domain=matchArray[2];
			
			
			// See if "user" is valid 
			
			if (user.match(userPat)==null) 
			{ // user is not valid
			
				return false;
			}
			
			/* if the e-mail address is at an IP address (as opposed to a symbolic
			host name) make sure the IP address is valid. */
			
			var IPArray=domain.match(ipDomainPat);
			if (IPArray!=null) 
			{// this is an IP address
			
				for (var i=1;i<=4;i++) 
				{
					if (IPArray[i]>255) 
					{
						return false;
				    }
				}

			}
			
			// Domain is symbolic name.  Check if it's valid.
			var atomPat=new RegExp("^" + atom + "$");
			var domArr=domain.split(".");
			var len=domArr.length;
			
			for (i=0;i<len;i++) 
			{
				if (domArr[i].search(atomPat)==-1) 
				{
					return false;
				}
			}
				

			// Make sure there's a host name preceding the domain.
			if (len<2) 
			{
				return false;
			}		
			
			// If we've gotten this far, everything's valid!	
			return true;
		
	}


/* INPUT *********************************************************************/

/**
 * Assigner le focus sur le champ du formulaire recu en parametre.
 * <p />
 * La particularite avec cette fonction est que lorsque ce champ contient
 * plusieurs instances (radio ou checkbox), le focus est assigne sur la
 * premiere instance.  Comparativement a la methode .focus() qui ne traite
 * pas de cette particularitee.
 * 
 * @param	theField	L'objet (document.form.champ) du formulaire.
 * 
 * @author Luc Rivet - luc.rivet@cognicase.com
 */
function setFocus( theField ) {
	if ( theField.focus ) {
		theField.focus();
	} else {
		if ( theField[0].focus() ) {
			theField[0].focus();
		}
	}
}

/**
 * Retourner le type du champ du formulaire recu en parametre.
 * 
 * @param	theField	L'objet (document.form.champ) du formulaire.
 * 
 * @return	Le type du champ.
 * 
 * @author Luc Rivet - luc.rivet@cognicase.com
 */
function getFieldType( theField ) {
	if ( theField ) {
		if ( theField.type ){
			return theField.type;
		} else {
			if ( theField[0].type ) {
				return theField[0].type;
			}
		}
	}
	return "";
}

/**
 * Verifie si la liste de champ (recu sous forme d'objet; document.form.champ)
 * est vide.
 * 
 * @param	Liste d'objet (document.form.champ) recu du formulaire.
 *			Ex; if ( isFieldEmpty( document.form.champ1, document.form.champ2 ) ) { ...
 * 
 * @return	boolean	- Vrai si un des champs recu en parametre est vide.
 * 					- Faux si l'ensemble des champs recu en parametre ne sont pas vide.
 * 
 * @author Luc Rivet - luc.rivet@cognicase.com
 */
function isFieldEmpty( ) {
	var empty = 0;
	var theField;
	var theFieldType;

	for ( var i=0; i < isFieldEmpty.arguments.length; i++ ) {
		theField = isFieldEmpty.arguments[i];
		theFieldType = getFieldType( theField );

		// SELEC-ONE
		if ( theFieldType == "select-one" ) {
			empty = isSelectEmpty( theField );
		}
		// RADIO
		if ( theFieldType == "radio" ) {
			empty = isRadioEmpty( theField );
		}
		// CHECKBOX
		if ( theFieldType == "checkbox" ){
			empty = isCheckboxEmpty( theField );
		}
		// TEXT/HIDDEN/PASSWORD/TEXTAREA
		if ( ( theFieldType == "text" ) || ( theFieldType == "hidden" ) || ( theFieldType == "password" ) || ( theFieldType == "textarea" ) ) {
			empty = isTextEmpty( theField );
		}

		// Si le champs est vide, faire ce qui suit
		if ( empty ) {
			return true;
		}
	}
	return false;
}
function isSelectEmpty( thisSelect ) {
	if ( thisSelect.options[thisSelect.selectedIndex].value != "" ) {
		return false;
	}
	return true;
}
function isRadioEmpty( thisRadio ) {
	for ( i=0; i< thisRadio.length; i++ ){
		if ( thisRadio[i].checked ) {
			return false;
		}
	}
	return true;
}
function isCheckboxEmpty( thisCheckbox ){
	for ( i=0; i < thisCheckbox.length; i++ ){
		if ( thisCheckbox[i].checked ){
			return false;
		}
	}
	return true;
}
function isTextEmpty( theText ){
	if ( theText.value != "" ) {
		return false;
	}
	return true;
}

/**
 * Retourner la valeur du champ du formulaire recu en parametre.
 * <p />
 * Les objets de type checkbox et select MULTIPLE ne sont pas traites.
 * 
 * @param	theField	L'objet (document.form.champ) du formulaire.
 * 
 * @return	La valeur du champ.
 * 
 * @author Luc Rivet - luc.rivet@cognicase.com
 */
function getFieldValue( theField ){

	theFieldType = getFieldType( theField );

	// SELEC-ONE
	if ( theFieldType == "select-one" ) {
		return getSelectValue( theField );
	}
	// RADIO
	if ( theFieldType == "radio" ) {
		return getRadioValue( theField );
	}
	// CHECKBOX
//	if ( theFieldType == "checkbox" ) {
//		return theField.value;
//	}
	// TEXT/HIDDEN/PASSWORD/TEXTAREA
	if ( ( theFieldType == "text" ) || ( theFieldType == "hidden" ) || ( theFieldType == "password" ) || ( theFieldType == "textarea" ) ) {
		return theField.value;
	}
	return "";
}
function getSelectValue( thisSelect ){
	return thisSelect.options[thisSelect.selectedIndex].value;
}
function getSelectText( thisSelect ){
	return thisSelect.options[thisSelect.selectedIndex].text;
}
function getRadioValue( thisRadio ){
	for ( i=0; i< thisRadio.length; i++ ){
		if ( thisRadio[i].checked ){
			return thisRadio[i].value;
		}
	}
	return "";
}

/**
 * Retourner l'index du radio CHECKED.
 * 
 * @param	thisRadio	L'objet (document.form.radio) du formulaire.
 * 
 * @return	- L'index du radio CHECKED : si un des radio est CHECKED.
 * 			- "" : si aucun des radio est CHECKED.
 * 
 * @author Luc Rivet - luc.rivet@cognicase.com
 */
function getRadioChecked( thisRadio ){
	for ( i=0; i< thisRadio.length; i++ ){
		if ( thisRadio[i].checked ){
			return i;
		}
	}
	return "";
}

/**
 * Assigne les valeurs vides a liste de champ recu en parametre.
 * <p />
 * Les objets de type select MULTIPLE ne sont pas traites.
 * 
 * @param	Liste d'objet (document.form.champ) recu du formulaire.
 *			Ex; if ( setFieldEmpty( document.form.champ1, document.form.champ2 ) ) { ...
 * 
 * @author Luc Rivet - luc.rivet@cognicase.com
 */
function setFieldEmpty() {
	for ( var i = 0; i < setFieldEmpty.arguments.length; i++ ) {

		theField = setFieldEmpty.arguments[i];
		theFieldType = getFieldType(theField);

		// SELEC-ONE
		if ( theFieldType == "select-one" ) {
			theField.options[0].selected = true;
		}
		// RADIO
		if ( theFieldType == "radio" ) {
			setAllRadioNotChecked( theField );
		}
		// CHECKBOX
		if ( theFieldType == "checkbox" ){
			setAllCheckboxNotChechek( theField );
		}
		// TEXT/HIDDEN/PASSWORD/TEXTAREA
		if ( ( theFieldType == "text" ) || ( theFieldType == "hidden" ) || ( theFieldType == "password" ) || ( theFieldType == "textarea" ) ) {
			theField.value = "";
		}
	}
}
function setAllRadioNotChecked() {
	for ( var i = 0; i < setAllRadioNotChecked.arguments.length; i++ ){
		thisRadio = setAllRadioNotChecked.arguments[i];

		for ( j = 0; j < thisRadio.length; j++ ){
			thisRadio[j].checked = false;
		}
	}
}
function setAllCheckboxNotChechek() {
	for ( var i = 0; i < setAllCheckboxNotChechek.arguments.length; i++ ){
		thisCheckbox = setAllCheckboxNotChechek.arguments[i];

		for ( i=0; i < thisCheckbox.length; i++ ){
			thisCheckbox[i].checked = false;
		}
	}
}


/* SELECT ********************************************************************/

/**
 * Retourner le nombre d'option SELECTED dans un select de type MULTIPLE.
 * 
 * @param	theSelect	L'objet (document.form.select) du formulaire.
 * 
 * @return	Nombre d'option SELECTED dans un select MULTIPLE.
 * 
 * @author Luc Rivet - luc.rivet@cognicase.com
 */
function getCountSelected( theSelect ) {
	var countSelected = 0;

	for ( var i = theSelect.options.length - 1; i >= 0; i-- ) {
		if ( theSelect.options[i].selected ) {
			countSelected = countSelected + 1;
		}
	}
	return countSelected;
}

/**
 * Assigner le boolean "theSelectedValue" a la propriete SELECTED de chacune
 * des options de l'objet theSelect recu en parametre.
 * 
 * @param	theSelect			L'objet (document.form.select) du formulaire.
 * @param	theSelectedValue	Valeur prise par l'ensemble des proprietes
 * 								SELECTED du select recu en parametre.
 * 
 * @author Luc Rivet - luc.rivet@cognicase.com
 */
function setAllSelectSelected( theSelect, theSelectedValue ) {
	for ( var j = theSelect.options.length - 1; j >= 0; j-- ) {
		theSelect.options[j].selected = theSelectedValue;
	}
}

/**
 * Manipuler deux select de type MULTIPLE et d'echanger des OPTIONS
 * de un a l'autre.
 * <p />
 * Les options SELECTED du select d'origine seront tranferes vers le select de
 * sorti.
 * 
 * @param	fromSelect			L'objet (document.form.select) d'origine.
 * @param	toSelect			L'objet (document.form.select) de sorti.
 * @param	all					Indique d'envoyer tout les options du select
 * 								d'origine au select de sorti.
 * 
 * @author Luc Rivet - luc.rivet@cognicase.com
 */
function moveOptionFromSelectToSelect( fromSelect, toSelect, all ) {
	var i;

	for( i = fromSelect.options.length - 1; i >= 0; i-- ) {
		if ( ( fromSelect.options[i].selected == true ) || ( all ) ) {
			var nouvelleOption = new Option( fromSelect.options[i].text, fromSelect.options[i].value );
			toSelect.options[toSelect.length] = nouvelleOption;
			toSelect.selectedIndex = toSelect.length - 1;
			fromSelect.options[i] = null;
		}
	}
}

/**
 * Supprimer l'ensemble des options des select recu en parametre.
 * 
 * @param	Liste d'objet (document.form.select) recu du formulaire.
 *			Ex; if ( deleteAllOptionSelect( document.form.select1, document.form.select2 ) ) { ...
 * 
 * @author Luc Rivet - luc.rivet@cognicase.com
 */
function deleteAllOptionSelect() {
	var i;

	for ( var i = 0; i < deleteAllOptionSelect.arguments.length; i++ ){
		thisSelect = deleteAllOptionSelect.arguments[i];

		for ( j = thisSelect.options.length - 1; j >= 0; j-- ) {
			thisSelect.options[j] = null;
		}
	}
}

/**
 * Supprimer les options des select recu en parametre dont leurs valeurs sont
 * "".
 * 
 * @param	Liste d'objet (document.form.select) recu du formulaire.
 *			Ex; if ( deleteEmptySelect( document.form.select1, document.form.select2 ) ) { ...
 * 
 * @author Luc Rivet - luc.rivet@cognicase.com
 */
function deleteEmptySelect() {
	var i;

	for ( var i = 0; i < deleteEmptySelect.arguments.length; i++ ){
		thisSelect = deleteEmptySelect.arguments[i];
		//enlever les blancs
		for ( j = thisSelect.options.length - 1; j >= 0; j-- ) {
			if ( thisSelect.options[j].value == "" ) {
				thisSelect.options[j] = null;
			}
		}
	}
}

/**
 * Opens a new customized window with a specified URL
 * @author Houssam Fawaz - houssam.fawaz@cognicase.com
 */
function openWin(url, width, height) {
	var winName; // New window name
	var params;  // Defines the new window parameters
	var winObj;  // New window object

	winName = "content";

	params  = "toolbar=0,";
	params += "location=0,";
	params += "directories=0,";
	params += "status=0,";
	params += "menubar=0,";
	params += "scrollbars=1,";
	params += "resizable=0,";
	params += "width="+width+",";
	params += "height="+height;

	winObj = window.open(url, winName, params);
}

/**
 * Validates a Client Card Number 
 */
function validClientCard(fld) {
	txt=fld.value;
	txt2="5002359";
	for (i=0;i<txt.length;i++)
		if ( !isNaN(txt.charAt(i))) txt2+=txt.charAt(i);
	
	if (txt2.length!=19) {
		//alert(msgErrNumeric);
		return false;
	}
	else
	{
		DgtTot=0;
		for (cpt1=0; cpt1<18; cpt1++)
		{
			if ((cpt1%2)==0)
				DgtTot += parseInt(txt2.charAt(cpt1));
			else
			{
				if (txt2.charAt(cpt1)<5)
					DgtTot += parseInt(txt2.charAt(cpt1)) *2 ;
				else
					DgtTot += (parseInt(txt2.charAt(cpt1)) *2 - 9 );
			}
		}
		if ( (10 - (DgtTot % 10))%10 != parseInt(txt2.charAt(18)) ) {
			//alert(msgErrInvalid);
			return false;
		}
	}
	
	return true;
}

/**
 * Validates a password
 */
function validPassword(fld) {
	txt=fld.value;
	dgt=0;let=0,oth=0;
	
	for (i=0;i<txt.length;i++) {
		if ( !isNaN(txt.charAt(i)) ) dgt++;
		else {
			if ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(txt.charAt(i))==-1)
				oth++;
			else 
				let++;
		}		
	}	

	if (txt.length!=8 || let==0 || dgt==0 || oth>0 ) {
		return false;			
	}
	
	return true;
}

/**
 * Pop up the browser print window
 * 
 * @author Houssam Fawaz - houssam.fawaz@cognicase.com
 */
function printWindow() {
	window.print();
}

/**
 *Copyright Microsoft (C)
 **/
 var Page_IsValid = true;
var Page_BlockSubmit = false;

function ValidatorUpdateDisplay(val) {
    if (typeof(val.display) == "string") {    
        if (val.display == "None") {
            return;
        }
        if (val.display == "Dynamic") {
            val.style.display = val.isvalid ? "none" : "inline";
            return;
        }
    }
    val.style.visibility = val.isvalid ? "hidden" : "visible";
}

function ValidatorUpdateIsValid() {
    var i;
    for (i = 0; i < myValidators.length; i++) {
        if (!myValidators[i].isvalid) {
            Page_IsValid = false;
            return;
        }
   }
   Page_IsValid = true;
}

function ValidatorHookupControlID(controlID, val) {
    if (typeof(controlID) != "string") {
        return;
    }
    var ctrl = document.all[controlID];
    if (typeof(ctrl) != "undefined") {
        ValidatorHookupControl(ctrl, val);
    }
    else {
        val.isvalid = true;
        val.enabled = false;
    }
}

function ValidatorHookupControl(control, val) {
    if (typeof(control.tagName) == "undefined" && typeof(control.length) == "number") {
        var i;
        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") {
        var i;
        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(); " + ev);
            if (control.type == "radio") {
                control.onclick = func;
            } else {            
                control.onchange = func;
            }

        }
        control.Validators[control.Validators.length] = val;
    }    
}

function ValidatorGetValue(id) {
    var control;
    control = document.all[id];
    if (typeof(control.value) == "string") {
        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.status == true)) {
                return inner.value;
            }
        }
    }
    else {
        return ValidatorGetValueRecursive(control);
    }
    return "";
}

function ValidatorGetControl(id) 
{
    var control;
    control = document.all[id];
    return control;
}

function ValidatorGetValueRecursive(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() {
    var i;
    for (i = 0; i < myValidators.length; i++) {
        ValidatorValidate(myValidators[i]);
    }
    ValidatorUpdateIsValid();    
    ValidationSummaryOnSubmit();
    Page_BlockSubmit = !Page_IsValid;
    return Page_IsValid;
}

function ValidatorCommonOnSubmit() {
    event.returnValue = !Page_BlockSubmit;
    Page_BlockSubmit = false;
}

function ValidatorEnable(val, enable) {
    val.enabled = (enable != false);
    ValidatorValidate(val);
    ValidatorUpdateIsValid();
}

function ValidatorOnChange() {
    var vals = event.srcElement.Validators;
    var i;
    for (i = 0; i < vals.length; i++) {
        ValidatorValidate(vals[i]);
    }
    ValidatorUpdateIsValid();    
}

function ValidatorValidate(val) {    
    val.isvalid = true;
    if (val.enabled != false) {
        if (typeof(val.evaluationfunction) == "function") {            
            val.isvalid = val.evaluationfunction(val); 
        }
    }
    ValidatorUpdateDisplay(val);
}

function ValidatorOnLoad() {
    if (typeof(myValidators) == "undefined")
        return;

    var i, val;
    for (i = 0; i < myValidators.length; i++) {
        val = myValidators[i];
        if (typeof(val.evaluationfunction) == "string") {
            eval("val.evaluationfunction = " + val.evaluationfunction + ";");
        }
        if (typeof(val.isvalid) == "string") {
            if (val.isvalid == "False") {
                val.isvalid = false;                                
                Page_IsValid = false;
            } 
            else {
                val.isvalid = true;
            }
        } else {
            val.isvalid = true;
        }
        if (typeof(val.enabled) == "string") {
            val.enabled = (val.enabled != "False");
        }
        
        ValidatorHookupControlID(val.controltovalidate, val);
        ValidatorHookupControlID(val.controlhookup, val);
    }
    Page_ValidationActive = true;
}

function ValidatorOnLoad() {
    if (typeof(myValidators) == "undefined")
        return;

    var i, val;
    for (i = 0; i < myValidators.length; i++) {
        val = myValidators[i];
        if (typeof(val.evaluationfunction) == "string") {
            eval("val.evaluationfunction = " + val.evaluationfunction + ";");
        }
        if (typeof(val.isvalid) == "string") {
            if (val.isvalid == "False") {
                val.isvalid = false;                                
                Page_IsValid = false;
            } 
            else {
                val.isvalid = true;
            }
        } else {
            val.isvalid = true;
        }
        if (typeof(val.enabled) == "string") {
            val.enabled = (val.enabled != "False");
        }
        
        ValidatorHookupControlID(val.controltovalidate, val);
        ValidatorHookupControlID(val.controlhookup, val);
    }
    Page_ValidationActive = true;
}

function ValidatorTrim(s) {
    var m = s.match(/^\s*(\S+(\s+\S+)*)\s*$/);
    return (m == null) ? "" : m[1];
}

function EvaluateIFIsIntegerWithOptionalVal(val) {
    	var value = ValidatorGetValue(val.controltovalidate);
    	var strNegative  	= "-";
	var strValid    	= "0123456789";
	
	vValue = trimSpaces(value);
	
	var iNegativePos	= vValue.indexOf(strNegative);
	var iLastPos    	= vValue.length - 1;
	var iMaxDecimal 	= vValue.length - 3;

	if (vValue == "")
		return true;
	// Negation seulement
	if ( vValue == strNegative )
		return false;

	var startLoop = 0;
	// To skip de negative char
	if ( iNegativePos == 0 ) {
		startLoop = 1;
	}

	for (j=startLoop;j<vValue.length;j++) {
		if (strValid.indexOf(vValue.charAt(j))==-1)
			return false;
	}

	return true;
}

/* Version Proxy validation immediate */
function EvaluateIFIsValidPostalCode(val) {
	
    	return(isValidPostalCode(ValidatorGetControl(val.controltovalidate)));    	
}

/* Version Proxy validation immediate */
function EvaluateIFNAS_isValid(val) {
	return(NAS_isValid(ValidatorGetControl(val.controltovalidate)));
    
}

/* Version Proxy validation immediate */
function EvaluateIFNAS_isValid_Optional(val) {
	var valueIn = ValidatorGetValue(val.controltovalidate);
	if( valueIn == "" )
		return true;
	return(NAS_isValid(ValidatorGetControl(val.controltovalidate)));
    
}

function EvaluateIFisEmailValid_Optional(val) {
	var valueIn = ValidatorGetValue(val.controltovalidate);
	if( valueIn == "" )
		return true;
	return(isEmailValid(ValidatorGetControl(val.controltovalidate)));
    
}

function EvaluateIFisDateValid(val) {
	var valueIn = ValidatorGetValue(val.controltovalidate);
	return(isDateValid(valueIn));
    
}

function EvaluateIFisNumericValue_Optional(val){
	var valueIn = ValidatorGetValue(val.controltovalidate);
	if( valueIn == "" )
		return true;
	if(isNumericValue(valueIn))
	{   if (valueIn >= 0)
			return true;
	}
	return false;
    
}
/* Version Proxy validation immediate */
function EvaluateIFIsValidPostalCode_Optionnal(val) {
	var valueIn = ValidatorGetValue(val.controltovalidate);
	if( valueIn == "" )
		return true;
  	return(isValidPostalCode(ValidatorGetControl(val.controltovalidate)));    	
}
function EvaluateIFisDateValid_Optionnal(val) {
	var valueIn = ValidatorGetValue(val.controltovalidate);
	if( valueIn == "" )
		return true;
	return(isDateValid(valueIn));
    
}

function isFormatDDMMYYYY(val)
{
	var day = "";
	var month = "";
	var year = "";
	if(val.length==8)
	{
		day = val.substring(0,2);
		month = val.substring(2,4);
		year =val.substring(4,8);
		if(isIntegerValue(day) && isIntegerValue(month) && isIntegerValue(year))
		{
			if(isDateValid(year+"/"+month+"/"+day))
			{
				return true;
			}
		}
	}
	return false;
}

function isFormatYYYYMMDD(val)
{
	var day = "";
	var month = "";
	var year = "";
	if(val.length==8)
	{
		year =val.substring(0,4);
		month = val.substring(4,6);
		day = val.substring(6,8);

		if(isIntegerValue(day) && isIntegerValue(month) && isIntegerValue(year))
		{
			if(isDateValid(year+"/"+month+"/"+day))
			{
				return true;
			}
		}
	}
	return false;
}	

function isFormatMMYYYY(val) {
	var month = "";
	var year = "";
	if(val.length==6) {
		month = val.substring(0,2);
		year = val.substring(2,6);
		if(isIntegerValue(month) && isIntegerValue(year)) {
			if((month >= 1) && (month <= 12) && (year>=1000)) {
				return true;
			}
		}
	}
	return false;
}
	
function isFormatYYYY(val) {
	var year = "";
	if(val.length==4) {
		year = val;
		if(isIntegerValue(year)) {
			if(year>=1000) {
				return true;
			}
		}
	}
	return false;
}

function ageOfPerson(val)
{
	var nbYears = 0;
	var day = "";
	var month = "";
	var year = "";
	var currentDay = "";
	var currentMonth = "";
	var currentYear = "";
	if (isFormatDDMMYYYY(val))
	{
		today = new Date();
		currentYear = today.getFullYear();
		currentMonth = today.getMonth() + 1;
		currentDay = today.getDate();

		day = val.substring(0,2);
		month = val.substring(2,4);
		year = val.substring(4,8);

		nbYears = (currentYear - year);

		if (currentMonth < month)
		{
			nbYears = nbYears - 1;
		}
		if (currentMonth == month)
		{
			if (currentDay < day)
			{
				if (currentMonth == 2)
				{
					if (((currentYear % 4 == 0) && (currentYear % 100 != 0)) || (currentYear % 400 == 0)) {
						nbYears = nbYears - 1;
					}
					else
					{
						if (currentDay < 28) {
							nbYears = nbYears - 1;
						}
					}
				}
				else
				{
					nbYears = nbYears - 1;
				}
			}
		}
	}
	else
	{
		nbYears = -1;
	}
	return nbYears;
}

function nbYearsSinceDate(val)
{
	var nbYears = 0;
	var month = "";
	var year = "";
	var currentMonth = "";
	var currentYear = "";
	if (isFormatMMYYYY(val))
	{
		today = new Date();
		currentYear = today.getFullYear();
		currentMonth = today.getMonth() + 1;
		month = val.substring(0,2);
		year = val.substring(2,6);
		nbYears = (currentYear - year);
		if (currentMonth < month)
		{
			nbYears = nbYears - 1;
		}
	}
	return nbYears;
}

/***************************************************************
* Desactive le bouton Enter
* A utiliser pour les Input Boxes pour switcher d'un a un autre
* quand le user pese sur Enter
****************************************************************/                
function handleEnter (field, event) {
		var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
		if (keyCode == 13) {
			var i;
			for (i = 0; i < field.form.elements.length; i++)
				if (field == field.form.elements[i])
					break;
			i = (i + 1) % field.form.elements.length;
			field.form.elements[i].focus();
			return false;
		} 
		else
		return true;
}      

/***************************************************************
* Desactive le bouton Enter
* A utiliser lorsque on veut desactiver le focntionnement 
* du bouton Enter
****************************************************************/                
function disactivateEnter (field, event) {
		var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
		if (keyCode == 13) {
	return false;
		} 
		else
		return true;
}      
