/**
 * TISC common scripts
 * TB.
 */

/* Extend JS Array */
//return array index if array contains value, otherwise return -1.
Array.prototype.valueIndex = function(value) {
  for (var i=0; i<this.length; i++)
    if (this[i] == value) {
    	return i;
    }	
  return -1;
}

//Return true if array contains value
Array.prototype.contains = function(value) {
  return this.valueIndex(value) >=0 ? true : false;
}

//add value to array, maintain unique values if unique=true.
//value can be comma delimited values
Array.prototype.add = function(value, unique) {
  if (unique) {
	  if (!this.contains(value)) {
	  	this.push(value);
	  }
	} else {
		this.push(value);
	}  
}

//remove given value from array
Array.prototype.remove = function(value) {
	var index = this.valueIndex(value);
	var aRemoved = this.splice (index, 1);
}
Array.prototype.isEmpty = function() {
	return (this == null || this.length < 1);
}
/******/

/*
 * Return true if a checkboxes or radio button is checked.
 */
function isCheckboxOrRadioChecked(form, namePrefix, matchValue, namePostfix) {
	return (countCheckboxOrRadioChecked(form, namePrefix, matchValue, namePostfix) > 0);
}

/*
 * Return count of selected checkboxes or radio buttons.
 * if matchValue param is null then return true if any checkbox or radio button in a group is checked.
 * if matchValue is defined, then return true only if checkbox/radio button with defined matchValue is checked.
 * if namePostfix (usually check/radio control id) is defined then check is done for that specific control.
 * JSF (datattable) names checkboxes as: formId:datatableId:datatableRowIndex:checkboxId
 */
function countCheckboxOrRadioChecked(form, namePrefix, matchValue, namePostfix) {

     //check for optional parameter
     if (typeof matchValue == "undefined") {
       matchValue = "";
     }
     if (typeof namePostfix == "undefined") {
       namePostfix = "";
     }

     var selectedCount = 0;
     
     for(var i=0; i<form.elements.length; i++) {
         if (((form.elements[i].type == "radio") || (form.elements[i].type == "checkbox")) && (form.elements[i].checked)) {
             if ((form.elements[i].name.indexOf(namePrefix) > -1) && 
             	  ((namePostfix == "") || (form.elements[i].name.indexOf(namePostfix) > -1))) {
             	  	
                if (matchValue == '') {
                    selectedCount++;
                } else if (matchValue == form.elements[i].value) {
                    selectedCount++;
                }
             }
         }
     }

     return selectedCount;
 }

/**
 * Check radio button from the radio group which matches the given button value.
 * @param radioButtonGroup
 * @param value
 */
function checkRadioGroupByValue(radioButtonGroup, value) {
   	for(var i=0; i < radioButtonGroup.length; i++) {
   		radioButton = radioButtonGroup[i];
   		if (radioButton.value == value.toString()) {
   			radioButton.checked = true;
   			return;
    	}
   	}	 	            
}

//Enable/Disable radio checkbox
function enDisableRadioOrCheckbox(form, namePrefix, matchValue, enable) {

     for(var i=0; i<form.elements.length; i++) {
         if ((form.elements[i].type == "radio") || (form.elements[i].type == "checkbox")) {
             if (form.elements[i].name.indexOf(namePrefix) > -1) {
                if (matchValue == form.elements[i].value) {
                    if (enable) {
                        form.elements[i].disabled = "";
                    } else {
                        form.elements[i].disabled = "disabled";
                    }
                 }
             }
         }
     }
 }

/*
 * Check/uncheck radio checkbox
 * JSF (datatable) names checkboxes as: formId:datatableId:datatableRowIndex:checkboxId
 * namePrefix=formId:datatableId
 * namePostfix=usually Id of checkbox.
 *
 */
function checkUncheckCheckbox(form, namePrefix, check, namePostfix) {

     if (typeof namePostfix == "undefined") {
       namePostfix = "";
     }

     for(var i=0; i<form.elements.length; i++) {
         if ((form.elements[i].type == "checkbox") || (form.elements[i].type == "radio")) {
             if ((form.elements[i].name.indexOf(namePrefix) == 0) && 
             		 ((namePostfix == "") || (form.elements[i].name.indexOf(namePostfix) > -1))) {
             		 	
                if (check) {
                    form.elements[i].checked = true;
                } else {
                    form.elements[i].checked = false;
                }
             }
         }
     }
 }

function select(field, values) {
     if (field != null) {
         if (field.type == 'select-multiple') {
             for (i = 0; i < field.options.length; i++) { field.options[i].selected = false; for (j = 0; j < values.length; j++) { if (field.options[i].value == values[j]) { field.options[i].selected = true; break; } } }
         }
     }
}

 /*
  * Return true if any value is selected in pull down list (ie. other than default value)
  */
 function isValueSelected(form, namePrefix, defaultValue, namePostfix) {

	 return (countValueSelected(form, namePrefix, defaultValue, namePostfix) > 0);
 }

 /*
  * Return count of pulldown/list controls (ie. other than default value)
  * if namePostfix (usually pulldown/list control id) is defined then check is done for that specific control.
  * JSF (datatbase) names pulldown/list as: formId:datatableId:datatableRowIndex:pulldownId
  */
 function countValueSelected(form, namePrefix, defaultValue, namePostfix) {

     //check for optional parameter
     if (typeof defaultValue == "undefined") {
    	 defaultValue = "";
     }
     if (typeof namePostfix == "undefined") {
       namePostfix = "";
     }
     
     var selectedCount = 0;
     
     for (var i=0; i<form.elements.length; i++) {
         if (form.elements[i].type == "select-one") {
             if ((form.elements[i].name.indexOf(namePrefix) > -1) && 
                	  ((namePostfix == "") || (form.elements[i].name.indexOf(namePostfix) > -1))) {
            	 
                if (getValue(form.elements[i]) != defaultValue) {
                	selectedCount++;
                }
             }
         }
     }
     return selectedCount;
 }
  
//Check if any of the text box are populated
function isValueEntered(form, namePrefix) {
     for (var i=0; i<form.elements.length; i++) {
         if ((form.elements[i].type == "text") && (form.elements[i].name.indexOf(namePrefix) > -1)) {
                if (trim(getValue(form.elements[i])) != "") {
                 return true;
             }
         }
     }
     return false;
}

//Check if any of the text box are NOT populated
function isValueNotEntered(form, namePrefix) {
     for (var i=0; i<form.elements.length; i++) {
         if ((form.elements[i].type == "text") && (form.elements[i].name.indexOf(namePrefix) > -1)) {
                if (trim(getValue(form.elements[i])) == "") {
                 return true;
             }
         }
     }
     return false;
}

//return true if form field exists with given name
// better way --> if (document.myform.myfield) return true;
function isFormFieldExist(form, fieldName) {

     for (var i=0; i<form.elements.length; i++) {
        if (form.elements[i].name == fieldName) {
            return true;
        }
    }
    return false;
}

  var AUSTRALIA_CODE = '1100';
  var AUSTRALIA_NAME = 'AUSTRALIA';
  var AUSTRALIA_NAME_DISPLAY = 'Australia';

  function isAustralia(country) {
    if (country != null) {
      country = trim(country);
      if ((country == AUSTRALIA_CODE) || (country.toUpperCase() == AUSTRALIA_NAME)) {
        return true;
      }
    }
    return false;
  }

  /* Returns true if the specified String contains a number, otherwise false.  */
  var NUMERALS = "0123456789";
  function containsNumber(pString) {
      if (pString == null) {
          return false;
      }
      pString = trim(pString);
      if (pString == "") {
          return false;
      }
      var nextChar;
      for (var i = 0; i < pString.length; i++) {
          nextChar = pString.charAt(i);
          if (NUMERALS.indexOf(nextChar) > -1) {
              return true;
          }
      }
      return false;
  }

  /* Returns true if the specified String contains a letter (case insensitive), otherwise false.  */
  var LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  function containsLetter(pString) {
      if (pString == null) {
          return false;
      }
      pString = trim(pString);
      if (pString == "") {
          return false;
      }
      var nextChar;
      pString = pString.toUpperCase();
      for (var i = 0; i < pString.length; i++) {
          nextChar = pString.charAt(i);
          if (LETTERS.indexOf(nextChar) > -1) {
              return true;
          }
      }
      return false;
  }

  /* Return true if password is atleast 6 characters long and contains atleast 1 digit and 1 letter */
  function isValidPassword(pPassword) {

    if (pPassword == null) {
        return false;
    }
    pPassword = trim(pPassword);
    if (pPassword == "") {
        return false;
    }

    pPassword = pPassword.toLowerCase();
    len = pPassword.length;
    
    if (len >=6 && len <= 10) {
        if (hasLetter(pPassword) && hasDigit(pPassword)) {
            return true;
        }
     }

     return false;
  }
  
  /* Country names can't contain numbers, but nulls and blanks are OK */
  function isValidCountryName(pCountry) {
    if (pCountry == null) {
        return true;
    }
    pCountry = trim(pCountry);
    if (pCountry == "") {
        return true;
    }
    return !containsNumber(pCountry);
  }

  function validateState(invokingObject, country, state, stateOther) {
      if (invokingObject == 'country') {
          if (isAustralia(getValue(country))) {
              setValue(stateOther, '');
              if (getValue(state) == "OTHER") {
                  setValue(state, '');
              }
          } else if (getValue(country) == '') {
              setValue(state, '');
              setValue(stateOther, '');
          } else {
              setValue(state, 'OTHER');
          }
      } else if (invokingObject == 'state') {
          if (getValue(state) != '' && getValue(state) != 'OTHER') {
              setValue(country, AUSTRALIA_NAME_DISPLAY);
          } else {
             setValue(country, '');
          }
      }
      return false;
  }

//if email entered, make sure it is in correct format.
function validateEmail(email, emailRepeated) {
    if (email != '' || emailRepeated != '') {
        if (!isValidEmailAddr(email)) {
        	alert('Your email address is not valid. Enter a\nsingle correct email address or clear it.');
        	return false;
      } else if (email != emailRepeated) {
          alert('Your email and repeated email addresses do not match.\nClear or enter same email address in both fields.');
          return false;
      }
    }
    return true;
}

//Validate email and only allow a single email address.
function isValidEmailAddr(email) {

		emailAddr = trim(email);
    if (emailAddr.length==0) {
        return true;
    }
    if (emailAddr.indexOf("@") < 1) { //  must contain @, and it must not be the first character
        return false;
    } else if (emailAddr.lastIndexOf(".") <= emailAddr.indexOf("@")) {  // last dot must be after the @
        return false;
    } else if (emailAddr.lastIndexOf("@") == emailAddr.length-1) {  // @ must not be the last character
        return false;
    } else if (emailAddr.indexOf("..") >=0) { // two periods in a row is not valid
    	return false;
    } else if (emailAddr.lastIndexOf(".") == emailAddr.length-1) {  // . must not be the last character
        return false;
		} else if (getStringCount(emailAddr, '@') > 1) {		//allow a single email address.
			return false;
		} else if (!containsLetter(emailAddr.substring(emailAddr.length-1))) {		//last character must be an alpha character.
			return false;
		}
    return true;
}

function getStringCount(sourceString, searchString) {

      srcString = sourceString;
        count = 0;
        i = srcString.indexOf(searchString);

        while(i >= 0) {
            count++;
            srcString = srcString.substring(i+1);
            i = srcString.indexOf(searchString);
        }
        return count;
}

function daysInMonth(month, year) {
    switch (month) {
        case  4 :
        case  6 :
        case  9 :
        case 11 :
            return 30;
        case  2 :
            return (isLeap(year)) ? 29 : 28;
        default :
            return 31;
    }
}

function isLeap(year) {
    return (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0);
}

function checkMandatoryDateField(form, name) {
    return checkDateField(form, name, true);
}

function checkDateField(form, name, mandatory) {
    var day = getValue(eval(form + '.' + name + '_Day'));
    var month = getValue(eval(form + '.' + name + '_Month'));
    var year = getValue(eval(form + '.' + name + '_Year'));
    if (day == '' && month == '' && year == '') {
        if (mandatory == null || !mandatory) {
            return true;
        } else {
            alert('Enter a date');
            focusOn(eval(form + '.' + name + '_Day'));
            return false;
        }
    }
    var opt = (mandatory == null || !mandatory) ? ' or leave the entire date blank' : '';
    if (day == '') {
        alert('Enter a day' + opt);
        focusOn(eval(form + '.' + name + '_Day'));
        return false;
    } else if (month == '') {
        alert('Select a month' + opt);
        eval(form + '.' + name + '_Month').focus();
        return false;
    } else if (year == '') {
        alert('Select a year' + opt);
        focusOn(eval(form + '.' + name + '_Year'));
        return false;
    }

    var iDay = parseInt(day, 10);
    var iMonth = parseInt(month, 10);
    var iYear = parseInt(year, 10);
    if (isNaN(iDay) || iDay < 1 || iDay > daysInMonth(iMonth, iYear)) {
        alert('Enter a valid date');
        focusOn(eval(form + '.' + name + '_Day'));
        return false;
    } else if (isNaN(iYear) || iYear < 1800 || iYear > 2100) {
        alert('Enter a valid year after 1800');
        focusOn(eval(form + '.' + name + '_Year'));
        return false;
    }
    return true;
}

// validation for optional groups that must be validated as a group
function Group(name_, mandatory_, error_) {
    this.name = name_;
    this.mandatory = mandatory_;
    this.error = error_;
}
function validateGroup(group, suffix) {
    var any = false;
    var i;
    for (i = 0; i < group.length; i++) {
        if (getValue(eval(group[i].name + suffix)).length > 0) {
            any = true;
        }
    }
    if (any) {
        for (i = 0; i < group.length; i++) {
            if (group[i].mandatory) {
                if (!checkMandatoryField(eval(group[i].name + suffix), group[i].error)) return false;
            }
        }
    }
    return true;
}
function isEmptyGroup(group, suffix) {
    var any = false;
    var i;
    for (i = 0; i < group.length; i++) {
        if (getValue(eval(group[i].name + suffix)).length > 0) {
            any = true;
        }
    }
    if (any) {
        for (i = 0; i < group.length; i++) {
            if (eval(group[i].name + suffix) != '') return false;
        }
    }
    return true;
}
function clearGroupValues(group, suffix) {
    for (i = 0; i < group.length; i++) {
        setValue(eval(group[i].name + suffix), "");
    }
}

function SaveField(name_, value_) {
    this.name = name_;
    this.oldValue = value_;
}

function saveValues(fields) {
    for (var i = 0; i < fields.length; i++) {
        fields[i].oldValue = getValue(eval(fields[i].name));
        setValue(eval(fields[i].name), "");
    }
}


function restoreValues(fields) {
    for (var i = 0; i < fields.length; i++) {
        setValue(eval(fields[i].name), fields[i].oldValue);
    }
}

function resetField(field) {
    setValue(field, field.defaultValue);
}

function suffixNumber(value) {
  var result = '';
  if ((value != null) && (value.length > 0)) {
    var number = parseInt(value);
    var lastDigit = parseInt(value.charAt(0))
    switch(lastDigit) {
      case 1: {
        if ((number % 100) == 1) {
          return value + 'st';
        } else {
          return value + 'th';
        }
        break;
      }
      case 2: {
        return value + 'nd';
        break;
      }
      case 3: {
        return value + 'rd';
        break;
      }
      default: {
        return value + 'th';
        break;
      }
    }
  }
  return result;
}

/**
 * The following function assumes that there are 3 date entry fields (for day, month and year)
 * and a hidden "whole date" field.  The assumed naming convention is that the whole date field
 * has the name specified in pDateFieldName and that the individual component field parts have
 * names made up of the name specified in pDateFieldName with _Day or _Month or _Year appended.
 * The function takes the values in the component fields and uses them to construct a string
 * that is loaded into the "whole date" field.  No validation is done as this is assumed to be
 * performed by the checkDateField() function.
 */
function loadDate(pFormName, pDateFieldName) {
    var day   = getValue(eval(pFormName + '.' + pDateFieldName + '_Day'));
    var month = getValue(eval(pFormName + '.' + pDateFieldName + '_Month'));
    var year  = getValue(eval(pFormName + '.' + pDateFieldName + '_Year'));
    setValue(eval(pFormName + '.' + pDateFieldName), day + '/' + month + '/' + year);
}

/**
 * The following function assumes that there are 3 date entry fields (for day, month and year).
 * The assumed naming convention is that the whole date field has the name specified in
 * pDateFieldName and that the individual component field parts have names made up of the name
 * specified in pDateFieldName with _Day or _Month or _Year appended.
 * The function takes the values in the component fields and simply checks that each one is
 * numeric.  The function returns true if this process succeeds, false otherwise.
 */
function validateDate(pFormName, pDateFieldName, pErrorMsg) {
    var day   = getValue(eval(pFormName + '.' + pDateFieldName + '_Day'));
    var month = getValue(eval(pFormName + '.' + pDateFieldName + '_Month'));
    var year  = getValue(eval(pFormName + '.' + pDateFieldName + '_Year'));
    var number = new Number(day);
    if (number == 0) {
        alert(pErrorMsg);
        focusOn(eval(pFormName + '.' + pDateFieldName + '_Day'));
        return false;
    }
    number = new Number(month);
    if (number == 0) {
        alert(pErrorMsg);
        focusOn(eval(pFormName + '.' + pDateFieldName + '_Month'));
        return false;
    }
    number = new Number(year);
    if (number == 0) {
        alert(pErrorMsg);
        focusOn(eval(pFormName + '.' + pDateFieldName + '_Year'));
        return false;
    }
    if (number < 1900) {
        alert ('Year must be 1900 or after.');
        return false;
    }
    return true;
}

function validAusPostcode(ausPostcode) {

    if ((!isAllDigits(ausPostcode)) || (ausPostcode.length != 4)) {
        alert("Enter a valid 4 digit Australian postcode.");
        return false;
    }
    return true;
}

//retruns the value of parameter
function getQueryParameter(param) {

  var queryString = window.location.search.substring(1);
  var params = queryString.split("&");
  for (var i=0;i<params.length;i++) {
    var pair = params[i].split("=");
    if (pair[0] == param) {
      return pair[1];
    }
  }
  return "";
}

//Show hide document element.
function show_hide(id, show) {
    element = document.getElementById(id);
    element.style.display = (('none'== element.style.display) ? '' : 'none');
}

function validateDate(field, alertMsg, format) {

    if (alertMsg == '') {
       alertMsg = 'Invalid date value.';
    }

    if (format == '') {
        format = "dd-MM-yyyy";
    }
    var date = Date.parseString(field.value, format);
    if (date == null) {
        alert(alertMsg);
        return false;
    }
    var year = date.getFullYear();
    if (year < 1900) {
        alert('Year must be 1900 or after.');
        return false;
    }

    return true;
}

function getValue(field) {
    if (field != null) {
        if (field.type == 'select-one' || field.type == 'select-multiple') {
            if (field.selectedIndex >= 0) {
                return field.options[field.selectedIndex].value;
            }
            return "";
        } else if (field.type == 'checkbox') {
            if (field.checked) {
                return 1;
            }
            else {
                return 0;
            }
        } else if (field.length != null) {
             for (var i = 0; i < field.length; i++) {
                 if (field[i].checked) {
                     return field[i].value;
                 }
             }
             return "";
        } else if (field.type == "radio") {
            if (field.checked) {
                return field.value;
            }
            else {
                return "";
            }
        } else {
            return field.value;
        }
    }
}

function setValue(field, value) {
     if (field != null) {
         if (field.type == 'select-one') {
             for (var i = 0; i < field.options.length; i++) { if (field.options[i].value == value) { field.selectedIndex = i; break; } }
         } else if (field.type == 'select-multiple') {
             for (var i = 0; i < field.options.length; i++) { if (field.options[i].value == value) { field.selectedIndex = i; break; } }
         } else if (field.type == 'checkbox') {
             field.checked = (value == '1');
         } else if (field.type == 'text') {
            field.value = value;
         } else if (field.length != null) {
             for (var i = 0; i < field.length; i++) {
                 if (field[i].value == value) {
                     field[i].checked = true;
                     break;
                 } else {
                     field[i].checked = false;
                 }
             }
         } else {
             field.value = value;
         }
     }
}

function getOption(field) {
    if (field != null) {
        if (field.type == 'select-one' || field.type == 'select-multiple') {
            if (field.selectedIndex >= 0) {
                return field.options[field.selectedIndex];
            }
        }
    }
    return null;
}

function getDescription(field) {
    var option = getOption(field);
    if (option != null) {
        return option.text;
    }
    return "";
}

function checkMandatoryField(field, message) {
    if (getValue(field) == '') {
        alert(message);
        focusOn(field);
        return false;
    }
    return true;
}

function focusOn(field) {
    try {
        if (field.length != null && field.type != 'select-one' && field.type != 'select-multiple') {
            field[0].focus();
        }
        else {
            field.focus();
        }
    } catch (e) {
       //supress error, can't focus eg if fields doesn't exist
       // or hidden etc.
    }
}

function fixURL(url) {
    url = escape(url);
    url = url.replace(/\//g, "%2f");
    return url;
}

function popup(pUrl, pWindowName, pWindowParams) {
    if (pWindowName == null) {
        pWindowName = "info";
    }
    if (pWindowParams == null) {
        pWindowParams = "location=no,resizable=yes,scrollbars=yes,toolbar=yes,status=no,width=700,height=600,top=50,left=50";
    }
    popupWindow = window.open(pUrl, pWindowName, pWindowParams);
    popupWindow.focus();
    return false;
}

/*
* sample methods to open popup window of comment style. Needs mods if used.
*/
function popupWindow(message) {

    var p=window.createPopup();
    var pbody = p.document.body;
    // pbody.style.backgroundColor="lime";
    pbody.style.border = "solid black 1px";
    pbody.innerHTML = message + " Click outside the pop-up to close.";
    p.show(150,150,200,50,document.body);
}

function scrollTop() {
	 window.scrollTo(0,0);	
}

//Return True if 'str' is all digits.
function isAllDigits(str){
    return isInValidCharSet(str,"0123456789");
}

/* Return true if strString contains a digit. */
function hasDigit(srcString) {
    for (var i=0; i<srcString.length; i++) {
        ch = srcString.charAt(i);
        if (ch >= '0' && ch <= '9') {
            return true;
        }
    }
    return false;
}

/* Return true if strString contains a alphabet letter. */
function hasLetter(srcString) {
    for (var i=0; i<srcString.length; i++) {
        ch = srcString.charAt(i);
        if (ch >= 'a' && ch <= 'z') {
            return true;
         }
    }
    return false;
} 

//Return True if 'str' is in a 'charset'.
function isInValidCharSet(str, charset) {
    var result = true;

    for (var i=0;i<str.length;i++) {
        if (charset.indexOf(str.substr(i,1)) < 0) {
            result = false;
            break;
        }
    }
    return result;
}

//Perform Luhn checksum algorithm on card number to validate it.
// Not tested for bankcard, skip LuhnCheck for bankcard for now.
function validateLuhnCheck(cardNumber, cardType) {

    cardType = cardType.toUpperCase();
    if (cardType == 'BANKCARD') {
        return true;
    }

    var result = true;

    var sum = 0;
    var mul = 1;
    var cardNumberLength = cardNumber.length;

    for (i = 0; i < cardNumberLength; i++) {
        var digit = cardNumber.substring(cardNumberLength - i - 1, cardNumberLength - i);
        var tproduct = parseInt(digit, 10) * mul;

        if (tproduct >= 10) {
            sum += (tproduct % 10) + 1;
        } else {
            sum += tproduct;
        } if (mul == 1) {
            mul++;
        } else {
            mul--;
        }
    }
    if ((sum % 10) != 0) {
        result = false;
    }

    return result;
}

//Validate card number corresponding to the card type.
// Need validation information for bankcard.
function validateCardNumber(cardNumber, cardType) {

    var result = false;
    cardType = cardType.toUpperCase();

    var cardNumberLength = cardNumber.length;
    var firstDigit = cardNumber.substring(0,1);
    var secondDigit = cardNumber.substring(1,2);
    var first4Digits = cardNumber.substring(0,4);

    switch (cardType) {
        case "VISA":
            result = ((cardNumberLength == 16) || (cardNumberLength == 13)) && (firstDigit == "4");
            break;
        case "AMEX":
            var validNums = "47";
            result = (cardNumberLength == 15) && (firstDigit == "3") && (validNums.indexOf(secondDigit)>=0);
            break;
        case "MASTERCARD":
            var validNums = "12345";
            result = (cardNumberLength == 16) && (firstDigit == "5") && (validNums.indexOf(secondDigit)>=0);
            break;
        case "DISCOVER":
            result = (cardNumberLength == 16) && (first4Digits == "6011");
            break;
        case "DINERS":
            var validNums = "068";
            result = (cardNumberLength == 14) && (firstDigit == "3") && (validNums.indexOf(secondDigit)>=0);
            break;
        case "BANKCARD":
            //Need validation informaiton.
            result =  true;
            break;
    }
    return result;
}

/**
 * Save data modifiable by the user.
 * Note: hidden input fields are not checked to avoid validation failure caused by richfaces creating hidden input fields.
 * Also note; element comparison may get out of synch if javascript action creates a new input field since the form was first loaded;
 * if such case arises, then saving/checking element name/value pair needs to be implemented.
 */
function saveFormData(form) {

    var saveData = new Array(form.elements.length);
    var elementType = "";

    for (var i = 0; i < saveData.length; i++) {

        elementType = form.elements[i].type;
        if (elementType != 'hidden' && elementType != 'submit' && elementType != 'button' && elementType != 'reset' && elementType != 'image') {
            saveData[i] = getValue(form.elements[i]);
        }
    }
    form.saveData = saveData;
    return saveData;
}

/**
 * Compare current form data with the saved values.
 * Note: hidden input fields are not checked to avoid validation failure caused by richfaces creating hidden input fields.
 * Also note; element comparison may get out of synch if javascript action creates a new input field since the form was first loaded;
 * if such case arises, then saving/checking element name/value pair needs to be implemented.
 */
function hasFormDataChanged(form, saveData, jsfValidationFailed) {
    var elementType = "";

    // Cancel check after JFS Validation failure on return from user form
	// submit.
    if (typeof(jsfValidationFailed) == 'boolean' && jsfValidationFailed) {
        return true;
    }

    // if saveData isn't defined, the form was most likely AJAX refreshed. Return true in that case.
    if (!saveData) return true;
    
    // return true if the number of elements don't match (in the case of deletes)
    if (saveData.length != form.elements.length) return true;
    
    for (var i = 0; i < saveData.length; i++) {

        elementType = form.elements[i].type;
        if (elementType != 'hidden' && elementType != 'submit' && elementType != 'button' && elementType != 'reset' && elementType != 'image') {
            if (saveData[i] != getValue(form.elements[i])) {
                return true;
            }
        }
    }
    return false;
}
 
/**
 * Restore a form's field data with previously saved values.  If confirmMessage is not null, the user is prompted with the message and given the option
 * to cancel.  If confirmMessage is null, the restore is done without prompting.
 */
function resetFormData(form, savedData, confirmMessage) {

    if (hasFormDataChanged(form, savedData)) {
        if (!confirmMessage || confirmReset(confirmMessage)) {
            var elementType = "";

            for (var i = 0; i < savedData.length; i++) {

                elementType = form.elements[i].type;
                if (elementType != 'hidden' && elementType != 'submit' && elementType != 'button' && elementType != 'reset' && elementType != 'image') {
                    setValue(form.elements[i], getValue(savedData[i]));
                }
            }
            return true;
        }
    }
    return false;
}

//returns whole string from parameter to the end of the query string.
function getParameter(URL, parameter) {
    var re = new RegExp("[?&](" + parameter + "=.*)(&|$)");
    var result = re.exec(URL);
    if (result != null) {
        return result[1];
    }
    return null;
}

function addParameter(URL, parameter) {
    if (parameter == null) {
        return URL;
    }
    var pos = URL.indexOf("?");
    if (pos >= 0) {
        URL += "&" + parameter;
    }
    else {
        URL += "?" + parameter;
    }
    // alert(URL);
    return URL;
}

function ltrim (s) {
    return s.replace( /^\s*/, "" );
}

function rtrim (s) {
    return s.replace( /\s*$/, "" );
}

function trim (s) {
    s = ltrim(s);
    return rtrim(s);
}

function FieldValue(name, value) {
    this.name = name;
    this.value = value;
}

function getURI(URL) {
    var pos = URL.indexOf("?");
    if (pos >= 0) {
        return URL.substring(0, pos);
    }
    else {
        return URL;
    }
}

function FieldValue(name, value) {
    this.name = name;
    this.value = value;
}

function add(arrayvar, item) {
    return arrayvar[arrayvar.length] = item;
}

function saveOriginalValue(form, name, value) {
    var field = add(form.originalValueList, new FieldValue(name, value));
    eval("form.originalValues." + name + " = field;");
}

function setOriginalValues(form) {
    if (form.originalValueList != null) {
        for (var i = 0; i < form.originalValueList.length; i++) {
            var field = eval("form." + form.originalValueList[i].name);
            setValue(field, form.originalValueList[i].value);
        }
    }
}

//-------------------------------------------------------------------
// commifyArray(array[,delimiter])
// Take an array of values and turn it into a comma-separated string
// Pass an optional second argument to specify a delimiter other than
// comma.
// -------------------------------------------------------------------
function commifyArray(obj,delimiter){
    if (typeof(delimiter)=="undefined" || delimiter==null) {
        delimiter = ",";
    }
    var s="";
    if(obj==null||obj.length<=0){return s;}
    for(var i=0;i<obj.length;i++){
        s=s+((s=="")?"":delimiter)+obj[i].toString();
    }
    return s;
}

function setButtonText(button, text) {
    if ((button) && (button != undefined) && (button != null) && (button.type == 'button')) {
        if (document.all) { // IE
            button.innerText = text;
        } else {  // Firefox
            button.textContent = text;
        }
    }
}

function getButtonText(button) {
    if ((button) && (button != undefined) && (button != null) && (button.type == 'button')) {
        if (document.all) { // IE
            return button.innerText;
        } else {  // Firefox
            return button.textContent;
        }
    }
}


function noDataChangeAlert() {
    alert('Save request cancelled.\n\nData has not been modified or changes\nhave already been saved.');
}

function confirmUpdate(msg) {
    if (msg == null) {
        msg = "Click Ok to save modified data.";
    }
    return confirm(msg);
}

function confirmUpdateAuto(msg) {
    if (msg == null) {
        msg = "Click Ok to automatically save modified data and continue.";
    }
    return confirm(msg);
}

function confirmEmail(msg){
	if(msg == null){
		msg = "Click Ok to send feedback email.";
	}
	return confirm(msg);
}

function confirmInsert(msg) {
    if (msg == null) {
        msg = "Click Ok to add a new record.";
    }
    return confirm(msg);
}

function confirmDelete(msg) {
    if (msg == null) {
        msg = "Click Ok to delete this record.";
    }
    return confirm(msg);
}

function confirmReset(msg) {
    if (msg == null) {
        msg = "Data has been modified but not saved.\n\n" +
        	  "Click Ok to lose changes and refresh page.";
    }
    return confirm(msg);
}

function confirmCancel(msg) {
    if (msg == null) {
        msg = "Data has been modified but not saved.\n\n" +
              "Click Ok to lose changes and continue.";
    }
    return confirm(msg);
}

function statusBarMessage(msg) {
    window.status = msg;
}

/*
* Extract and return entityId (ID)from entityIdValue (EntityName:ID)
*/
function getEntityId(entityIdValue) {

    if (entityIdValue.indexOf(":") < 0) {
        return entityIdValue;
    } else {
        return entityIdValue.substring(entityIdValue.indexOf(":")+1);
    }    
}

function isBrowserCompatible() {

	//alert(navigator.userAgent);

	var browserMsg = '';
	var version = parseFloat(getFireFoxVersion());
	if (version > 0) {
        if (version < 3) {
        	browserMsg = "version of Mozilla Firefox";
        }
	} else {
		version = parseFloat(getInternetExplorerVersion());
		if (version > 0) {
		    if (version < 7) {
		    	browserMsg = "version of Internet Explorer";
		    }
		} else {
			version = parseFloat(getSafariVersion());
			if (version > 0) {
		        if (version < 528.00) {
		        	browserMsg = "version of Safari";
		        }
		    } else {
		    	browserMsg = "Internet browser";
		    }
		}
	}
    return browserMsg;
}

function getFireFoxVersion() {
	
	var version = 0;
	
    //Test for Firefox/x.x or Firefox x.x (ignoring remaining digits);
    if (/Firefox[\/\s](\d+\.\d+)/.test(navigator.userAgent)) { 
    	version = new Number(RegExp.$1); //capture x.x portion and store as a number
    }
    return version;
}

function getInternetExplorerVersion() {
	
	var version = 0;
	
	//test for MSIE x.x;
	if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) {  
		version = new Number(RegExp.$1) //capture x.x portion and store as a number
    }
    return version;
}

function getSafariVersion() {
	
	var version = 0;
	
    //Test for Safari/x.x or Safar x.x (ignoring remaining digits);
    if (/Safari[\/\s](\d+\.\d+)/.test(navigator.userAgent)) { 
    	version = new Number(RegExp.$1); //capture x.x portion and store as a number
    }
    return version;
}

/**
 * Alternative for innerHTML to avoid DOM update error due to a bug in some browsers (eg Safari).
 * @param element the DOM element where the HTML will be loaded
 * @param HTML the string of valid HTML code
 * @param clearfirst if false, existing child nodes of the element will be retained
 * @return
 */
function betterInnerHTML(element, HTML, clearfirst) {
	 
	// load the HTML as XML
	function Load(xmlString) {
		var xml;
		if (typeof DOMParser != "undefined") xml = (new DOMParser()).parseFromString(xmlString, "application/xml");
		else {
			var ieDOM = ["MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XMLDOM"];
			for (var i = 0; i < ieDOM.length && !xml; i++) {
				try { xml = new ActiveXObject(ieDOM[i]); xml.loadXML(xmlString); }
				catch(e) {}
			}
		}
		return xml;
	}
	
	// create node event
	function AddEvent(node, evt, fn) { node[evt] = function() { return eval(fn); }; }

	// recursively copy the XML into the DOM
	function Copy(domNode, xmlDoc, level) {

		if (typeof level == "undefined") level = 1;
		if (level > 1) {

			if (xmlDoc.nodeType == 1) {

				// element node
				var thisNode = document.createElement(xmlDoc.nodeName);

				// attributes
				var handler = {};
				for (var a = 0, attr = xmlDoc.attributes.length; a < attr; a++) {
					var aName = xmlDoc.attributes[a].name, aValue = xmlDoc.attributes[a].value, evt = (aName.substr(0,2) == "on");
					if (evt) handler[aName] = aValue;
					else {
						switch (aName) {
							case "class": thisNode.className = aValue; break;
							case "for": thisNode.htmlFor = aValue; break;
							default: thisNode.setAttribute(aName, aValue);
						}
					}
				}

				// append node
				domNode = domNode.appendChild(thisNode);

				// attach events
				for (evt in handler) AddEvent(domNode, evt, handler[evt]);
				
			}
			else if (xmlDoc.nodeType == 3) {
				// text node
				var text = (xmlDoc.nodeValue ? xmlDoc.nodeValue : "");
				var test = text.replace(/^\s*|\s*$/g, "");
				if (test.length < 7 || (test.indexOf("<!--") != 0 && test.indexOf("-->") != (test.length - 3))) {
					domNode.appendChild(document.createTextNode(text));
				}
			}
		}

		// do child nodes
		for (var i = 0, j = xmlDoc.childNodes.length; i < j; i++) Copy(domNode, xmlDoc.childNodes[i], level+1);
	}

	// load the XML and copies to DOM
	HTML = "<root>"+HTML+"</root>";
	var xmlDoc = Load(HTML);
	if (element && xmlDoc) {
		if (clearfirst != false) while (element.lastChild) element.removeChild(element.lastChild);
		Copy(element, xmlDoc.documentElement);
	}
}

