/*
  $revision 1.1$

  $date 14-jan-2003$

  This is a library of generic javascript functions.
*/

/*******************************************************************************
* Helper functions.                                                            *
*******************************************************************************/
function errorText( field )
/*
  Hightlight the text of incorrect entries.
*/
{
    field.style.backgroundColor = "yellow";
    field.style.color           = "red";
}

function normalText( field )
/*
  If the field is highlighted from incorrect entry before, make field
  appear normal now.
*/
{
    field.style.backgroundColor = "white";
    field.style.color           = "black";
}

function normalTextIfValue( field )
/*
  If the field is highlighted for missing information before and there is now
  a value in it, make the field appear normal.
*/
{
    if ( field.value != "" )
        normalText( field );
}

/*******************************************************************************
* capitalize                                                                   *
*******************************************************************************/
function capitalize( field )
/*
  This function will be called to capitalize the value in a given field.
*/
{
    field.value = field.value.toUpperCase();
}

/*******************************************************************************
* formatDate                                                                   *
*******************************************************************************/
function formatDate( datevalue, dateFormat )
/*
  This function will return a given date in a given format; as long as the
  format is one of:
       
       MM/DD/YYYY
       YYYY/MM/DD
       MM/YYYY
       YYYY/MM
       MM/DD/YYYY HH24:MI
       MM/DD/YYYY HH24:MI:SS
*/
{
    var formattedDatevalue;
    var month;

    switch ( datevalue.getMonth() )
    {
        case 0:
            month = "01";
            break;
        case 1:
            month = "02";
            break;
        case 2:
            month = "03";
            break;
        case 3:
            month = "04";
            break;
        case 4:
            month = "05";
            break;
        case 5:
            month = "06";
            break;
        case 6:
            month = "07";
            break;
        case 7:
            month = "08";
            break;
        case 8:
            month = "09";
            break;
        case 9:
            month = "10";
            break;
        case 10:
            month = "11";
            break;
        case 11:
            month = "12";
    }

    if ( dateFormat == "MM/DD/YYYY" )
        formattedDatevalue =   month
                             + "/"
                             + leftPad( datevalue.getDate().toString(), 2, '0' )
                             + "/"
                             + datevalue.getFullYear();
    else if ( dateFormat == "YYYY/MM/DD" )
        formattedDatevalue =   datevalue.getFullYear()
                             + "/"
                             + month
                             + "/"
                             + leftPad( datevalue.getDate().toString(), 2, '0' );
    else if ( dateFormat == "MM/YYYY" )
        formattedDatevalue =   month
                             + "/"
                             + datevalue.getFullYear();
    else if ( dateFormat == "YYYY/MM" )
        formattedDatevalue =   datevalue.getFullYear()
                             + "/"
                             + month;
    else if ( dateFormat == "MM/DD/YYYY HH24:MI" )
        formattedDatevalue =   month
                             + "/"
                             + leftPad( datevalue.getDate().toString(), 2, '0' )
                             + "/"
                             + datevalue.getFullYear()
                             + " "
                             + leftPad( datevalue.getHours().toString(), 2, '0' )
                             + ":"
                             + leftPad( datevalue.getMinutes().toString(), 2, '0' );
    else if ( dateFormat == "MM/DD/YYYY HH24:MI:SS" )
        formattedDatevalue =   month
                             + "/"
                             + leftPad( datevalue.getDate().toString(), 2, '0' )
                             + "/"
                             + datevalue.getFullYear()
                             + " "
                             + leftPad( datevalue.getHours().toString(), 2, '0' )
                             + ":"
                             + leftPad( datevalue.getMinutes().toString(), 2, '0' )
                             + ":"
                             + leftPad( datevalue.getSeconds().toString(), 2, '0' );

    return( formattedDatevalue );
}

/*******************************************************************************
* initcap                                                                      *
*******************************************************************************/
function initcap( field )
/*
  A function that can be passed a field and will set the first letter of
  every word to upper case and every other letter to lower case.  A word will
  be limited by either a space or a dash ('-').
*/
{
    var i;
    var capNext = true;
    var ch;
    var s1 = "", s2 = "";

    /* Start by forcing entire string to lower case. */
    s1 = field.value.toLowerCase();

    /* For each character in the string... */
    for ( i = 0; i < s1.length; i++ )
    {
        /* Get the character from the string for ease of reference. */
        ch = s1.charAt( i );

        /*
          If the character is a delimiter...  The next character will be
          capitalized.
        */
        if ( ch == ' ' || ch == '-' )
            capNext = true;

        /* If this letter is to be capitalized... */
        if ( capNext && ch >= 'a' && ch <= 'z' )
        {
            ch = ch.toUpperCase();
            capNext = false;
        }

        s2 = s2 + ch;
    }

    field.value = s2;
}

/*******************************************************************************
* isAlpha                                                                      *
*******************************************************************************/
function isAlpha( value )
/*
  A function that can be passed a string and will check each digit to see
  if it is between 'a' and 'z' or between 'A' and 'Z'.  The space and dash
  ('-') and '.' characters will also be accepted.
*/
{
    var i;
    var ch;

    /* For each character in the string... */
    for ( i = 0; i < value.length; i++ )
    {
        /* Get the character from the string for ease of reference. */
        ch = value.charAt( i );

        /*
          If the character is neither a lowercase nor an uppercase
          letter of the alphabet...
        */
        if (    ( ch < 'a' || ch > 'z' )
             && ( ch < 'A' || ch > 'Z' )
             && ch != ' '
             && ch != '-'
             && ch != '.'
           )
            return( false );
    }

    return( true );
}

/*******************************************************************************
* isNumeric                                                                    *
*******************************************************************************/
function isNumeric( value )
/*
  A function that can be passed a string and will check each digit to see if it
  is between '0' and '9'.  Decimal points are also allowed as well as a leading
  negative sign.
*/
{
    var i;
    var ch;
    var decimal_count = 0;

    /* For each character in the string... */
    for ( i = 0; i < value.length; i++ )
    {
        /* Get the character from the string for ease of reference. */
        ch = value.charAt( i );

        /* If the character is a decimal point... */
        if ( ch == '.' )
        {
            /* If there is more than one decimal point... */
            if ( decimal_count++ != 0 )
                return( false );
        }
        else if ( ch == '-' )
        {
            if ( i != 0 )
                return( false );
        }
        /* Else if the character is not a number... */
        else if ( ch < '0' || ch > '9' )
            return( false );
    }

    /* If the last character is a decimal point... */
    if ( value.charAt( value.length - 1 ) == '.' )
        return( false );

    /* If the only character is a negative sign... */
    if ( value.charAt( value.length - 1 ) == '-' )
        return( false );

    return( true );
}

/*******************************************************************************
* isValidEmail                                                                 *
*******************************************************************************/
function isValidEmail( value )
/*
  The e-mail address should have one and only one '@' symbol.  And the '@'
  symbol must not be the first character, and the last '.' must be at least
  one character after the '@' and not the last character.
*/
{
    var amp_count = 0;
    var dot_count = 0;
    var i

    for ( i = 0; i < value.length; i++ )
    {
        if ( value.charAt(i) == '@' )
            amp_count++;

        if ( value.charAt(i) == '.' )
            dot_count++;
    }

    if (    amp_count != 1
         || dot_count == 0
         || value.charAt(0) == '@'
         || value.charAt(0) == '.'
         || value.charAt(value.length - 1) == '.'
         || value.charAt(value.indexOf('@') + 1) == '.'
         || value.charAt(value.indexOf('@') - 1) == '.'
         || value.lastIndexOf('.') < value.indexOf('@')
       )
        return( false );
    else
        return( true );
}

/*******************************************************************************
* leftPad                                                                      *
*******************************************************************************/
function leftPad( value, padWidth, padCharacter )
/*
  This function will take a value and if it is less than that given in width,
  will left pad it with a a given character.
*/
{
    while ( value.length < padWidth )
    {
        value = padCharacter + value;
    }

    return( value );
}

/*******************************************************************************
* moneyFormat                                                                  *
*******************************************************************************/
function moneyFormat( Amount )
/*
  This function will take a valid dollar with cents amount or even dollar amount
  and return it with commas every three digits and any cent amount padded out to
  two decimal places.
*/
{
    var digits = 1;
    var ch;
    var formattedAmount = "";

    /* For each digit of the string backwards... */
    for ( ch = Amount.length - 1; ch >= 0; ch-- )
    {
        /* Add the digit to the formatted string. */
        formattedAmount = Amount.charAt(ch) + formattedAmount;

        /* If there are cents... */
        if ( Amount.charAt(ch) == '.' )
        {
            /* Reset the comma counter. */
            digits = 0;

            /* If there are not two digits, pad the cents out... */
            if ( formattedAmount.length == 2 )
                formattedAmount = formattedAmount + "0";
        }

        /* If it is time for a comma... */
        if ( ch != 0 && digits == 3 && Amount.charAt(ch - 1) != '-' )
        {
            formattedAmount = "," + formattedAmount;
            digits = 1;
        }
        else
            digits++;
    }

    /* Trim any leading zeroes from the value. */
    while (    (    formattedAmount.charAt(0) == '0'
                 || formattedAmount.charAt(0) == ','
               )
            && formattedAmount.length > 1
          )
    {
          formattedAmount
        = formattedAmount.substring(1, formattedAmount.length);
    }

    /* If there are no cents on the amount, add some. */
    if ( formattedAmount.indexOf('.') == -1 )
        formattedAmount = formattedAmount + ".00";

    return( formattedAmount );
}

/*******************************************************************************
* phoneFormat                                                                  *
*******************************************************************************/
function phoneFormat( value )
/*
  A function that can both format and indirectly validate a given string that is
  supposed to hold a ten-digit phone number.  First, all non-numeric characters
  will be stripped out, and then the presence of ten remaining digits will be
  tested for.  If there are not ten digits, null will be returned, meaning that
  the given string was invalid.  Then, the format '(999) 999-9999' will be
  applied to the digits and a string in that format returned.
*/
{
    var i;
    var newPhone       = new String("");
    var formattedPhone = new String("");

    for ( i=0; i <= value.length; i++ )
    {
        if ( value.charAt(i) >= '0' && value.charAt(i) <= '9' )
            newPhone = newPhone + value.charAt(i);
    }

    if ( newPhone.length != 10 )
        return( null );
    else
    {
          formattedPhone
        =   "(" + newPhone.substring(0,3) + ") "
          + newPhone.substring(3,6)
          + "-"
          + newPhone.substring(6,10);

        return( formattedPhone );
    }
}

/*******************************************************************************
* rightPad                                                                     *
*******************************************************************************/
function rightPad( value, padWidth, padCharacter )
/*
  This function will take a value and if it is less than that given in width,
  will right pad it with a a given character.
*/
{
    while ( value.length < padWidth )
    {
        value = value + padCharacter;
    }

    return( value );
}

/*******************************************************************************
* validateAlphaField                                                           *
*******************************************************************************/
function validateAlphaField( field )
/* The field should contain only alphabetic characters. */
{
    if ( field.value != "" && ! isAlpha( field.value ) )
    {
        errorText( field );
        alert(   "Incorrect entry ("
               + field.value
               + "); must contain only alphabetic characters."
             );
        field.value = "";
        field.focus();
    }
    else
        normalText( field );
}

/*******************************************************************************
* validateFixedNumericField                                                    *
*******************************************************************************/
function validateFixedNumericField( field, length )
/* Check the field value for a fixed length and all numeric digits. */
{
    if (    field.value != ""
         && (   field.value.length != length
              || ! isNumeric( field.value )
            )
       )
    {
        errorText( field );
        alert(   "Incorrect entry ("
               + field.value
               + "); must be completely input with numeric digits."
             );
        field.value = "";
        field.focus();
    }
    else
        normalText( field );
}

/*******************************************************************************
* validateNumericField                                                         *
*******************************************************************************/
function validateNumericField( field )
/* Check the field value for all numeric digits. */
{
    if ( field.value != "" && ! isNumeric( field.value ) )
    {
        errorText( field );
        alert(   "Incorrect entry ("
               + field.value
               + "); must be input with numeric digits."
             );
        field.value = "";
        field.focus();
    }
    else
        normalText( field );
}

/*******************************************************************************
* validateEmail                                                                *
*******************************************************************************/
function validateEmail( field )
/*
  The e-mail address should have one and only one '@' symbol.  And the '@'
  symbol must not be the first character, and the last '.' must be at least
  one character after the '@' and not the last character.
*/
{
    if ( field.value != "" && ! isValidEmail( field.value ) )
    {
        errorText( field );
        alert(   "Incorrect entry ("
               + field.value
               + "); your e-mail address does not appear to be valid."
             );
        field.value = "";
        field.focus();
    }
    else
        normalText( field );
}

/*******************************************************************************
* validateMoneyField                                                           *
*******************************************************************************/
function validateMoneyField( field )
/*
  This function will validate and format a field containing a money value.
*/
{
    var i;
    var newAmount = new String("");

    if ( field.value != "" )
    {
        /* Strip out any commas or dollar signs so that numeric test will succeed. */
        for ( i = 0; i <= field.value.length; i++ )
        {
            if ( field.value.charAt(i) != ',' && field.value.charAt(i) != '$' )
            {
                if ( newAmount.value == null )
                    newAmount.value = field.value.charAt(i);
                else
                    newAmount.value = newAmount.value + field.value.charAt(i);
            }
        }

        if ( ! isNumeric( newAmount.value ) )
        {
            errorText( field );
            alert(   "Incorrect entry ("
                   + field.value
                   + "); invalid number."
                 );
            field.value = "";
            field.focus();
        }
        else if (    field.value.indexOf('.') != -1
                  && field.value.indexOf('.') < field.value.length - 3
                )
        {
            errorText( field );
            alert(   "Incorrect entry ("
                   + field.value
                   + "); invalid dollar amount."
                 );
            field.value = "";
            field.focus();
        }
        else
        {
            normalText( field );
            field.value = moneyFormat( newAmount.value );
        }
    }
}

/*******************************************************************************
* validatePhoneField                                                           *
*******************************************************************************/
function validatePhoneField( field )
/*
  This function will validate that a U.S./Canada-style ten-digit phone number
  is input in a given field and will give it a standard format.
*/
{
    var formattedPhone;

    if ( field.value != "" )
    {
        formattedPhone = phoneFormat( field.value );

        /* If the field value could not be formatted; is invalid... */
        if ( formattedPhone == null )
        {
            errorText( field );
            alert(   "Incorrect entry ("
                   + field.value
                   + "); phone number must be ten numbers."
                 );
            field.value = "";
            field.focus();
        }
        else
        {
            normalText( field );
            field.value = formattedPhone;
        }
    }
}

/*******************************************************************************
* validateZip                                                                  *
*******************************************************************************/
function validateZip( field )
/* Check the zip code for a fixed length of five and all numeric digits. */
{
    var value = field.value;

    /* If the length of the zip code is not five digits or is not numeric... */
    if ( value != "" && (value.length != 5 || ! isNumeric( value )) )
    {
        errorText( field );
        alert(   "Incorrect entry ("
               + field.value
               + "); zip code is invalid."
             );
        field.value = "";
        field.focus();
    }
    else
        normalText( field );
}


