/*
 *  JavaScript Validation Component
 *  2004-09-17
 */

String.prototype.isEmail = function() {
  var re = /^(\w+(\-?\.?\w*)*)@[A-Za-z]\w+(\-?\.?\w*)*(\.[A-Za-z]{2,})+$/;
  return re.test(this);
}

String.prototype.isEmpty = function() {
  return (this == "");
}

String.prototype.isNumeric = function() {
  var re = /^\d+(\.)?\d*$/;
  return (re.test(this) && parseInt(this) != NaN);
}

String.prototype.ltrim = function(c) {
  var s = this;
  while (s.substring(0, 1) == c) s = s.substring(1);
  return s;
}

String.prototype.trim = function() {
  return this.replace(/^\s*|\s*$/g, "");
}

function isISO8601Date(s) {
  var re = /^\d{4}-\d{2}-\d{2}$/;
  return re.test(s);
}

function Validator() {
  this.rules = new Array();
}

Validator.prototype.addRequiredRule = function(fieldId, errorMsg) {
  this.rules[this.rules.length] = new Rule(fieldId, 0, null, true, 0, 0, 0, null, errorMsg);
}

Validator.prototype.addEmailRule = function(fieldId, isRequired, errorMsg) {
  this.rules[this.rules.length] = new Rule(fieldId, 1, null, isRequired, 0, 0, 0, null, errorMsg);
}

Validator.prototype.addDateRule = function(fieldId1, fieldId2, comparison, errorMsg) {
  this.rules[this.rules.length] = new Rule(fieldId1, 2, fieldId2, false, 0, 0, 0, comparison, errorMsg);
}

Validator.prototype.addNumericTextRule = function(fieldId, isRequired, minLength, errorMsg) {
  this.rules[this.rules.length] = new Rule(fieldId, 3, null, isRequired, minLength, 0, 0, null, errorMsg);
}

Validator.prototype.addNumberRule = function(fieldId, minValue, maxValue, errorMsg) {
  this.rules[this.rules.length] = new Rule(fieldId, 4, null, true, 0, minValue, maxValue, null, errorMsg);
}

Validator.prototype.validate = function() {
  var isValid = true;
  var setFocus = false;
  var errorMsg = "";
  for (var i = 0; i < this.rules.length; i++) {
    var rule = this.rules[i];
    isValid = true;
    var field = document.getElementById(rule.fieldId);
    field.value = field.value.trim();
    
    switch (rule.mode) {
      case 0: // Required
        if (field.value.isEmpty())
          isValid = false;
        break;
      case 1: // Email
        if (rule.isRequired || !field.value.isEmpty()) {
          if (!field.value.isEmail())
            isValid = false;
        }
        break;
      case 2: // Date Comparison
        var field2 = document.getElementById(rule.fieldId2);
        field2.value = field2.value.trim();
        if (isISO8601Date(field.value) && isISO8601Date(field2.value)) {
          var date1 = new Date(parseInt(field.value.substring(0, 4)), parseInt(field.value.substring(5, 7).ltrim("0")) - 1, parseInt(field.value.substring(8, 10).ltrim("0"))).getTime();
          var date2 = new Date(parseInt(field2.value.substring(0, 4)), parseInt(field2.value.substring(5, 7).ltrim("0")) - 1, parseInt(field2.value.substring(8, 10).ltrim("0"))).getTime();
          var comp = 1;
          if (date1 < date2)
            comp = -1;
          else if (date1 == date2)
            comp = 0;
          isValid = false;
          for (var j = 0; j < rule.comparison.length; j++) {
            if (comp == rule.comparison[j]) {
              isValid = true;
              break;
            }
          }
        } else {
          isValid = false;
        }
        break;
      case 3: // Numeric Text
        if (rule.isRequired || !field.value.isEmpty()) {
          if (!field.value.isNumeric || field.value.length < rule.minLength)
            isValid = false;
        }
        break;
      case 3: // Number
        var value = field.value;
        while (value.substring(0, 1) == "0")
          value = value.substring(1);
        if (value == "") value = "0";
        value = parseInt(value);
        if (!isNaN(value)) field.value = value;
        if (isNaN(value) || value < rule.minValue || value > rule.maxValue)
          isValid = false;
    }
    
    if (!isValid) {
      if (!setFocus) {
        if (rule.mode == 2)
          document.getElementById(rule.fieldId + "Day").focus();
        else
          field.focus()
        setFocus = true;
      }
      errorMsg += "- " + rule.errorMsg + "\r\n";
    }
  }
  
  if (errorMsg != "") {
    alert("Some form fields contain unsuitable values, please correct these fields and try again.\r\n" + errorMsg);
    return false;
  } else {
    return true;
  }
}

function Rule(fieldId, mode, fieldId2, isRequired, minLength, minValue, maxValue, comparison, errorMsg) {
  this.fieldId = fieldId;
  this.mode = mode;
  this.fieldId2 = fieldId2;
  this.isRequired = isRequired;
  this.minLength = minLength;
  this.minValue = minValue;
  this.maxValue = maxValue;
  this.comparison = comparison;
  this.errorMsg = errorMsg;
}