function trim(myString) {
// myString     : any string
// RETURN VALUE : myString with all beginning and ending whitespace removed

   myString = myString.replace(/^[\s]+/g,"");
   myString = myString.replace(/[\s]+$/g,"");

  return myString;
}


function checkPostalCode(myPC, isRequired) {
// myPC         : Canadian Postal Code
// isRequired   : 1=yes, 0=no
// RETURN VALUE : empty string on valid postal code, text message on invalid postal code

  if (myPC == "") {
    if (isRequired == 1) {
      return "Le code postal est exigé.";
    } else {
      return "";
    }
  }

  if ((myPC.length < 6) || (myPC.length > 7)) {
    return "Le code postal doit contenir 6 caractères.";
  }

  if (/([DFIOQU])/.test(myPC)) {
    return "Le code postal contient un caractère invalide.";
  }

  if (/^([WZ])/.test(myPC)) {
    return "Le code postal contient une erreur.";
  }

  if (/^([A-Z]{1}\d[A-Z]{1})( |-)?(\d[A-Z]{1}\d)$/.test(myPC)) {
    return "";
  }

  return "Le code postal contient une erreur.";
}


function checkPhone(myPhone, myExtension, myName, isRequired) {
// myPhone      : phone number
// myExtension  : optional extension number, up to 4 digits
// myName       : optional name for the myPhone field, used for returning messages
// isRequired   : 1=yes, 0=no (this only checks if myPhone is required; myExtension is always optional)
// RETURN VALUE : empty string on valid phone number, text message on invalid phone number

  if (myName == "") { myName = "Le numéro de téléphone"; }

  myPhone = trim(myPhone);
  myExtension = trim(myExtension);

  if (myPhone == "") {
    if (isRequired == 1)        { return myName + " est exigé."; }
    else if (myExtension != "") { return "Le numéro de poste ne peut pas être spécifié car " + myName + " n'est pas spécifié."; }
    else                        { return ""; }
  }

  myPhone = myPhone.replace(/^(\d{3})[ \-=\.]*(\d{4})$/, "$1$2");
  myPhone = myPhone.replace(/^[ (]*(\d{3})[ \-=\.)]*(\d{3})[ \-=\.]*(\d{4})$/, "$1$2$3");
  myPhone = myPhone.replace(/^[ (]*1[ \-=\.(]*(\d{3})[ \-=\.)]*(\d{3})[ \-=\.]*(\d{4})$/, "$1$2$3");

  if ((myPhone.length != 10) && (myPhone.length != 7)) { return myName + " est invalide."; }
  if (!myPhone.match(/^(\d)+$/)) { return myName + " est invalide."; }

  if (myExtension != "") {
    if (myExtension.length > 4) { return "Le numéro de poste peut contenir au maximum 4 chiffres."; }
    if (!myExtension.match(/^(\d)+$/)) { return "Le numéro de poste est invalide. Il peut seulement contenir des chiffres."; }
  }

  return "";
}


function checkEmail(myEmail, myName, isRequired) {
// myEmail      : e-mail address
// myName       : optional name for the myEmail field, used for returning messages
// isRequired   : 1=yes, 0=no
// RETURN VALUE : empty string on valid e-mail, text message on invalid e-mail syntax

  if (myName.length < 1) {
    myName = "Le courriel";
  }

  if (myEmail == "") {
    if (isRequired == 1) {
      return myName + " est exigé.";
    } else {
      return "";
    }
  }

/*
  // regular expression source: http://www.breakingpar.com/bkp/home.nsf/Doc!OpenNavigator&87256B280015193F87256C40004CC8C6
  if (!(/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(myEmail))) {
    return myName + " est invalide.";
  }
*/

  // regular expression source: http://www.hexillion.com/samples/
  // Matches a limited version of the RFC 2822 addr-spec form.
  if (!(/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!\.)){0,61}[a-zA-Z0-9]?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!$)){0,61}[a-zA-Z0-9]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/.test(myEmail))) {
    return myName + " est invalide.";
  }

  return "";
}


function checkText(myText, myName, minLength, maxLength) {
// myText       : some text string to perform a check
// myName       : optional name for the myText field, used for returning messages
// minLength    : non-negative integer (0 means myText can be empty string)
// maxLength    : integer (0 means myText must be empty string, -1 means myText has no max length)
// RETURN VALUE : empty string on valid text, text message on invalid text

  if (myName.length < 1) {
    myName = "Le texte";
  }

  if (myText == "") {
    if (minLength > 0) {
      return myName + " est exigé.";
    } else {
      return "";
    }
  }

  if (myText.length < minLength) {
    return myName + " doit contenir au minimum " + minLength + " caractères.";
  }

  if ((maxLength >= 0) && (myText.length > maxLength)) {
    return myName + " peut contenir au maximum " + maxLength + " caractères.";
  }

  return "";
}


function checkUserID(myUserID, myName, minLength, maxLength) {
// myUserID     : user ID to perform a check
// myName       : optional name for the myUserID field, used for returning messages
// minLength    : non-negative integer (0 means myUserID can be empty string)
// maxLength    : integer (0 means myUserID must be empty string, -1 means myUserID has no max length)
// RETURN VALUE : empty string on valid user ID, text message on invalid user ID

  if (myName.length < 1) {
    myName = "Le code d'utilisateur";
  }

  if (myUserID == "") {
    if (minLength > 0) {
      return myName + " est exigé.";
    } else {
      return "";
    }
  }

  if (myUserID.length < minLength) {
    return myName + " doit contenir au minimum " + minLength + " caractères.";
  }

  if ((maxLength >= 0) && (myUserID.length > maxLength)) {
    return myName + " peut contenir au maximum " + maxLength + " caractères.";
  }

  if (/^(([a-z]|\d)*)$/.test(myUserID)) {
    return "";
  }

  return myName + " peut seulement contenir des caractères alphanumériques.";
}


function checkPassword(myPassword, myName, minLength, maxLength) {
// myPassword   : password to perform a check
// myName       : optional name for the myPassword field, used for returning messages
// minLength    : non-negative integer (0 means myPassword can be empty string)
// maxLength    : integer (0 means myPassword must be empty string, -1 means myPassword has no max length)
// RETURN VALUE : empty string on valid password, text message on invalid password

  if (myName.length < 1) {
    myName = "Le mot de passe";
  }

  if (myPassword == "") {
    if (minLength > 0) {
      return myName + " est exigé.";
    } else {
      return "";
    }
  }

  if (myPassword.length < minLength) {
    return myName + " doit contenir au minimum " + minLength + " caractères.";
  }

  if ((maxLength >= 0) && (myPassword.length > maxLength)) {
    return myName + " peut contenir au maximum " + maxLength + " caractères.";
  }

  if (/^(([a-z]|\d)*)$/.test(myPassword)) {
    return "";
  }

  return myName + " peut seulement contenir des caractères alphanumériques.";
}


function isUnsignedInteger(myInteger) {
// myInteger    : string representation of an integer
// RETURN VALUE : true on valid integer, false on invalid integer

  if (/^(\d)+$/.test(myInteger)) {
    return true;
  }
  return false;
}


function isDate(myMonth, myDay, myYear) {
// myMonth      : month (1-12)
// myDay        : date of the month (1-31)
// myYear       : 4-digit year
// RETURN VALUE : true on valid date, false on invalid date


  if (!isUnsignedInteger(myMonth)) return false;
  if ((myMonth < 1) || (myMonth > 12)) return false;

  if (!isUnsignedInteger(myDay)) return false;
  if ((myDay < 1) || (myDay > 31)) return false;

  if (!isUnsignedInteger(myYear)) return false;
  if ((myYear < 1000) || (myYear > 9999)) return false;

  if (myMonth == 2) {
    // February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    if ((myYear % 4 == 0) && ((!(myYear % 100 == 0)) || (myYear % 400 == 0))) {
      // leap year
      if (myDay > 29) return false;
    } else {
      // not a leap year
      if (myDay > 28) return false;
    }
  }

  if ((myMonth == 4) || (myMonth == 6) || (myMonth == 9) || (myMonth == 11)) {
    if (myDay > 30) return false;
  }

  return true;
}

