/**
 * $Id: Validation.cli.js,v 1.6 2006/06/12 22:30:00 max Exp $
 * Validation.cli.js
 * 
 * Contains generic form validation functions
 * 
 * To use, must associate a "validate" member
 * with each form element to be validated and
 * assign it a function to call that returns
 * true if the field is valid and false if not 
 * The function must take a single argument which
 * is the element being validated.
 * 
 * See RequestDemo.cli.js for an example...
 **/
 
/**
 * ValidateForm - Generic validation function
 *    that validates all fields on a form
 *    that have a "validate" handler defined
 *    Calls the validate function with the
 *    field as the argument
 * 
 * @param form  The form to validate
 * @return      Returns true if all validation
 *              functions return true, false
 *              if any return false
 **/
function ValidateForm(form) {
    
    var valid;

    for (var i=0; i < form.elements.length; i++) {

        var validator = form.elements[i].validate;

        if (validator != undefined) {

            valid = validator(form.elements[i]);

            if (!valid) {

                form.errorElem = form.elements[i];
                return false;
            }
        }
    }
    
    return true;
}

/**
 * ValidateFormUI - This is the UI version of the
 *     ValidateForm function that calls the ValidateForm
 *     function and if invalid, will display an alert
 *     with the error message, highlight the field in error
 *     and return false.  o/w will return true.
 * 
 * @param  form  The form to validate
 * @return       True if valid, false if not
 **/
function ValidateFormUI(form) {

    if (!ValidateForm(form)) {

        form.errorElem.select();
        alert(form.errorElem.errorText);
        return false;
    }
    
    return true;
}

/**
 * ValidateNotBlank - This validation function
 *    returns true if the provided field has a non-blank
 *    value or false otherwise
 *
 * @param  obj  The element to validate the value of 
 * @return      False if the field is blank, true o/w
 **/
function ValidateNotBlank(obj) {

    if (obj.value == "") {

        obj.errorText = "Please enter a value for the " + obj.description + " field";

        return false;
    }

    return true;
}

/**
 * ValidateEmail - Performs rudimentary validation to make sure
 *    the entered email address resembles a valid email address
 * 
 * @param obj  The element to validate as an email address
 * @return     True if it is accepted as a valid email address,
 *             false otherwise
 **/
function ValidateEmail(obj) {

    if (!ValidateNotBlank(obj))
    {

        return false;
    }

    var regexp = /.*@.*\.[a-zA-Z]+/i;

    if (regexp.exec(obj.value) == null)
    {   
        obj.errorText = "The email address you entered is not in a recognized format.  Please re-enter.";

        return false;
    }

    return true;
}

// Declaring required variables
var digits = "0123456789";
// non-digit characters which are allowed in phone numbers
var phoneNumberDelimiters = "()- ";
// characters which are allowed in international phone numbers
// (a leading + is OK)
var validWorldPhoneChars = phoneNumberDelimiters + "+";
// Minimum no of digits in an international phone no.
var minDigitsInIPhoneNumber = 10;

function isInteger(s)
{
    var i;
    for (i = 0; i < s.length; i++)
    {   
        // Check that current character is number.
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    // All characters are numbers.
    return true;
}

function stripCharsInBag(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++)
    {   
        // Check that current character isn't whitespace.
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }
    return returnString;
}

function checkInternationalPhone(strPhone)
{
    s = stripCharsInBag(strPhone, validWorldPhoneChars);
    return (isInteger(s) && s.length >= minDigitsInIPhoneNumber);
}

/**
 * ValidateRequiredPhone - Performs rudimentary validation to make sure a phone number
 *    is entered and the entered phone number resembles a valid phone number
 * 
 * @param obj  The element to validate as a phone number
 * @return     True if it is accepted as a valid phone number,
 *             false otherwise
 **/
function ValidateRequiredPhone(obj)
{
    if (ValidateNotBlank(obj) == false)
    {
        return false;
    }

    if (checkInternationalPhone(obj.value) == false)
    {
        obj.errorText = "The phone number you entered is not in a recognized format.  Please re-enter.";
        return false;
    }

    return true;
}

/**
 * ValidateNonRequiredPhone - Performs rudimentary validation to make sure
 *    the entered phone number (if any) resembles a valid phone number.
 * 
 * @param obj  The element to validate as a phone number
 * @return     True if it is accepted as a valid phone number or nothing is entered,
 *             false otherwise
 **/
function ValidateNonRequiredPhone(obj)
{
    if (obj == null || obj.value == "")
    {
        return true; // Return true if nothing is entered
    }

    if (checkInternationalPhone(obj.value) == false)
    {
        obj.errorText = "The phone number you entered is not in a recognized format.  Please re-enter.";
        return false;
    }

    return true;
}
