/*
  14/09/2004
  Validation for MC forms
  All validation is based on field names.
*/

function MCFormValidate (f) {
  var val = new MCValidator();
  if (! val.isInputValid(f)) {
    alert(val.toString());
    return false;
  }
  return true;
}

function MCValidator() { }

MCValidator.prototype.isInputValid = function (f) {
  var req = /\*$/;     // Field name required regex
  var blank = /^\s*$/; // Field value blank regex

  // Check for missing
  this.missing = new Array();
  for (var i=0; i<f.elements.length; i++) {
    if (req.test(f.elements[i].name)) {
      if (f.elements[i].type == 'checkbox' && !f.elements[i].checked) {
        this.missing[this.missing.length] = f.elements[i];
      } else if (blank.test(f.elements[i].value)) {
        this.missing[this.missing.length] = f.elements[i];
      }
    }
  }

  // Check custom tests
  this.failedTests = new Array();
  for (var i=0; i<f.elements.length; i++) {
    if (f.elements[i].id) {
      var field = f.elements[i];
      var e = eval(f.elements[i].id);
      if (e) {
        var errors = new Array();
        if (e.constructor == Array && e.length > 0) {
          for (var j=0; j<e.length; j++) {
            if (e[j] != "") { errors[errors.length] = e[j]; }
          }
        } else if (e.constructor != Array) {
          errors[errors.length] = e;
        }

        if (errors.length) { 
          this.failedTests[this.failedTests.length] = { obj:field, err:errors};
        }
      }
    }
  }

  // Check for different data types
  if (this.missing.length || this.failedTests.length) {
    return false;
  }

  return true;
}

MCValidator.prototype.toString = function () {
  var message = "The following errors occurred:\n";

  for (var i=0; i<this.missing.length; i++) {
    message += "- Required field '"+this.missing[i].name+"' is missing\n";
  }

  for (var i=0; i<this.failedTests.length; i++) {
    message += "- The field '"+this.failedTests[i].obj.name+"' had the following error(s): "+this.failedTests[i].err+"\n";
  }

  return message;
}

function isValidCreditCardNumber(ccNumField,ccTypeField) {
  var ccnum = ccNumField.value;

  if (ccTypeField) {
    for (var i=0; i<ccNumField.form.length; i++) {
      if (ccNumField.form.elements[i].name == ccTypeField) {
        ccTypeField = ccNumField.form.elements[i];
        break;
      }
    }

    var type = ccTypeField.value;
    var re;
    if (type == "visa") {
      // Visa: length 16, prefix 4, dashes optional.
      re = /^4\d{3}-?\d{4}-?\d{4}-?\d{4}$/;
    } else if (type == "mastercard") {
      // Mastercard: length 16, prefix 51-55, dashes optional.
      re = /^5[1-5]\d{2}-?\d{4}-?\d{4}-?\d{4}$/;
    } else if (type == "discover") {
      // Discover: length 16, prefix 6011, dashes optional.
      re = /^6011-?\d{4}-?\d{4}-?\d{4}$/;
    } else if (type == "amex") {
      // American Express: length 15, prefix 34 or 37.
      re = /^3[4,7]\d{13}$/;
    } else if (type == "diners") {
      // Diners: length 14, prefix 30, 36, or 38.
      re = /^3[0,6,8]\d{12}$/;
    }

    if (!re.test(ccnum)) return "Invalid credit card number or type";
  }

  // Checksum ("Mod 10")
  // Add even digits in even length strings or odd digits in odd length strings.
  var checksum = 0;
  for (var i=(2-(ccnum.length % 2)); i<=ccnum.length; i+=2) {
    checksum += parseInt(ccnum.charAt(i-1));
  }

  // Analyze odd digits in even length strings or even digits in odd length strings.
  for (var i=(ccnum.length % 2) + 1; i<ccnum.length; i+=2) {
    var digit = parseInt(ccnum.charAt(i-1)) * 2;
    if (digit < 10) { checksum += digit; } else { checksum += (digit-9); }
  }

  if ((checksum % 10) == 0) { return ""; }
  return "Invalid credit card number";
}

function compareTo(sField,dField) {
  for (var i=0; i<sField.form.length; i++) {
    if (sField.form.elements[i].name == dField) {
      dField = sField.form.elements[i];
      break;
    }
  }

  if (sField.value == dField.value) { return ""; }
  var message = sField.name+" and "+dField.name+" did not match";
  return message;
}

function copyTo(sField,dField) {
  dField.value = sField.value;
  return "";
}

// Data type functions
function isNumber(field) {
  var re = /^[0-9]+$/;
  if (!re.test(field.value)) return "Must be a number";
  return "";
}

// Data type functions
function isDecimal(field) {
  var re = /^[0-9]+(\.[0-9]+)?$/;
  if (!re.test(field.value)) return "Must be a decimal number";
  return "";
}

function isText(field) {
  var re = /^[a-zA-Z0-9 _+-\:\/\\,\.]+$/;
  var val = '';
  if (field.type == 'radio') { val = field.checked?field.value:''; }
  else { val = field.value; }
  if (!re.test(val)) return "Must be text (A-Z, numbers and spaces)";
  return "";
}

function isEmail(field) {
  var re = /^.+\@[a-z0-9-]+(\.[a-z0-9-]+)+$/i;
  if (!re.test(field.value)) return "Must be a valid email address";
  return "";
}

function isPhone(field) {
  var re = /^[a-zA-Z0-9 _+-]+$/;
  if (!re.test(field.value)) return "Must be a telephone number";
  return "";
}

