// This file should be used for global Client Side javascript functions

/**
 * Determines if an email address is in a proper email address format and returns true or false as necessary
 * An email address is deemed okay if:
 *   1.  The email address has a '@' in it
 *   2.  The email address has a '.' in it
 * @param field The input field
 * @param field_name The field_name to be displayed to the user if the field is not a valid email
 **/
function isValidEmail(field, field_name) {
  var in_email = field.value;
  var allowedChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&*+-_.@'";

   // Check for @ in email. Can't split email at @ if it doesn't exist 
  if (in_email.indexOf("@") == -1) {
    alert("Please enter a valid " + field_name + ".");
    field.focus();
    return false;
  } 
  splitArray = in_email.split("@");
   
  // make sure no spaces, ;, or more than one @
  /* if (in_email.indexOf("@") == -1 || in_email.indexOf(".") == -1 || in_email.indexOf(" ") != -1 || in_email.indexOf(";") != -1 || splitArray.length > 2) {
  */
  if (splitArray.length > 2) {
    alert("Please enter one valid " + field_name + ".");
    field.focus();
    return false;
  }
  else {   // follow RFC822 appendix D definition local-part@domain-literal
    if ( splitArray[0].indexOf(".") == 0 || splitArray[0].substring(splitArray[0].length-1, splitArray[0].length) == "." ||
        splitArray[1].indexOf(".") == 0 || splitArray[1].substring(splitArray[1].length-1, splitArray[1].length) == "." ) {
      alert("Please enter a valid " + field_name + ".  \nA valid entry may not contain the '.' character " +
            "at the beginning or ending of the local or domain portion.");
      field.focus();
      return false;
    }

    for( var i = 0; i < field.value.length; i++ ) {
      var testChar = field.value.charAt(i);
      if( allowedChars.indexOf(testChar) == -1) {
        alert("Please enter a valid " + field_name + ".  \nA valid entry may not contain the ' " +
              testChar + " ' character.");
        field.focus();
        return false;
      }
    } // end of for loop
  }

  return true;

}


/**
 * Determines if a host name is in a host name format and returns true or false as necessary
 * A hostname is deemed okay if:
 *   1.  The hostname begins with "http://" or "https://"
 *   2.  The hostname contains one '.' (https://fncb.com)
 *   3.  The hostname doesn't end with a '\' or '/'
 * @param field The input field
 * @param field_name The field_name to be displayed to the user if the field is not a valid hostname
 **/
function isValidHostname(field, field_name) {
  var in_hostname = field.value;

  if ((in_hostname.indexOf("http://") == -1 && in_hostname.indexOf("https://") == -1) ||
      in_hostname.indexOf(".") == -1 ||
      in_hostname.charAt(in_hostname.length -1) == '/' || in_hostname.charAt(in_hostname.length-1) == '\\') {
    alert("Please enter a valid " + field_name + ".  \nExample:  https://www.digsigtrust.com");
    field.focus();
    return false;
  }
  else
    return true;
}

/**
 * Determines if a ssn field is in the correct format ###-##-####
 * @param field The input field
 * @param field_name The field_name to be displayed to the user if the field is not a valid ssn
 * (Added 12-27-1999 regexp conditional.)
 **/
function isValidSSN(field, field_name) {
  var in_ssn = field.value;

  if ( !(in_ssn.match(/^\d\d\d-\d\d-\d\d\d\d$/)) ) {
    alert("Please enter a valid " + field_name + ".  \nThe correct format is ###-##-####");
    field.focus();
    return false;
  }
  else
    return true;
}

/**
 * Determines if a phone number is in the format 801-983-0000
 * A phone number is deemed okay if:
 *   1.  It has exactly 12 characters
 *   2.  The characters at index 3 and index 7 are '-'
 *   3.  All the other characters are valid numbers
 * @param field The input field
 * @param field_name The field_name to be displayed to the user if the field is not a valid phone
 * (Added 12-27-1999 regexp conditional.)
**/
function isValidPhone(field, field_name) {
  var in_phone = field.value;

  if ( !(in_phone.match(/^\d\d\d-\d\d\d-\d\d\d\d$/)) ) {
    alert("Please enter a valid " + field_name + ".  \nThe correct format is ###-###-####");
    field.focus();
    return false;
  }
  else
    return true;
}

/**
 * Determines if a zip code is in a proper zip code format and returns true or false as necessary
 * An zip code is deemed okay if:
 *   1.  The zip code has numbers (0-9) in it
 *   2.  The zip code may have a '- in it 
 * @param field The input field
 * @param field_name The field_name to be displayed to the user if the field is not a valid zip code
 **/
function isValidZipCode(field, field_name) {
  var in_zip = field.value;

  if ( !(in_zip.match(/^\d\d\d\d\d$/)) && !(in_zip.match(/^\d\d\d\d\d-\d\d\d\d$/)) ) {
    alert("Please enter a valid " + field_name + ".  \nThe correct format may contain only numbers or \"-\".");
    field.focus();
    return false;
  }
  else
    return true;
}


/**
 * Determines if an IP address is in a proper IP format and returns true or false as necessary
 * An IP is deemed okay if:
 *   1. There are 4 sets of numbers (1 to 3 digits) seperated by periods
 * @param field The input field
 * @param field_name The field_name to be displayed to the user if the field is not a valid IP 
 **/
function isValidIP(field, field_name) {
  var in_ip = field.value;

  if ( !(in_ip.match(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/)) ) {
    alert("Please enter a valid " + field_name );
    field.focus();
    return false;
  }
  else
    return true;
}




/**
 * Determines if a valid selection has not been made.  If not, the user is alerted and false is returned.
 * Otherwise, true is returned.
 * A selection is deemed invalid if:
 *   1. It has a value of ""
 *   2. It has a value of 0
 *   3. It has a value less than 0
 * @param field       The input field
 * @param field_name  The field name to be displayed to the user if the field is not a valid selection
**/
function isValidOption(field, field_name) {
  // alert("The selected \"" + field_name + "\" option has selection value: " + field.selectedIndex);
  if (field.selectedIndex == "" || field.selectedIndex == 0 || field.selectedIndex < 0)
  {
    alert("The selected \"" + field_name + "\" option is not a valid selection.  Please choose one of the other options.");
    field.focus();
    return false;
  }
  else 
    return true;
}

/**
 * Determines if a form field is empty.  If the form is empty, the user is alerted and false is returned.  
 * Otherwise, true is returned.
 * @param field The input field
 * @param field_name The field_name to be displayed to the user if the field is empty
 **/
function isNotEmpty(field, field_name) {
  if(field.value == "") {
    alert("Please enter a value in the " + field_name + " field");
    field.focus();
    return false;
  }
  else
    return true;
} 


/**
 * Determines if passphraseHint is valid 
 * 1. not contained in passphrase
 * 2. not containing passphrase
 * @param field_hint       The hint input field 
 * @param field_passphrase The passphrase input field
 * @param field_hint_name  The name of the hint input field
 * @param field_pass_name  The name of the passphrase input field
 * @return boolean         true if passphase hint is okay, else false
 */
function isValidPassphraseHint(field_hint, field_passphrase, field_hint_name, field_pass_name) {
  if (field_hint.value != "") {
    var re = new RegExp(field_passphrase.value,"i");
    var re2 = new RegExp(field_hint.value,"i");
    var passInHint = field_hint.value.search(re);
    var hintInPass = field_passphrase.value.search(re2);

    if (passInHint != -1) {
      alert("Your " + field_pass_name + " is included in your " + field_hint_name + ".");
      return false;
    }
    if (hintInPass != -1) {
      alert("Your " + field_hint_name + " is included in your " + field_pass_name + ".");
      return false;
    }
  }
  return true;
}


/**
 * Determines if form checkbox or radio field is checked.  If the form is not checked, the user is alerted and false is 
 * returned.  Otherwise, true is returned.
 * Assumption: field.length > 1
 * @param field The input field
 * @param field_name The field_name to be displayed to the user if the field is not checked 
 **/
function isChecked(field, field_name) {
  var checked = false;

  for( var i = 0; !checked && (i < field.length); i++) {
    checked = field[i].checked;
  } 

  if (!checked) {
    alert("Please select a value in the " + field_name + " field.");
    field[0].focus();
    return false;
  } else {
    return true;
  }
}


/**
 * Identify number of checkboxes checked for a field.
 * Assumption: field.length > 1
 * @return the number of checkboxes checked
 */
function hasAtLeastXChecked(field, field_name, num_checks) {
  var numChecked = 0;

  for( var i = 0; i < field.length; i++) {
    if (field[i].checked)
      numChecked++;
  }

  if (numChecked != num_checks) {
    alert("You must select only/at least " + num_checks + " " + field_name + ".");
    field[0].focus();
    return false;
  } else {
    return true;
  }

}
 


/**
 * Determines if a form field has at least a certain number of characters.  
 * If at least the specified number of characters don't exist in the form field, faslse is returned.  
 * Otherwise, true is returned.
 * @param field The input field
 * @param field_name The field_name to be displayed to the user if the specified number of characters don't exist
**/
function hasAtLeastXChars(field, field_name, num_chars) {
  if(trim(field.value).length < num_chars) {
    alert("Please enter at least " + num_chars + " characters in the " + field_name + " field");
    field.focus();
    return false;
  }
  else
    return true;
}

/**
 * Determines if a form field has an invalid character.
 * If the specified character exists in the form field, false is returned.
 * There is now an internal list of bad characteres, such as " which will also be rejected
 * Otherwise, true is returned.
 * @param field The input field
 * @param field_name The field_name to be displayed to the user if the specified number of characters don't exist
 * @param invalid_char The invalid character for field
 **/
function hasNoInvalidChar(field, field_name, invalid_char) {
  var bad_char_array = ["\"", "\\", "/", "=", invalid_char];
   
  for (x = 0; x < bad_char_array.length; x++) {
    if(field.value.indexOf(bad_char_array[x]) != -1) {
      alert("Please enter a valid " + field_name + ".  \nA valid entry may not contain the ' " + bad_char_array[x] +
            " ' character.");
      field.focus();
      return false;
    }
  }
  return true;
}


/**
 * Determines if a form field has all allowed characters, which is currently limited to PrintableSting less characters
 * known to cause issues with publishing to ldap directory, such as , : = /
 * If an unspecified character exists in the form field, false is returned.
 * Otherwise, true is returned.
 * The listing of allowable
 * @param field The input field
 * @param field_name The field_name to be displayed to the user if the specified number of characters don't exist
 **/
function hasOnlyAllowedChars(field, field_name) {
  // PrintableString def www.asn-1.com/usascii.html limited to exclude ,:=/
  var printableString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 abcdefghijklmnopqrstuvwxyz()+-.?'";

  for( var i = 0; i < field.value.length; i++ ) {
    var testChar = field.value.charAt(i);
    if( printableString.indexOf(testChar) == -1) {
      alert("Please enter a valid " + field_name + ".  \nA valid entry may not contain the ' " + 
            testChar + " ' character.");
      field.focus();
      return false;
    }
  }
  return true;
}


/**
 * Determines if two text fields are equal.  
 * If they are not equal, false is returned and an error message pops up,
 * Otherwise, true is returned.
 * @param field1 - The 1st field to be compared
 * @param field2 - The 2nd field to be compared
 * @param error_message - The error message to be displayed if the fields don't match
**/
function areEqual(field1, field2, error_message) {
  if(field1.value == field2.value) {
    return true;
  }
  else {
    alert(error_message);
    field1.focus();
    return false;
  }
}


/**
 * Determines if a form field has only numeric characters in it.  If only numeric characters exist in the form field,
 * true is returned.  Otherwise, false is returned
 * @param field The input field
 * @param field_name The field_name to be displayed to the user if the specified field contains non-numeric characters
**/
function isNumeric(field, field_name, min, max) {

  var foundNonNumeric = false;
  for(charIndex = 0; charIndex < field.value.length; charIndex++) {
    if(isNaN(parseInt(field.value.charAt(charIndex)))) {
      foundNonNumeric = true;
      break;
    }
  }
  if(foundNonNumeric) {
    alert("The " + field_name + " may contain only numeric characters");
    field.focus();
  }

  if (min != 'undefined' && max != 'undefined') { 
    if (field.value < min) {
      alert("The " + field_name + " value cannot be less than " + min);
      foundNonNumeric = true;
      field.focus();
    }
    if (field.value > max) {
      alert("The " + field_name + " value cannot be greater than " + max);
      foundNonNumeric = true;
      field.focus();
    }
  }

  return !foundNonNumeric;
} 


/**
 * Determines if all fields of a numeric input with 3 parts:
 * - all are completed
 * - all are numeric
 * This function may be used to validate date fields (dob), ssn, and phone numbers.
 * @param field1  The first input field
 * @param field2  The second input field
 * @param field3  The third input field
 * @param name1  The first input field name
 * @param name2  The second input field name
 * @param name3  The third input field name
 * @param length1  The first input field length
 * @param length2  The second input field length
 * @param length3  The third input field length
 * @returns boolean  true if validation successful, else false
*/
function isGroupCompleted(field1, field2, field3, name1, name2, name3, length1, length2, length3) {
  return (
    hasAtLeastXChars(field1, name1, length1) &&
    isNumeric(field1, name1) &&
    hasAtLeastXChars(field2, name2, length2) &&
    isNumeric(field2, name2) &&
    hasAtLeastXChars(field3, name3, length3) &&
    isNumeric(field3, name3) 
  );
}


/**
 * Determines if a date entered in the mm-yyyy format is valid.  If so, true is returned.
 * Otherwise, the user is alerted of the error, and false is returned.
 * @param field The input date field
 * @param field_name The field_name to be displayed in error messages to the user
 **/
function isValidMMYYYY(field, field_name) {
  var inputDate = field.value;
  
  if(inputDate == "") {
    alert("Please enter a value in the " + field_name + " field");
    field.focus();
    return false;
  }

  if( !(inputDate.match(/^\d\d-\d\d\d\d$/)) ) {
    alert("Please enter the " + field_name + " field in the mm-yyyy format");
    field.focus();
    return false;
  }

  var mm = inputDate.substring(0,2);
  var yyyy = inputDate.substring(3);

  if(mm == 0 || mm > 12) {
    alert("Error in " + field_name + " field.  The Month must be between 1 and 12");
    field.focus();
    return false;
  }
  return true;
}
  

/**
 * Determines if a date entered in the mm-dd-yyyy format is valid.  If so, true is returned.
 * Otherwise, the user is alerted of the error, and false is returned.
 * @param field The input date field
 * @param field_name The field_name to be displayed in error messages to the user
 **/
function isValidDate(field, field_name) {
  var inputDate = field.value;
  
  if(inputDate == "") {
    alert("Please enter a value in the " + field_name + " field");
    field.focus();
    return false;
  }

  if( !(inputDate.match(/^\d\d-\d\d-\d\d\d\d$/)) ) {
    alert("Please enter the " + field_name + " field in the mm-dd-yyyy format");
    field.focus();
    return false;
  }

  var mm = inputDate.substring(0,2);
  var dd = inputDate.substring(3,5);
  var yyyy = inputDate.substring(6);

  if(mm == 0 || dd == 0) {
    alert("Error in " + field_name + " field.  The Month and Day must be greater than 0");
    field.focus();
    return false;
  }

  if(mm > 12) {
    alert("Error in " + field_name + " field.  The Month must be between 1 and 12");
    field.focus();
    return false;
  }

  var maxDays = getDaysInMonth(mm,yyyy);

  if(dd > maxDays) {
    alert("Error in " + field_name + " field.  There are only " + maxDays + " days in " + getMonthName(mm) + " of " + yyyy);
    field.focus();
    return false;
  }

  return true;
}


/**
 * Determines if a date entered in the mm-dd-yyyy format is malformed.  If not, the submitted mm-dd-yyyy is returned.
 * Date is malformed if in one of the following formats:
 *   If mm-d-yyyy format then mm-0d-yyyy is returned.
 *   If m-dd-yyyy format then 0m-dd-yyyy is returned.
 *   If m-d-yyyy  format then 0m-0d-yyyy is returned.
 * @param mmddyyyy     The input date 
 **/
function fixMMDDYYYYDate(mmddyyyy) {

  // separate out mm dd yyyy components
  regExp = /^(\d\d?)-(\d\d?)-(\d+)$/;
  reArray = mmddyyyy.match(regExp);
  mm = reArray[1];
  dd = reArray[2];
  yyyy = reArray[3];

 if (mmddyyyy.length = 10) {
   return mmddyyyy;
 } else {
  // prepend 0s to mm and/or dd
  mm = (mm.length < 2)? ("0"+mm):mm;
  dd = (dd.length < 2)? ("0"+dd):dd;

  return(mm + "-" + dd + "-" + yyyy); 
 } 

}


/**
 * Determines if the date entered in the mm-dd-yyyy format is greater than today 
 *
 *
**/
function hasNotExpired(field, field_name) {
  var mmddyyyy = field.value;

  // separate out mm dd yyyy components
  regExp = /^(\d\d?)-(\d\d?)-(\d+)$/;
  reArray = mmddyyyy.match(regExp);
  mm = reArray[1];
  dd = reArray[2];
  yyyy = reArray[3];

  var today = new Date();
  var field_date = new Date();

  field_date.setYear(yyyy);
  field_date.setMonth( (parseInt(mm) - 1 ) );  //month 0-11
  field_date.setDate(dd);

  //Clear out time
  field_date.setHours(0);
  field_date.setMinutes(0);
  field_date.setSeconds(0);
  today.setHours(0);
  today.setMinutes(0);
  today.setSeconds(0);

  //Check field_date to current day (/10000 to drop off miliseconds)
  if( parseInt(field_date.getTime() / 10000) < parseInt(today.getTime() / 10000) ) {
     alert(field_name + " has expired.  Please check date and re-enter");
     field.focus();
     return false;
  }

  return true; 
}


/**
 * Determines if the date entered in the mm-yyyy format is greater than today
 *
**/
function hasNotExpiredMMYYYY(field, field_name) {
  var mmyyyy = field.value;

  // separate out mm yyyy components
  regExp = /^(\d\d?)-(\d+)$/;
  reArray = mmyyyy.match(regExp);
  mm = reArray[1];
  yyyy = reArray[2];

  var today = new Date();
  var field_date = new Date();

  field_date.setYear(yyyy);
  field_date.setMonth( (parseInt(mm) - 1 ) );  //month 0-11
  // default to last day of month
  field_date.setDate(getDaysInMonth(mm,yyyy));

  //Clear out time
  field_date.setHours(0);
  field_date.setMinutes(0);
  field_date.setSeconds(0);
  today.setHours(0);
  today.setMinutes(0);
  today.setSeconds(0);

  //Check field_date to current day (/10000 to drop off miliseconds)
  if( parseInt(field_date.getTime() / 10000) < parseInt(today.getTime() / 10000) ) {
     alert(field_name + " has expired.  Please check date and re-enter");
     field.focus();
     return false;
  }

  return true;
}


/**
 * Determines if the date entered in the mm-yyyy format is greater than today
 *
**/
function hasNotExpiredMMYYYY2(fieldMM, fieldYYYY, field_name) {
  var mm = fieldMM.value;
  var yyyy = fieldYYYY.value;

  var today = new Date();
  var field_date = new Date();

  field_date.setYear(yyyy);
  field_date.setMonth( (parseInt(mm) - 1 ) );  //month 0-11
  // default to last day of month
  field_date.setDate(getDaysInMonth(mm,yyyy));

  //Clear out time
  field_date.setHours(0);
  field_date.setMinutes(0);
  field_date.setSeconds(0);
  today.setHours(0);
  today.setMinutes(0);
  today.setSeconds(0);

  //Check field_date to current day (/10000 to drop off miliseconds)
  if( parseInt(field_date.getTime() / 10000) < parseInt(today.getTime() / 10000) ) {
     alert(field_name + " has expired.  Please check date and re-enter");
     fieldMM.focus();
     return false;
  }

  return true;
}


/**
 * Determines if the Credit Card entered is the correct length and begins with the right numbers 
 *
**/

function isValidCC(cc_type, cc_num) {
  type = cc_type.selectedIndex;
  number = cc_num.value;

  // Visa
  if (type == 1) {
    if (number.length != 13 && number.length != 16) {
      alert("The length of your VISA Credit Card number seems to be incorrect. Please check and re-enter the credit card information. (SYS004)");
      return false;
    }
    if (number.substring(0, 1) != "4") {
      alert("The credit card number you entered does not seem to be valid for a VISA card. Please check and re-enter the credit card information. (SYS004)");
      return false;
    }

  }

  // Mastercard
  else if (type == 2) {
    if (number.length != 16) {
      alert("The length of your MASTERCARD Credit Card number seems to be incorrect. Please check and re-enter the credit card information. (SYS004)");
      return false; 
    }
    if (number.substring(0, 2) != "51" && number.substring(0,2) != "52" && number.substring(0,2) != "53" && number.substring(0,2) != "54" && number.substring(0,2) != "55") {
      alert("The credit card number you entered does not seem to be valid for a MASTERCARD card. Please check and re-enter the credit card information. (SYS004)");
      return false;
    }
  }

  // American Express
  else if (type == 3) {
    if (number.length != 15) {
      alert("The Length of your AMERICAN EXPRESS Credit Card number seems to be incorrect. Please check and re-enter the credit card information. (SYS004)");
      return false;
    }
    if (number.substring(0, 2) != "34" && number.substring(0,2) != "37") {
      alert("The credit card number you entered does not seem to be valid for an AMERICAN EXPRESS card. Please check and re-enter the credit card information. (SYS004)");
      return false;
    }
  }
  return true;
}






//************************************DATE LIBRARY***********************************************
// The following functions are date oriented

/**
 * This function returns the number of days in a month given the month and the year
 * @param mm The month between 1 and 12
 * @param yyyy The four digit year
 **/
function getDaysInMonth(mm, yyyy) {
  var days;
  switch(mm){
    case 1:
      days = 31;
      break;
    case 2:
      if(isLeapYear(yyyy) == false) 
        days = 28;
      else 
	days = 29;
      break;
    case 3:
      days = 31;
      break;
    case 4:
      days = 30;
      break;
    case 5:
      days = 31;
      break;
    case 6:
      days = 30;
      break;
    case 7:
      days = 31;
      break;
    case 8:
      days = 31;
      break;
    case 9:
      days = 30;
      break;
    case 10:
      days = 31;
      break;
    case 11:
      days = 30;
      break;
    case 12:
      days = 31;
      break;
  }
  return parseInt(days);
}

/**
 * This function determines if a year is a leap year
 * @param yyyy A four digit year.
 * @return true if the input year is a leap year.  false otherwise
 **/
function isLeapYear(yyyy) {
  if(((yyyy % 4 == 0) && ((yyyy % 100) != 0)) || ((yyyy % 400) == 0)) 
    return true;
  else 
    return false;
}

/**
 * This function returns a month name given a month number.
 * @param mm The month number from 1-12
 * @return The month name
 **/
function getMonthName(mm) {
  var monthNames = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", 
                             "October", "November", "December");
  if(mm >= 1 && mm <= 12) 
    return monthNames[mm-1];
  else
    return "";
}
//*********************************END DATE LIBRARY***************************************************


//*********************************FRAMES / WINDOWS LIBRARY*******************************************

/**
 * This function breaks out of the frame.
 * Assumption: do not want to completely break out of frames; desireable to use NES frames debugging info. 
 * @param frameFileName  Frame URI or filename (i.e. frames.html)
 **/
function breakOutOfParentFrame(frameFileName) {
  if ((window != parent) && (parent.location.href.indexOf(frameFileName) != -1)) parent.location.href = location.href;
}


/** 
 * Open child window one quarter the size of the parent window
 * Author:
 *   Original:  Eric King (eric_andrew_king@hotmail.com) 
 *   Web Site:  http://redrival.com/eak/ The JavaScript Source!! http://javascript.internet.com
 **/ 
function NewWindow(mypage, myname, w, h, scroll) {
  var winl = (screen.width - w) / 2;
  var wint = (screen.height - h) / 2;
  winprops = 'height='+h+',width='+w+',top='+wint+',left='+winl+',scrollbars='+scroll+',resizable'
  win = window.open(mypage, myname, winprops)
  if (navigator.appName == "Netscape" && parseInt(navigator.appVersion) >= 4) { win.window.focus(); }
}


/**
 * Open a popup window using the arguments passed in
 * Neovation SWA usability
 * @param url        URL of the window to open and the attributes to use for the window
 * @param features   window features
*/
function openWin(url,features){

  var newWin = window.open(url,"",features);

}


/**
 * Submit the form when form is embedded in (div tag) layers used with Netscape,
 * i.e.  <div class="swaBeginWzrdContent" id="body">  where id="body" is the layer_id
 * Neovation SWA usability
 * @param layer_id    an ID="xxx" tag used with a div tag
 * @param form_name   name of form, commonly theForm
*/
function goToNext(layer_id, form_name){
  // Set reference to form - syntax different for NS and IE
  if (navigator.appName.indexOf("Netscape") != -1)
    var frm = document.layers[layer_id].document.forms[form_name];
  else if (navigator.appName.indexOf("Microsoft Internet Explorer") != -1)
    var frm = document.forms[form_name];

  if (validateForm(frm))
    frm.submit();
}


/**
 * Ask user to confirm exiting a wizard. If confirms, close the window.
 * Neovation SWA usability
*/
function confirmQuit(){

  // Ask user to confirm quiting the wizard
  var closeWin = confirm("Are you sure you want to quit the wizard?");

  // If user confirmed quitting, close window. If not, do nothing
  if (closeWin)
    self.close();

}



/**
 * Ask user to confirm exiting the application. If confirms, return to return_page.
*/

function confirmQuitApp(return_page){

  // Ask user to confirm quiting the wizard
  var returnWin = confirm("Are you sure you want to quit the application?");

  // If user confirmed quitting, update page. If not, do nothing
  if (returnWin)
    self.location.href = return_page;

}


/**
 * Print browser window contents
 * Neovation SWA usability
*/
function printBrowserWindow(){
  // IE 4x doesn't support window print function
  if (window.print) {
    window.print();
  }
  else {
    alert("This browser does not support printing using a javascript function.  Use the hotkeys ALT-F then CTRL-P to print this screen.");
  }
}


//*********************************END FRAMES / WINDOWS LIBRARY***************************************


//*********************************BROWSER LIBRARY****************************************************

/**
 * Detect browser version and return identifying string
 * @return identifying browser version, something like #.# or #.##
 */
function getBrowserVersion() {
    var agent = navigator.userAgent;
    var browserVersion = "";

    // msie
    if (agent.indexOf("MSIE") != "-1") {
        browserVersion = agent.substring( (agent.indexOf("MSIE") + 5), agent.length );
        browserVersion = browserVersion.substring( 0, browserVersion.indexOf(";") );
    }

    // netscape
    else if ( (agent.indexOf("Mozilla") != "-1") && (agent.indexOf("compatible") == "-1") ) {
        browserVersion = agent.substring( (agent.indexOf("Mozilla/") + 8), agent.length );
        browserVersion = browserVersion.substring( 0, browserVersion.indexOf(" ") );
    }
    else {
        browserVersion = "";
    }

    return browserVersion;
}


/**
 * Get browser major version and return integer
 * @return browser major version, #
 *   Assumes truncation of non -+0123456789 characters
 */
function getBrowserMajorVersion() {
  return parseInt( getBrowserVersion() );
}

/** 
 * Determine if browser has DST Root X1 cert preloaded
 * Assumes only in browsers: Netscape 4.51 and greater,
 *   IE 5.01 and greater
 */
function hasDSTRootCertInBrowser() {
  // IE 
  if ( (navigator.appName == "Microsoft Internet Explorer") && !( parseFloat( getBrowserVersion() ) < 5.01 ) ) {
    return true;
  }
  else if ( (navigator.appName == "Netscape") && !( parseFloat( getBrowserVersion() ) < 4.51 ) ) {
    return true;
  }
  else 
    return false;
}
 

/**
 * Writes out ordered list of Root Certificate installation instructions (DOM)
 * Currently only MSIE 5, MSIE 4, and Netscape (default) supported
 */
function writeRootCertInstall() {
  document.write("\n<ol>");
  if ( (navigator.appName == "Microsoft Internet Explorer") && ( parseInt( getBrowserVersion() ) >= 5 ) ) {
    document.write("\n  <li>Choose \"Open this file from its current location\".</li>");
    document.write("\n  <li>Click OK. The Certificate information will be displayed.</li>");
    document.write("\n  <li>Click Install Certificate. The Certificate Manager Import wizard appears.</li>");
    document.write("\n  <li>Click Next.</li>");
    document.write("\n  <li>Click Next.</li>");
    document.write("\n  <li>Click Finish.</li>");
    document.write("\n  <li>Click Yes.</li>");
  }
  // lower version of IE
  else if ( (navigator.appName == "Microsoft Internet Explorer") && ( parseInt( getBrowserVersion() ) < 5 ) ) {        
    document.write("\n  <li>Select \"Open this file from its current location\".</li>");
    document.write("\n  <li>Click OK. The New Site Certificate dialog box appears.</li>");
    document.write("\n  <li>Ensure the check boxes are selected for Enable Certificate and each service for which you want the certificate to be used.</li>");
    document.write("\n  <li>Click OK. The Root Certificate Store message appears.</li>");
    document.write("\n  <li>Click Yes.</li>");
  }
  // otherwise assumption of Netscape browser
  else {
    document.write("\n  <li>Click Next.</li>");
    document.write("\n  <li>Click Next.</li>");
    document.write("\n  <li>Click Next.</li>");
    document.write("\n  <li>Place check marks in all three boxes to accept this CA for certifying network sites, e-mail users, and software developers.</li>");
    document.write("\n  <li>Click Next.</li>");
    document.write("\n  <li>Click Next.</li>");
    document.write("\n  <li>In the \"Name:\" field, type a name for the root certificate.</li>");
    document.write("\n  <li>Click Finish.</li>");
  }
  document.write("\n</ol>");

} 


/**
 * Extract query string from URL (e.g. document.URL)
 * @param  url      The URL, formatted like document.URL
 * @return query    The query string, including beginning '?'
 */
function getQueryString(url) {

  var query = "";

  if (url.length > 0 && url.indexOf("?") > 0) {
    query = document.URL.substr(document.URL.indexOf("?"));
  }

  return query;
}


// Checks to make sure the passphrase hint it not included in passphrase
function isPasswordInHint(theForm) {
  if (theForm.passphrase_hint.value != "") {
    var re = new RegExp(theForm.passphrase1.value,"i");
    var re2 = new RegExp(theForm.passphrase_hint.value,"i");
    var passInHint = theForm.passphrase_hint.value.search(re);
    var hintInPass = theForm.passphrase1.value.search(re2);

    if (passInHint != -1) {
      alert("Your passphrase is included in your passphrase hint.");
      return false;
    }
    if (hintInPass != -1) {
      alert("Your passphrase hint is included in your passphrase.");
      return false;
    }
  }
  return true;
}

/**
 * Determines if Washington is the state and a valid county has been entered .  If not, the user is alerted and false is returned.
 * Otherwise, true is returned.
 * A selection is deemed invalid if:
 *   1. It has a value of ""
 *   2. It has a value of 0
 *   3. It has a value less than 0
 * @param field       The input field
 * @param field_name  The field name to be displayed to the user if the field is not a valid selection
**/
function inStateCounty(county, state, field_name) {

  if ((state.options[state.selectedIndex].value == 53) && (county.selectedIndex == 0)) 
  {
    alert("The selected \"" + field_name + "\" option is not a valid selection for State of Washington addresses.  Please choose a valid county.");
    county.focus();
    return false;
  }
  else
  {
    return true;
  }
}


/** 
 * This function moves chosen options from one select box to another.
 * All options in each list should have a unique name, plus have a value.
 * The resulting lists will be sorted by name.  If it is called with no
 * items selected, the lists will still be sorted.
 *
 * Based on (with variable names changed for better readability,
 * and comments added) a free script by Phil Webb (phil@philwebb.com). 
 *
 * @param  SourceList
 * @param  TargetList
 */
function moveSelectedOptionsToAnotherList(SourceList, TargetList) {
  var SourceTextArray = new Array();
  var TargetTextArray = new Array();
  var ValuesArray = new Array();
  var i;
  // The ValuesArray will contain all the values (accessed by text, not 
  // index) of both the source and the target lists.  It allows the two 
  // new arrays to be created using only the display text, sorted, and
  // then copied (together with the value, retrieved from ValuesArray)
  // to the two select boxes. 
  
  // Copy the target array to ValuesArray
  for (i = 0; i < TargetList.options.length; i++) {
    ValuesArray[TargetList.options[i].text] = TargetList.options[i].value;
    TargetTextArray[i] = TargetList.options[i].text;
  }
  
  var sourceLength = 0;
  var targetLength = TargetTextArray.length;
  for(i = 0; i < SourceList.options.length; i++) {
    // Copy the source array to ValuesArray
    ValuesArray[SourceList.options[i].text] = SourceList.options[i].value;
	
    if (SourceList.options[i].selected && SourceList.options[i].value != "") {
      // Move the selected option from the source to the target
      TargetTextArray[targetLength] = SourceList.options[i].text;
      targetLength++;
    }
    else {
      // Leave the unselected option in the source
      SourceTextArray[sourceLength] = SourceList.options[i].text;
      sourceLength++;
    }
  }
  // Sort both of the arrays by their text values
  SourceTextArray.sort();
  TargetTextArray.sort();
  
  // Empty the existing lists
  SourceList.length = 0;
  TargetList.length = 0;
  
  // Populate the source list
  var c;
  for(c = 0; c < SourceTextArray.length; c++) {
    var NewOption = new Option();
    NewOption.value = ValuesArray[SourceTextArray[c]];
    NewOption.text = SourceTextArray[c];
    SourceList[c] = NewOption;
  }
  
  // Populate the target list
  for(c = 0; c < TargetTextArray.length; c++) {
    var NewOption = new Option();
    NewOption.value = ValuesArray[TargetTextArray[c]];
    NewOption.text = TargetTextArray[c];
    TargetList[c] = NewOption;
  }
}

/** 
 * This is used when there are two list boxes and buttons move
 * items from the options box to the selected box (e.g. for 
 * LRA permissions).  This function will return all of the
 * names or values found in a list.
 *
 * @param  selectBox
 * @param  textOrValues   "text" or "values" to determine what is returned
 *                        (normally "values")
 * @param  separator      '~' or similar
 *
 * @return parsedValues  = concatentation of the text or values in the list
 *
 * The result from this call should be placed in a hidden
 * field to submit it.
 */
function concatenateAllListItems(selectBox, textOrValues, separator){
  if (  (selectBox == null) ||
        (textOrValues == null) ||
        ( (textOrValues != "text") && (textOrValues != "values")) ||
        (separator == null) ) {

    return "*ERROR*"; // ERROR  (needs to be handled by calling page)
  }
  
  var i;
  var result = new String();
  if (textOrValues == "text") {
    for (i=0; i < selectBox.options.length; i++){
      result += selectBox.options[i].text;
      if (i < (selectBox.options.length-1)) {
        result += separator;
      }
    }
  }
  else { // "values"
    for (i=0; i < selectBox.options.length; i++){
      result += selectBox.options[i].value;
      if (i < (selectBox.options.length-1)) {
        result += separator;
      }
    }
  }
  return result;
}


//*********************************STRING TRIM LIBRARY****************************************************
function LTrim(s) {
  //trim lefthand spaces
  while(s.charAt(0)==' ') {
    s = s.substring(1,s.length);
  }
  return s;
}

function RTrim(s) {
  //trim righthand spaces
  if(s.length > 1) {                          
    while(s.charAt(s.length-1)==' ') {
      s = s.substring(0,s.length-1);
    }
  }
  return s;
}

function trim(str) {
  str=LTrim(str);
  str=RTrim(str);
  return str;
}
//*******************************END STRING TRIM LIBRARY**************************************************
