/**
 validate.js - 1.0 (1/16/2002)
 Automated form validation.  Copyright 2002 Kevin P. Crawford (kcrawford@vml.com).

 fields = [
   ["name", "message"],
   ["name", "message", "minLength:TYPE"],
   ...
 ];

 */

function validate(form, fields) {
  var valid = true;
  if(form == null || fields == null) return valid;
  list: for(var i=0; i<fields.length; i++) {
    var field = fields[i];
    var name = field[0];
    var message = field[1];
    if(form[name] == null) continue list;

    var type = 'DEFAULT', length = 1, match = '';
    if(field[2] != null) {
      if(field[2].constructor == RegExp) {
        type = 'REGEX';
        match = field[2];
      } else switch(field[2].charAt(0)) {
        case '$':
          type = 'MATCH';
          match = field[2].substr(1);
          break;
        default:
          var parts = field[2].split(':');
          if(parts[1] != null) {
            length = parts[0];
            type = parts.slice(1).join('');
            if(type == '') type = 'DEFAULT';
          } else if(field[2].match(/^\d+$/)) {
            length = field[2];
          } else {
            type = field[2];
          }
      }
    }

    var passed = true, selected = 0, x = 0;
    if(form[name].type == null && form[name].length != null) switch(form[name][0].type) {
        case 'radio':
        case 'checkbox':
            selected = 0;
            for(x=0; x<form[name].length; x++)
              if(form[name][x].checked) selected++;
            passed = (selected >= length);
            break;
            
    } else switch(form[name].type) {
        case 'radio':
        case 'checkbox':
            selected = 0;
            if(form[name].checked == true) selected++;
            passed = (selected >= length);
            break;

        case 'select-one':
        case 'select-multiple':
            selected = 0;
            for(x=0; x<form[name].length; x++)
              if(form[name][x].selected && form[name][x].value != '') selected++;
            passed = (selected >= length);
            break;

        default:
            type: while(true) switch(type) {
              /** regular expression matching **/
              case 'EMAIL':
                match = /^[A-Za-z_0-9\-.]+@([A-Za-z_0-9\-]+\.)+[A-Za-z]+$/;
                type  = 'REGEX';
                continue type;
        
              case 'ALPHANUMERIC':
                match = new RegExp('^[A-Za-z0-9]{' + length + ',}$');
                type  = 'REGEX';
                continue type;

              case 'NUMERIC':
                match = new RegExp('^\\d{' + length + ',}$');
                type  = 'REGEX';
                continue type;
        
              case 'CURRENCY':
                match = /^\d+\.\d{2}$/;
                type  = 'REGEX';
                continue type;
        
              case 'PHONE':
                match = /^\D*\d{3}\D*\d{3}\D*\d{4}$/;
                type  = 'REGEX';
                continue type;
              
              case 'ZIP':
                match = /^\d{5}(-\d{4})?$/;
                type = 'REGEX';
                continue type;
        
              case 'REGEX':
                passed = match.test(form[name].value);
                break type;
        
              /** standard matching **/
              case 'MATCH':
                passed = (form[name].value == form[match].value);
                if(!passed) {
                  form[name].value = '';
                  form[match].value = '';
                  name = match;
                }
                break type;
        
              case 'DEFAULT':
              default:
                passed = (form[name].value.length >= length);
                break type;
            }
    }
    
    if(!passed) {
      alert(message);
      if(form[name].type == null && form[name].length != null) form[name][0].focus();
      else form[name].focus();
      valid = false;
      break list;
    }
  }

  if(arguments[2]) {
    return valid; 
  } else if(valid) form.submit();
}
