/*---------------------------------------------------------------------------------------------------------------------
###INDEX OF FUNCTIONS###
(in order as they appear in this document)
(please keep them in the alphabetic order)

~~~CHECK FUNCTIONS~~~
(boolean return)
checkPostalCode (Object field)           ->Check for a Zip/Postal code in the format X9X X9X OR 5 to 9 digits; the function is not case sensitif and can accept any spaces between characters (but the field's length should be limited). This function also check for a parital postal code that must be at least 2 characters of a valid postal code
validationPostalCode(String code)        ->Validate a Zip/Postal code in the format X9X X9X OR 5 to 9 digits; the function is not case sensitif and can accept any spaces between characters (but the field's length should be limited)
validationPartialPostalCode(String code) ->Validate a partial Zip/Postal code with a minimum of 2 characters in the format X9X X9X OR 5 to 9 digits; the function is not case sensitif and can accept any spaces between characters (but the field's length should be limited)
isNonnegativeInteger (s [,eok])          ->True if string s is an integer >= 0.
isSignedInteger (s [,eok])               ->True if all characters in string s are numbers; leading + or - allowed.
isInteger (s [,eok])                     ->True if all characters in string s are numbers.
isDigit (c)                              ->Check whether character c is a digit.
isEmpty (s)                              ->Check whether a string is empty.
isLetter (c)				                     ->Check whether character c is an English letter
isAlphabetic (s [,eok])		               ->True if string s is English letters
---------------------------------------------------------------------------------------------------------------------*/

// Global variable defaultEmptyOK defines default return value
// for many functions when they are passed the empty string.
// By default, they will return defaultEmptyOK.
//
// defaultEmptyOK is false, which means that by default,
// these functions will do "strict" validation.  Function
// isInteger, for example, will only return true if it is
// passed a string containing an integer; if it is passed
// the empty string, it will return false.
//
// You can change this default behavior globally (for all
// functions which use defaultEmptyOK) by changing the value
// of defaultEmptyOK.
//
// Most of these functions have an optional argument emptyOK
// which allows you to override the default behavior for
// the duration of a function call.
//
// This functionality is useful because it is possible to
// say "if the user puts anything in this field, it must
// be an integer (or a phone number, or a string, etc.),
// but it's OK to leave the field empty too."
// This is the case for fields which are optional but which
// must have a certain kind of content if filled in.

var defaultEmptyOK = false

//Check for a Zip/Postal code in the format X9X X9X OR 5 to 9 digits; the function is not case sensitif and can accept any spaces between characters (but the field's length should be limited)
//This function also check for a parital postal code that must be at least 2 characters of a valid postal code

function checkPostalCode(field)
{
  var CANPattern = /[A-z]/;
  var codetest = field.value.substring(0,1);
  field.value = field.value.replace(/\s/g,"");
  var canadien = CANPattern.test(codetest);
  var partialCode = false;

//if (!canadien)
//   return false;
//if ((canadien && field.value.length < 6) ||
//    (canadien==false && field.value.length < 5))
//  partialCode = true;

  if (!canadien)
     return false;
  if (field.value.length < 6)
     partialCode = true;

  if(field.value!="" && field.value.length<2)
  {
    return false;
  }

  if((field.value!="" && partialCode==false && validationPostalCode(field.value)==false)||
     (field.value!="" && partialCode && validationPartialPostalCode(field.value)==false))
  {
    return false;
  }
  else
  {
    return true;
  }
}

//Validate a Zip/Postal code in the format X9X X9X OR 5 to 9 digits; the function is not case sensitif and can accept any spaces between characters (but the field's length should be limited)
function validationPostalCode(code)
{
  var CANPattern = /[A-z]\d[A-z]\d[A-z]\d/;
  code = code.replace(/\s/g,"");
  return ((CANPattern.test(code) && code.length == 6) || (isNonnegativeInteger(code) && code.length >= 5 && code.length <= 9));
}


// Validate a partial Zip/Postal code with a one of the formats: 999999999, X9X or X9XX9X
// The function is not case sensitive
function validationPartialPostalCode(code)
{
  var valideCAN = false;

  code = code.replace(/\s/g,"");
  switch(code.length)
  {
//   case 2:
//     var CANPattern = /[A-z]\d/;
//     valideCAN = CANPattern.test(code);
//     break;
    case 3:
      var CANPattern = /[A-z]\d[A-z]/;
      valideCAN = CANPattern.test(code);
      break;
//   case 4:
//     var CANPattern = /[A-z]\d[A-z]\d/;
//     valideCAN = CANPattern.test(code);
//     break;
//   case 5:
//     var CANPattern = /[A-z]\d[A-z]\d[A-z]/;
//     valideCAN = CANPattern.test(code);
//     break;
    case 6:
      var CANPattern = /[A-z]\d[A-z]\d[A-z]\d/;
      valideCAN = CANPattern.test(code);
      break;
    default:
      valideCAN = false;
  }

  return (valideCAN || (isNonnegativeInteger(code) && code.length >= 2 && code.length <= 9));
}


// isNonnegativeInteger (STRING s [, BOOLEAN emptyOK])
//
// Returns true if string s is an integer >= 0.
//
// For explanation of optional argument emptyOK,
// see comments of function isInteger.

function isNonnegativeInteger (s)
{   var secondArg = defaultEmptyOK;

    if (isNonnegativeInteger.arguments.length > 1)
     secondArg = isNonnegativeInteger.arguments[1];

    // The next line is a bit byzantine.  What it means is:
    // a) s must be a signed integer, AND
    // b) one of the following must be true:
    //  i)  s is empty and we are supposed to return true for
    //      empty strings
    //  ii) this is a number >= 0

    return (isSignedInteger(s, secondArg)
      && ( (isEmpty(s) && secondArg)  || (parseFloat (s) >= 0) ) );
}


// isSignedInteger (STRING s [, BOOLEAN emptyOK])
//
// Returns true if all characters are numbers;
// first character is allowed to be + or - as well.
//
// Does not accept floating point, exponential notation, etc.
//
// We don't use parseInt because that would accept a string
// with trailing non-numeric characters.
//
// For explanation of optional argument emptyOK,
// see comments of function isInteger.
//
// EXAMPLE FUNCTION CALL:   RESULT:
// isSignedInteger ("5")    true
// isSignedInteger ("")     defaultEmptyOK
// isSignedInteger ("-5")   true
// isSignedInteger ("+5")   true
// isSignedInteger ("", false)  false
// isSignedInteger ("", true)   true

function isSignedInteger (s)
{
	  if (isEmpty(s))
      if (isSignedInteger.arguments.length == 1)
        return defaultEmptyOK;
      else
      	return (isSignedInteger.arguments[1] == true);

    else {
     var startPos = 0;
     var secondArg = defaultEmptyOK;

     if (isSignedInteger.arguments.length > 1)
      secondArg = isSignedInteger.arguments[1];

     // skip leading + or -
     if ( (s.charAt(0) == "-") || (s.charAt(0) == "+") )
     startPos = 1;
     return (isInteger(s.substring(startPos, s.length), secondArg))
    }
}


// isInteger (STRING s [, BOOLEAN emptyOK])
//
// Returns true if all characters in string s are numbers.
//
// Accepts non-signed integers only. Does not accept floating
// point, exponential notation, etc.
//
// We don't use parseInt because that would accept a string
// with trailing non-numeric characters.
//
// By default, returns defaultEmptyOK if s is empty.
// There is an optional second argument called emptyOK.
// emptyOK is used to override for a single function call
//     the default behavior which is specified globally by
//     defaultEmptyOK.
// If emptyOK is false (or any value other than true),
//     the function will return false if s is empty.
// If emptyOK is true, the function will return true if s is empty.
//
// EXAMPLE FUNCTION CALL: RESULT:
// isInteger ("5")      true
// isInteger ("")     defaultEmptyOK
// isInteger ("-5")     false
// isInteger ("", true)   true
// isInteger ("", false)  false
// isInteger ("5", false) true

function isInteger (s)
{
	  var i;

    if (isEmpty(s))
    if (isInteger.arguments.length == 1) return defaultEmptyOK;
    else return (isInteger.arguments[1] == true);

    // Search through string's characters one by one
    // until we find a non-numeric character.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++)
    {
     // Check that current character is number.
     var c = s.charAt(i);
     if (!isDigit(c)) return false;
    }

    // All characters are numbers.
    return true;
}


// Returns true if character c is a digit
// (0 .. 9).

function isDigit (c)
{   return ((c >= "0") && (c <= "9"))
}

// Returns true if character c is an English letter
// (A .. Z, a..z).
//
// NOTE: Need i18n version to support European characters.
// This could be tricky due to different character
// sets and orderings for various languages and platforms.

function isLetter (c)
{
	var isValid;

	isValid = false;

	isValid |= ((c >= "a") && (c <= "z"));
	isValid |= ((c >= "A") && (c <= "Z"));
	isValid |= ((c >= "À") && (c <= "Ä"));
	isValid |= ((c >= "È") && (c <= "Ë"));
	isValid |= ((c >= "Ì") && (c <= "Ï"));
	isValid |= ((c >= "Ò") && (c <= "Ö"));
	isValid |= ((c >= "Ù") && (c <= "Ü"));
	isValid |= ((c >= "à") && (c <= "ä"));
	isValid |= ((c >= "è") && (c <= "ë"));
	isValid |= ((c >= "ì") && (c <= "ï"));
	isValid |= ((c >= "ò") && (c <= "ö"));
	isValid |= ((c >= "ù") && (c <= "ü"));
	isValid |= ((c == "Ç") || (c == "ç"));

	return isValid;
}



// Check whether string s is empty.
function isEmpty(s)
{   return ((s == null) || (s.length == 0))
}

// isAlphabetic (STRING s [, BOOLEAN emptyOK])
//
// Returns true if string s is English letters
// (A .. Z, a..z) only.
//
// For explanation of optional argument emptyOK,
// see comments of function isInteger.
//
// NOTE: Need i18n version to support European characters.
// This could be tricky due to different character
// sets and orderings for various languages and platforms.

function isAlphabetic(s)
{
	  var i;

    if (isEmpty(s))
	     if (isAlphabetic.arguments.length == 1)
	        return defaultEmptyOK;
	     else
	     	  return (isAlphabetic.arguments[1] == true);

    // Search through string's characters one by one
    // until we find a non-alphabetic character.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++)
    {
	   // Check that current character is letter.
	   var c = s.charAt(i);

	   if (!isLetter(c) && (c != ' ') && (c != '-'))
	     return false;
    }

    // All characters are letters.
    return true;
}

function isBlank(s)
{
	for(var i_ix = 0; i_ix < s.length; i_ix++)
	{
		var c = s.charAt(i_ix);
		if ((c != ' ') && (c != '\n') && (c != '\t')) {
			return false;
		}
	}
	return true;
}

