if(window.addEventListener) {
 window.addEventListener('load', initFormValidator, false);
} else if(window.attachEvent) {
  window.attachEvent('onload', initFormValidator);
}

var formValidatorParents = null;

function initFormValidator() {
  for(var i = 0; i < document.forms.length; i++) {
    var form = document.forms[i];
    validateForm(form);
    form.onsubmit = function() { return validateForm(form); };
    for(var j = 0; j <  form.elements.length; j++) {
      var elem = form.elements[j];
      formValidatorAddEventListener(elem, "change", function(){ validateForm(form); return true; });
      if((elem.tagName == "INPUT" && elem.type != "submit")
          || elem.tagName == "TEXTAREA") {
        formValidatorAddEventListener(elem, "keyup", function(){ validateForm(form); return true; });
      }
    }
  }
}

function formValidatorAddEventListener(elem, eventType, handler) {
  if(elem.addEventListener)
    elem.addEventListener(eventType, handler, false);
  else if(elem.attachEvent)
    elem.attachEvent('on' + eventType, handler);
}

function validateForm(form) {
  var inputs = form.elements;
  var valid = true;
  var errorelements = new Array();
  for(var i = 0; i < inputs.length; i++) {
    var input = inputs[i];
    if(formValidatorParents) {
      var found = false;
      parents: for(var j = 0; j < formValidatorParents.length; j++) {
        var parent = formValidatorParents[j];
	var elem = input;
	while(elem = elem.parentNode) {
	  if(elem == parent) {
	    found = true;
	    break parents;
	  }
	}
      }
      if(!found)
        continue;
    }
    var errorelement = null;
    if(input.id)
      errorelement = "label_for_" + input.id;
    if(input.getAttribute("errorelement"))
      errorelement = input.getAttribute("errorelement");
    if(validateFormField(input)) {
      if(errorelement && typeof errorelements[errorelement] == "undefined")
        errorelements[errorelement] = true;
    } else {
      if(errorelement)
        errorelements[errorelement] = false;
      valid = false;
    }
    if(input.getAttribute("type") && input.getAttribute("type") == "submit") {
      if(valid) {
        input.disabled = false;
      } else {
        input.disabled = true;
      }
    }
  }
  for(var i in errorelements) {
    markValid(i, errorelements[i]);
  }
  var elems = form.getElementsByTagName("*");
  for(var i = 0; i < elems.length; i++) {
    var elem = elems[i];
    if(valid) {
      var src = elem.getAttribute("enabledsrc");
      if(src && src != elem.getAttribute("src"))
        elem.setAttribute("src", src);
    } else {
      var src = elem.getAttribute("disabledsrc");
      if(src && src != elem.getAttribute("src"))
        elem.setAttribute("src", src);
    }
  }
  return valid;
}

function validateFormField(input) {
  if(input.getAttribute("required") && !input.value)
    return false;
  var regex = input.getAttribute("mustMatch");
  if(regex && input.value && !input.value.match(regex))
    return false;
  var customCheck = input.getAttribute("customCheck");
  if(customCheck) {
    var value = input.value;
    if(!eval(customCheck))
      return false;
  }
  var xwith = input.getAttribute("xwith");
  if(xwith) {
    var xelem = document.getElementById(xwith);
    if((xelem && xelem.value && xelem.value != "0" && input.value && input.value != "0")
         || (xelem && (!xelem.value || xelem.value == "0") && (!input.value || input.value == "0")))
      return false;
  }
  return true;
}

function markValid(errorelement, valid) {
  var elem = document.getElementById(errorelement);
  if(elem)
    elem.className = valid ? "fieldValid" : "fieldInvalid";
}
