//Javascript Form Validation
//Author: H Glenn Hatfield
//Date: 13 April 2005

/**
 * In another file, set up the validation_array by calling the function AddValidationField(formName,fieldName,regex,error_div);
 * The above variable definitions should be specified after this file is loaded.
 */

var validation_array = new Array();
var fieldIndex = 0;

function Validate( formName ) {
  if(!validation_array) return false;
  if(formName == 'all' || formName == ''){
    __clear_errors_all();
    return __validate_all();
  }
  if(!validation_array[formName]){
    return false;
  }
  __clear_errors(formName);
  var retVal = __validate_form(formName);
  return retVal;
}

// wrapper for AddValidationFieldReal, the field value must match the pattern
function AddValidationField(formName, fieldName, regex, error_div, required){
  var not = 0;
  AddValidationFieldReal(formName, fieldName, regex, error_div, required, not);
}

// wrapper for AddValidationFieldReal, the field value must not match the pattern
function AddValidationFieldNot(formName, fieldName, regex, error_div, required){
  var not = 1;
  AddValidationFieldReal(formName, fieldName, regex, error_div, required, not);
}

// the real AddValidationField. Needs to know if the pattern should match, or if the pattern is not allowed.
function AddValidationFieldReal(formName, fieldName, regex, error_div, required, not){
  if(formName == '' || fieldName == '' || error_div == '') {alert('Invalid Call to AddValidationField'); return false;}
  if(!validation_array[formName]){
    validation_array[formName] = new Array();
  }
  if(!validation_array[formName][fieldName]){
    validation_array[formName][fieldName] = new Array();
  }

  if(!validation_array[formName][fieldName]['not'])
    validation_array[formName][fieldName]['not'] = Array();
  validation_array[formName][fieldName]['not'][ validation_array[formName][fieldName]['not'].length  ] = not;

  // array of regex so a field can be checked for more than one thing. only make the array if it doesn't exist
  if(!validation_array[formName][fieldName]['regex'])
    validation_array[formName][fieldName]['regex'] = Array();
  validation_array[formName][fieldName]['regex'][ validation_array[formName][fieldName]['regex'].length  ] = regex;

  // array of error_divs so a field can can have two different msgs to go with the regexes.
  if(!validation_array[formName][fieldName]['error_div'])
    validation_array[formName][fieldName]['error_div'] = Array();
  validation_array[formName][fieldName]['error_div'][ validation_array[formName][fieldName]['error_div'].length  ] = error_div;

  if(typeof (required)=='undefined')required = true;
  validation_array[formName][fieldName]['required'] = required;
  return true;
}

function ClearAll(formName){
  if(validation_array[formName]){
    __clear_errors(formName);
  }
}

function Clear(formName,fieldName){
  __clear_error(formName,fieldName);
}

/*
 * Reset() will set validation_array to be an empty array, ready to be repopulated
 *
 */
function Reset(){
  validation_array = new Array();
}
 /***********************************************************
 * The functions that follow should not be called directly. *
 * Only call the Validate() function.                       *
 ***********************************************************/

function __clear_error(formName,fieldName){
  var errorDiv;
  var size = validation_array[formName][fieldName]['error_div'].length;
  var i = 0;
  while(i < size) {
    errorDiv = document.getElementById( validation_array[formName][fieldName]['error_div'][i] );

    if(errorDiv){
      errorDiv.style.display = "none";
    }
    i++;
  }
}

function __clear_errors(formName){
  for (var field in validation_array[formName]){
    __clear_error(formName, field);
  }
}

function __validate_all(){
  for( var i in validation_array)
  {
    if ( !__validate_form(validation_array[i]) )return false;
  }
  return true;
}

function __validate_form( formName ){

  var retVal = true;
  if(!document.forms[formName]) return false;
  for( var field in validation_array[formName] ){
    if( validation_array[formName][field]['required']){
      if( !__validate_field( formName, field ) ){
        retVal = false;
        if(validation_array[formName][field]['error_div'][fieldIndex]){
          var errorDiv = document.getElementById(validation_array[formName][field]['error_div'][fieldIndex] );
          if (errorDiv) errorDiv.style.display = "block";
        }
      }
    }
  }
  return retVal;
}

function __validate_field( formName, fieldName ){
  var re='';
  if(!document.forms[formName][fieldName]) return false;
  if(document.forms[formName][fieldName].type){
    var inspect_value;
    switch(document.forms[formName][fieldName].type){
      case 'checkbox':
        return document.forms[formName][fieldName].checked;
        break;
      case 'select-one':
        var sel_ele = document.forms[formName][fieldName];
        if( sel_ele ) {
          inspect_value = sel_ele[ sel_ele.selectedIndex ].value;
        } else {
          inspect_value = '';
        }
      case 'hidden':
      case 'password':
      case 'textarea':
      case 'text':

        var i = 0;
        var numChecks = validation_array[formName][fieldName]['regex'].length;
        var result;
        var notContain;
        var ret;

        // same logic for testing select box value, but inspect_value is already set.
        if( inspect_value == null ) {
          inspect_value = document.forms[formName][fieldName].value;
        }

        while(i < numChecks ) {

          // after we return we need to know which error_div to show if there is more than one.
          fieldIndex = i;

          notContain = validation_array[formName][fieldName]['not'][i];
          //alert(numChecks + ' not ' + notContain + ' ' + inspect_value );
          re = new RegExp(validation_array[formName][fieldName]['regex'][i]);
          if( notContain) {
            result = !inspect_value.match(re);
          } else {
            result = inspect_value.match(re);
          }

          // multi check fields need more work
          if( numChecks > 1 ) {

            // must decide if it is good or bad, not just return teh result
            if( !!result ) {
              ret = 'good';
              // it is good, so if it is the last check for this field, return it.
              if( (i + 1) == numChecks) {
                //alert( 'last check, is good');
                return ret;
              }
            // it is bad, stop other checks and return the error
            } else {
              ret = '';
              // alert('found bad ' + fieldIndex);
              return ret;
            }

          // single check field can just return
          } else {
            return result;
          }

          i++;
        }
        break;

      case 'radio':
        re = new RegExp(validation_array[formName][fieldName]['regex']);
        return document.forms[formName][fieldName].value.match(re);
        break;
    }
  }else{
    for( var i = 0; i < document.forms[formName][fieldName].length; ++i){
      if(document.forms[formName][fieldName][i].checked) return true;
    }
    return false;
  }
  return false;
}

