function validate(o) {

  if (validate.arguments.length > 0) {
  	disableForm(o);
    
    fieldNames = o.fieldNames.value.split(",");
    fieldTypes = o.fieldTypes.value.split(",");
    fieldReqs  = o.fieldReqs.value.split(",");
    fieldDesc  = o.fieldDesc.value.split(",");
    var valid  = new Array(fieldNames.length);
    var errMsg = new Array(fieldNames.length);
    var errMsg = new String();
    
    if (fieldNames.length != fieldTypes.length ||
        fieldTypes.length != fieldReqs.length ||
        fieldReqs.length  != fieldDesc.length) {
      alert('Form validation not propertly configured.');
      return false;
    }
    
    for (i=0; i<fieldNames.length; i++) {
      if (fieldTypes[i].substr(0,10) == String("type_list_") || o[fieldNames[i]].value.length > 0) {
        valid[i] = true;
        
        switch (fieldTypes[i].toLowerCase()) {
          case 'type_email':
            if (! isEmail(o[fieldNames[i]].value)) {
              valid[i] = false;
              errMsg += fieldDesc[i] + ': You must enter a valid email address\n';
              flagField(o[fieldNames[i]]);              
            }
            break;
            
          case 'type_int':
          case 'type_integer':
            if (parseInt(o[fieldNames[i]].value) != parseFloat(o[fieldNames[i]].value)) {
              valid[i] = false;
              errMsg += fieldDesc[i] + ': You must enter a number\n';
              flagField(o[fieldNames[i]]);
            }
            break;
          case 'type_float':
            if (isNaN(o[fieldNames[i]].value)) {
              valid[i] = false;
              errMsg += fieldDesc[i] + ': You must enter a number\n';
              flagField(o[fieldNames[i]]);              
            }
            break;
          case 'type_date':
            break;
          case 'type_zip':
            break;
          case 'type_url':
            break;
          case 'type_phone':
          	if (o[fieldNames[i]].value.length < 10) {
          		valid[i] = false;
          		errMsg += fieldDesc[i] + ': You must enter a valid phone number, with area code\n';
          		flagField(o[fieldNames[i]]);
          	}
            break;
          case 'type_cc':
            break;
        }
      } else {
        if (fieldReqs[i] > 0) {
          valid[i] = false;
          errMsg += fieldDesc[i] + ': This is a required field\n';
          flagField(o[fieldNames[i]]);          
        }
      }
      
      if (valid[i]) {
        unFlagField(o[fieldNames[i]]);
      }
    }
  }

  if (errMsg.length > 0) {
    alert(errMsg);
	  enableForm(o);  
    return false;
  } else {
    return true;
  }
}

function disableForm(o) {
	for(var i=0;i<o.elements.length;i++) {
		if (o.elements[i].type == "submit") {
			submitButtonCaption = o.elements[i].value;
			o.elements[i].value = "loading...";
			o.elements[i].disabled = true;
		}
	}
}

function enableForm(o) {
	for(var i=0;i<o.elements.length;i++) {
		if (o.elements[i].type == "submit") {
			o.elements[i].value = submitButtonCaption;
			o.elements[i].disabled = false;
		}	
	}
}	

function flagField(f) {
  f.style.border = '2px solid';
  f.style.background = '#FDFFEA';
}

function unFlagField(f) {
  f.style.border = '';
  f.style.background = '#FFFFFF';  
}

function isEmail(str) {
  var pattern = /\s*\w+@[^\.]+\.[^\.]+(\.[^\.])*\s*/;
  legalChars = "~0123456789.-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_@+";

  if(!pattern.test(str)) {
    return false;
  }
  
  //This enhances the previous EMail check. This checks for legal values and returns illegal values
  for(x=0; x < str; x++) {
    if (legalChars.indexOf(str.substring(x,x+1)) < 0) {
      return false;
    }
  }
  
  return true;
}