var NUMBERS = "0123456789";
var LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

/**
 * Add Methods to the Standard String
 */
String.prototype.startsWith = stringStartsWith;

/**
 * Test whether the String starts with the supplied String
 *
 * @param str The Test String
 * @return true if the String starts with str
 */
function stringStartsWith (str) {
  return this.substring(0,str.length) == str;
} //stringStartsWith

/**
 * Test whether the supplied character is part of the supplied
 * set
 *
 * @param ch The character in question
 * @param set The set of valid characters
 * @return true if ch is in set
 */
function isIn (ch,set) {
  return set.indexOf(ch) != -1;
} //isIn

/**
 * Return the portion of the supplied string that contains only
 * characters in the supplied set.
 *
 * @param str The String to be stripped
 * @param set The set of valid characters
 * @return the stripped string
 */
function onlyContains (str,set) {
  var ch;
  var buf = "";
  for(i = 0;i < str.length;i++) {
    ch = str.charAt(i);
    if(isIn(ch,set)) {
      buf += ch;
    }
  }
  return buf;
} //onlyContains

/**
 * Test whether the supplied character is a Number
 *
 * @param ch The Character
 * @return True if the Character is a Numeric Digit
 */
function isNumber (ch) {
  return isIn(ch,NUMBERS);
} //isNumber

/**
 * Return a string containing only the numbers from the supplied string.
 *
 * @param str The String to be stripped
 * @return the characters from str that are digits
 */
function onlyNumbers (str) {
  return onlyContains(str,NUMBERS);
} //onlyNumbers

/**
 * Test whether the supplied string is numeric
 *
 * @param str The String to be tested
 * @return true if str only contains numeric digits
 */
function isNumeric (str) {
  return onlyNumbers(str).length == str.length;
} //isNumeric

/**
 * Test whether the supplied character is an Upper or Lower Case Letter
 *
 * @param ch The Character
 * @return True if the Character is a Letter
 */
function isLetter (ch) {
  return isIn(ch,LETTERS);
} //isLetter

/**
 * Return a string containing only Upper or Lower case letters from the
 *  supplied string.
 *
 * @param str The String to be Stripped
 * @return the characters from str that are letters
 */
function onlyLetters (str) {
  return onlyContains(str,LETTERS);
} //onlyLetters

/**
 * Test whether the supplied string is alphabetic
 *
 * @param str The String to be tested
 * @return true if str only contains letters
 */
function isAlphabetic (str) {
  return onlyLetters(str).length == str.length;
} //isAlphabetic

/**
 * Test whether the supplied string is alpha-numeric
 *
 * @param str The String to be tested
 * @return true if str only contains letters and numbers
 */
function isAlphaNumeric (str) {
  return onlyContains(str,NUMBERS + LETTERS).length == str.length;
} //isAlphaNumeric

/**
 * Format the supplied field value as a 10-digit phone number.
 *
 * param fld The Field to be formatted as a phone number
 */
function formatPhone (fld) {
  if(!isFieldEmpty(fld)) {
    var str = onlyNumbers(fld.value);
    if(str.length == 10) {
      str = ("(" + str.substring(0,3) + ") " + str.substring(3,6) + "-" + str.substring(6,10));
      fld.value = str;
      return true;
    }
  }
  return false;
} //formatPhone

/**
 * Format the supplied field value as a Date, with the supplied format mask.
 *
 * param fld The Field to be formatted as a Date
 * param fmt The Format to use on the field.
 */
function formatDate (fld,fmt) {
  var format = "mm/dd/yyyy";
  if(fmt != null) format = fmt;
  var str = onlyNumbers(fld.value);
  var tempFormat = onlyLetters(format);
  if(str.length == tempFormat.length) {
    str = (str.substring(0,2) + "/" + str.substring(2,4) + "/" + str.substring(4,8));
    fld.value = str;
  } else {
    fld.value = str;
  }
} //formatDate

/**
 * If the supplied condition is not true, alert the user with the supplied
 *  message and give the supplied field the focus.
 *
 * @param condition The Assertion Condition
 * @param msg The Message to Alert if <code>condition</code> is false
 * @param fld The Field to give focus if <code>condition</code> is false
 * @return The <code>condition</code>
 */
function assert (condition,msg,fld) {
  if(!condition) {
    alert(msg);
    if(fld != null) {
      fld.focus();
    }
  }
  return condition;
} //assert

/**
 * Test whether the text field value is empty
 *
 * @param fld The Field to Test
 * @return true if fld contains no value
 */
function isFieldEmpty (fld) {
  return (fld.value == '') || (fld.value == ' ');
} //isFieldEmpty

/**
 * Retrieve the Select Value
 *
 * @param fld The Field to Access
 * @return The value of the Field
 */
function selectValue (fld) {
  return fld.options[fld.selectedIndex].value;
} //selectValue

/**
 * Retrieve the Value for the chosen Radio Button
 *
 * @param fld The Radio Button Group
 * @return The Chosen Radio Button Value
 */
function radioValue (fld) {
  for(var i = 0; i < fld.length;i++) {
    if(fld[i].checked) {
      return fld[i].value;
    }
  }
  return fld[0].value;
} //radioValue

/**
 * Retrieve the index for the checked Radio Button
 *
 * @param fld The Radio Button Group
 * @return The Checked Radio Button index (or -1 if none checked)
 */
function radioIndex (fld) {
  for(var i = 0;i < fld.length;i++) {
    if(fld[i].checked) {
      return i;
    }
  }
  return -1;
} //radioIndex

/**
 * Test whether a group of radio buttons have a selection
 *  @param buttonGroup The group of radios to be tested
 */
function isRadioEmpty(buttonGroup){
  for (i=0; i < buttonGroup.length; i++) {
    if (buttonGroup[i].checked == true) {
      return false;
    }
  }
  return true;
}

/**
 * Test whether a select box has a valid selection
 *
 * @param fld The Select Field to Test
 * @return true if fld contains no value
 */
function isSelectEmpty (fld) {
  return (fld.selectedIndex == -1) || (selectValue(fld) == '') || (selectValue(fld) == ' ');
} //isSelectEmpty

/**
 * Return the Index of the specified value within the select box
 *
 * @param sel The Select Box Object
 * @param val The Value to find
 * @return The index of the option (or -1 if not found)
 */
function indexOfOption (sel,val) {
  for(var i = 0;i < sel.options.length;i++) {
    if(sel.options[i].value == val) {
      return i;
    }
  }
  return -1;
} //indexOfOption

/**
 * Test whether the supplied select box contains the specified value
 *
 * @param sel The Select Box Object
 * @param val The Value to look for
 * @return true if one of the options in the Select Box matches val
 */
function hasOption (sel,val) {
  return indexOfOption(sel,val) != -1;
} //hasOption

/**
 * Test whether the supplied Year Month and Day consitute a valid date
 *
 * @param year The Year Number
 * @param month The Month Number
 * @param day The Day of the Month
 */
function isValidDate (year,month,day) {
  return (new Date(year,month,day).getDate() == day);
} //isValidDate

/**
 * Test whether a Field contains a valid Date
 *
 * @param form The Form Object containing the Date Field
 * @param name The Name of the Date Field
 * @return new Date
 */
function getDateField (form,name) {
  var format = form.elements[name + "Format"].value;
  if((format.indexOf('|') == -1) && (format.indexOf('#') == -1)) {
    return !isSelectEmpty(form.elements[name]);
  } else {
    var ch;
    var val;
    var fld;
    var day = 1;
    var month = 0;
    var year = 1901;
    var prev = '|';
    var sel = true;
    var now = new Date();
    for(var i = 0;i < format.length;i++) {
      ch = format.charAt(i);
      if(ch != prev) {
        if(ch == '|') {
          sel = true;
        } else if(ch == '#') {
          sel = false
        } else {
          fld = form.elements[name + ch];
          if(sel) {
            if(isSelectEmpty(fld)) {
              return false;
            } else {
              val = selectValue(fld);
            }
          } else {
            if(isFieldEmpty(fld) || isNaN(fld.value)) {
              return false;
            } else {
              val = fld.value;
            }
          }
          switch(ch) {
            case 'd':
              day = val;
              break;
            case 'M':
              month = val;
              break;
            case 'y':
              year = val;
              if(year.length == 2) {
                year = ((year > (now.getYear() % 100)) ? 19 : 20) + year;
                fld.value = year;
              }
              break;
          }
        }
        prev = ch;
      }
    }
    return new Date(year,month,day);
  }
} //getDateField

/**
 * Test whether a Field contains a valid Date
 *
 * @param form The Form Object containing the Date Field
 * @param name The Name of the Date Field
 * @return true if valid
 */
function isValidDateField (form,name) {
  var format = form.elements[name + "Format"].value;
  if((format.indexOf('|') == -1) && (format.indexOf('#') == -1)) {
    return !isSelectEmpty(form.elements[name]);
  } else {
    var ch;
    var val;
    var fld;
    var day = 1;
    var month = 0;
    var year = 1901;
    var prev = '|';
    var sel = true;
    var now = new Date();
    for(var i = 0;i < format.length;i++) {
      ch = format.charAt(i);
      if(ch != prev) {
        if(ch == '|') {
          sel = true;
        } else if(ch == '#') {
          sel = false
        } else {
          fld = form.elements[name + ch];
          if(sel) {
            if(isSelectEmpty(fld)) {
              return false;
            } else {
              val = selectValue(fld);
            }
          } else {
            if(isFieldEmpty(fld) || isNaN(fld.value)) {
              return false;
            } else {
              val = fld.value;
            }
          }
          switch(ch) {
            case 'd':
              day = val;
              break;
            case 'M':
              month = val;
              break;
            case 'y':
              year = val;
              if(year.length == 2) {
                year = ((year > (now.getYear() % 100)) ? 19 : 20) + year;
                fld.value = year;
              }
              break;
          }
        }
        prev = ch;
      }
    }
    return isValidDate(year,month,day);
  }
} //isValidDateField

/**
 * Test whether a Field contains a valid Birth Date
 *
 * @param form The Form Object containing the Date Field
 * @param name The Name of the Date Field
 * @return true if valid
 */
function isValidBirthDateField (form,name) {
  var format = form.elements[name + "Format"].value;
  if((format.indexOf('|') == -1) && (format.indexOf('#') == -1)) {
    return !isSelectEmpty(form.elements[name]);
  } else {
    var ch;
    var val;
    var fld;
    var day = 1;
    var month = 0;
    var year = 1901;
    var prev = '|';
    var sel = true;
    var now = new Date();
    for(var i = 0;i < format.length;i++) {
      ch = format.charAt(i);
      if(ch != prev) {
        if(ch == '|') {
          sel = true;
        } else if(ch == '#') {
          sel = false
        } else {
          fld = form.elements[name + ch];
          if(sel) {
            if(isSelectEmpty(fld)) {
              return false;
            } else {
              val = selectValue(fld);
            }
          } else {
            if(isFieldEmpty(fld) || isNaN(fld.value)) {
              return false;
            } else {
              val = fld.value;
            }
          }
          switch(ch) {
            case 'd':
              day = val;
              break;
            case 'M':
              month = val;
              break;
            case 'y':
              year = val;
              if(year.length == 1) {
                year = '0' + year;
              }
              if(year.length == 2) {
                year = ((year > (now.getYear() % 100)) ? 19 : 20) + year;
                fld.value = year;
              }
              break;
          }
        }
        prev = ch;
      }
    }
    var date = new Date(year,month,day);
    var then = new Date();
    then.setFullYear(then.getFullYear() - 120);
    if(date < then) {
      return false;
    }
    if(date > now) {
      return false;
    }
    return (date.getDate() == day);
  }
} //isValidBirthDateField

/**
 * Test whether the supplied Email Address is valid
 *
 * @param addr The EMail Address String
 * @return true if valid
 */
function isValidEMail (addr) {
  var at = addr.indexOf('@');
  if(at > 0) {
    var dot = addr.indexOf('.',at);
    if(dot > at + 1) {
      return addr.length > dot + 1;
    }
  }
  return false;
} //isValidEMail

/**
 * Test whether the supplied string is a valid US postal code
 *
 * @param zip The Postal Code to check
 * @return true if valid
 */
function isValidZip (zip) {
  if(zip.length > 0) {
    if(onlyContains(zip,NUMBERS + '-').length == zip.length) {
      if((zip.length == 5) || ((zip.length == 10) && (zip.charAt(5) == '-'))) {
        return true;
      }
    }
  }
  return false;
} //isValidZip

/**
 * Set the specified named image to the supplied Image
 *
 * @param name The Image Tag Name
 * @param src The Image Tag Source File Name
 */
function setImage (name,src) {
  if(document.images) {
    document.images[name].src = src;
  }
} //setImage

/**
 * Set the Status Bar to the Supplied Message
 *
 * @param msg The Status Bar Message
 * @return true
 */
function setStatus (msg) {
  status = msg;
  return true;
} //setStatus

/**
 * Reset the Status Bar
 *
 * @return true
 */
function resetStatus () {
  status = '';
  return true;
} //resetStatus

/**
 * Move us out of the popup or frame into the parent
 */
function unpop () {
  if(opener) {
    if(typeof opener.location.href != "unknown") {
      if(document.images) {
        opener.location.replace(window.location.href);
      } else {
        opener.location.href = window.location.href;
      }
      window.close();
    }
  } else if(self != top) {
    if(document.images) {
      top.location.replace(window.location.href);
    } else {
      top.location.href = window.location.href;
    }
    window.close();
  }
} //unpop

/**
 * Get rid of line feeds and double spaces
 */
function trimLineFeeds (str) {
  var buf = "";
  var space = " ";
  var lastCh;
  var ch;
  for(i = 0;i < str.length;i++) {
    lastCh = ch;
    ch = str.charAt(i);
    if(ch < space) ch = space;
    if(!((ch == space) && (lastCh == space))) buf += ch;
  }
  return buf;
} //trimLineFeeds

function isInteger(s){
  var i;
    for (i = 0; i < s.length; i++){
        // Check that current character is number.
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    // All characters are numbers.
    return true;
}

function stripCharsInBag(s, bag){
  var i;
    var returnString = "";
    // Search through string's characters one by one.
    // If character is not in bag, append to returnString.
    for (i = 0; i < s.length; i++){
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }
    return returnString;
}

function daysInFebruary (year){
  // February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
}
function DaysArray(n) {
  for (var i = 1; i <= n; i++) {
    this[i] = 31
    if (i==4 || i==6 || i==9 || i==11) {this[i] = 30}
    if (i==2) {this[i] = 29}
   }
   return this
}

function isDate(dtStr){// valid date formate is mm/dd/yyyy
 // Declaring valid date character, minimum year and maximum year
  var dtCh= "/";
  var minYear=1900;
  var maxYear=2100;

  var daysInMonth = DaysArray(12)
  var pos1=dtStr.indexOf(dtCh)
  var pos2=dtStr.indexOf(dtCh,pos1+1)
  var strMonth=dtStr.substring(0,pos1)
  var strDay=dtStr.substring(pos1+1,pos2)
  var strYear=dtStr.substring(pos2+1)
  strYr=strYear
  if (strDay.charAt(0)=="0" && strDay.length>1) strDay=strDay.substring(1)
  if (strMonth.charAt(0)=="0" && strMonth.length>1) strMonth=strMonth.substring(1)
  for (var i = 1; i <= 3; i++) {
    if (strYr.charAt(0)=="0" && strYr.length>1) strYr=strYr.substring(1)
  }
  month=parseInt(strMonth)
  day=parseInt(strDay)
  year=parseInt(strYr)
  if (pos1==-1 || pos2==-1){
    return false
  }
  if (strMonth.length<1 || month<1 || month>12){
    return false
  }
  if (strDay.length<1 || day<1 || day>31 || (month==2 && day>daysInFebruary(year)) || day > daysInMonth[month]){
    return false
  }
  if (strYear.length != 4 || year==0 || year<minYear || year>maxYear){
    return false
  }
  if (dtStr.indexOf(dtCh,pos2+1)!=-1 || isInteger(stripCharsInBag(dtStr, dtCh))==false){
    return false
  }
return true
}


function formatCurrency(num) {
  if (num.length > 3) {
    if (num.indexOf(".") == -1) {
      num = num.substring(0,3) + '.' + num.substring(3,num.length);
    }
  }
  var num = num.toString().replace(/\$|\,/g,'');
  if(isNaN(num))
  num = "0";

  sign = (num == (num = Math.abs(num)));
  num = Math.floor(num*100+0.50000000001);
  cents = num%100;
  num = Math.floor(num/100).toString();
  if(cents<10)
    cents = "0" + cents;
  for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
    num = num.substring(0,num.length-(4*i+3))+','+
    num.substring(num.length-(4*i+3));
  if (num == "0") {
    num = "";
    return num
  } else {
    return (((sign)?'':'-') + num + '.' + cents);
  }

}

function checkPoll(form) {
  var answered = false;
  for (var i=0, j=form.elements.length; i<j; i++) {
     field = form.elements[i].type;
    if (field == "checkbox" || field == "radio") {
      if (form.elements[i].checked) {
          return true;
          answered = true;
      }
    }
  }
  if (!answered == true) {
    alert("Please select a survey option before clicking Submit");
    return false;
  }
}

/**
 * Creates a list of new Option Objects
 *  The value and display text will be the same.
 *
 * @param ary An Array of Strings to build the option tags.
 * @param opt The select tag object to add option tags to.
 */
function createOptions (ary,opt) {
  for(i=0;i<ary.length;i++){
    opt[opt.length]=newOpt(ary[i],ary[i]);
  }
}

/**
 * Creates a new Option Object
 *
 * @param value The value of the option tag.
 * @param display The text to display in the option tag.
 * @return the new Option Object
 */
function newOpt (value,display) {
  return new Option(value,display);
}

/**
 * verifies with a user that they want to leave the plan application and lose any data they have entered
 *
 * @param url   The url to jump to if the user confirms that they want to leave.
 */
function LeaveApplication(url){
  if (confirm("Leaving this page will delete all previously entered data.")) {
    document.location = url;
  }
}

