function toUpper(e) {

  // a letter, and then one, none or more letters
  var pattern = /(\w)(\w*)/;

  // split the sentence into an array of words
  var a = e.split(/\s+/g);

  for (i = 0; i < a.length; i ++ ) {

    // just a temp variable to store the fragments in.
    var parts = a[i].match(pattern);

    var firstLetter = parts[1].toUpperCase();
    var restOfWord = parts[2].toLowerCase();

    // re-assign it back to the array and move on
    a[i] = firstLetter + restOfWord;
  }

  // join it back together
  return a.join(' ');
}

function mod_ten(cc_number, message_div_id, link_root, cc_type_selected, submission_button_id) {
  var valid         = "0123456789"          // Valid digits in a credit card number
  var len           = cc_number.length;     // The length of the submitted cc number
  var cc_num_string = cc_number.toString(); // string of cc_number
  var is_valid      = false;                // by default assume it is NOT a valid cc
  var check_cc_type = false;                // Determine whether or not a CC type check is required
  var has_bad_chars = false;
  var cc_type;
  var prefix;
  var cc_num_int;

  // Determine if any credit card number is set, or if the credit card number is masked
  if (cc_num_string.length == 0 || cc_num_string.substring(0,4) == '****') {
    // Nothing to test. Clear the Mod-10 check image
    eval("document.getElementById('" + message_div_id + "').innerHTML = ''");

    // If a submission button was passed in, enable it.
    if (typeof(submission_button_id) != 'undefined') {
      // Enable the button
      document.getElementById(submission_button_id).disabled = '';
    }

    return is_valid;
  }

  // Retrieve the value from the selection pull down
  if (typeof(cc_type_selected) != 'undefined') {
    // Retrieve the menu object
    menu_object   = document.getElementById(cc_type_selected);

    // Get the credit card type from the full name in the innerHTML.
    // This is lame, but different customers us different CC codes, so the
    // value (which only stores the code) cannot be used.
    cc_type_name  = menu_object.options[menu_object.selectedIndex].innerHTML;
    cc_type_name  = toUpper(cc_type_name);

    // Flag the system to perform a CC type check
    check_cc_type = true;
  }

  // determine credit card type (MC, Visa, Amex and Disco only)
  if (cc_num_string.substring(0, 2) >= "51" && cc_num_string.substring(0, 2) <= "55") {
    cc_type = 'Mastercard';
  }
  else if (cc_num_string.substring(0,1) == "4") {
    cc_type = 'Visa';
  }
  else if (cc_num_string.substring(0,2) == "34" || cc_num_string.substring(0,2) == "37") {
    cc_type = 'American Express';
  }
  else if (cc_num_string.substring(0,4) == "6011") {

    // there are a couple different ways discover card is expressed, make them consistent.
    if (cc_type_name == 'Discover Card') {
      cc_type_name = 'Discover';
    }
    cc_type = 'Discover';
  }

  //  Determine if the cc_number is in fact all numbers
  for (var j = 0; j < len; j++) {
    temp = "" + cc_num_string.substring(j, j+1);
    if (valid.indexOf(temp) == "-1"){
      has_bad_chars = true;
    }
  }

  // Strip spaces
  cc_num_string = cc_num_string.replace(/[^\d]/g,'');
  len           = cc_num_string.length;
  cc_num_int    = parseInt(cc_num_string);

  // Determine if it is the proper length
  if (((len == 0) && (is_valid)) || has_bad_chars) {  // nothing, field is blank AND passed above # check
    is_valid = false;
  }
  else {
    // cc_number is a number and the proper length - let's see if it is a valid card number
    if ((cc_type == 'Visa' && (len == 13 || len == 16)) || (cc_type != 'Visa' && len >= 13)) {
      is_valid = mod_ten_check(len, cc_num_int);
    }
  }

  // Determine if a CC type check is required
  if (check_cc_type) {
    if (cc_type != cc_type_name) {
      is_valid = false;
    }
  }

  // change alert to on-page display or other indication as needed.
  if (is_valid) {
    // Set the successful Mod-10 image
    eval("document.getElementById('" + message_div_id + "').innerHTML = '<img src=\"" + link_root + "images/tick.gif\" /> " + '' + "'");

    // If a submission button was passed in, enable it.
    if (typeof(submission_button_id) != 'undefined') {
      // Enable the button
      document.getElementById(submission_button_id).disabled = '';
    }
  }
  else {
    // Set the failed Mod-10 image
    eval("document.getElementById('" + message_div_id + "').innerHTML = '<img src=\"" + link_root + "images/cross.gif\" />'");

    // If a submission button was passed in, disable it.
    if (typeof(submission_button_id) != 'undefined') {
      // Disable the button
      document.getElementById(submission_button_id).disabled = 'disabled';
    }
  }

  return is_valid; // Return the results
}

// The actual mod then check
function mod_ten_check(len, cc_num_int)
{
  var int_total = 0; // integer total set at zero
  var calc;          // used for calculation of each digit

  // 15 or 16 for Amex or V/MC/Disc
  for (var i = len; i > 0; i--) {
    // LOOP throught the digits of the card
    calc       = parseInt(cc_num_int) % 10;  // right most digit
    calc       = parseInt(calc);             // assure it is an integer
    int_total += calc;                       // running total of the card number as we loop - Do Nothing to first digit
    i--;                                     // decrement the count - move to the next digit in the card
    cc_num_int = cc_num_int / 10;            // subtracts right most digit from cc_number
    calc       = parseInt(cc_num_int) % 10 ; // NEXT right most digit
    calc       = calc *2;                    // multiply the digit by two

    // Simple switch statement to change the value of calc to 7 if 16 is the multiple.
    switch(calc){
      case 10:
        calc = 1;
        break;       //5*2=10 & 1+0 = 1
      case 12:
        calc = 3;
        break;       //6*2=12 & 1+2 = 3
      case 14:
        calc = 5;
        break;       //7*2=14 & 1+4 = 5
      case 16:
        calc = 7;
        break;       //8*2=16 & 1+6 = 7
      case 18:
        calc = 9;
        break;       //9*2=18 & 1+8 = 9
      default:
        calc = calc; //4*2= 8 &   8 = 8  -same for all lower numbers
    }

    cc_num_int = cc_num_int / 10;  // subtracts right most digit from ccNum
    int_total += calc;             // running total of the card number as we loop
  }

  if ((int_total % 10) == 0){  // check to see if the sum Mod 10 is zero
    // This IS (or could be) a valid credit card number.
    return true;
  }
  else {
    // This could NOT be a valid credit card number
    return false;
  }
}