function ValidationMethod(f,d,v){
	this.init(f,d,v);
}

function ValidationMethod_init(f,d,v){
	this.required = false;
	this.elementName = "";
	this.elementDisplayName = "";
	this.method = "";
	this.element = "";
	this.parameter = "";
	this.form = f;

	this.validMethod = new Object();
	this.validMethod["b"] = "isValid";
	this.validMethod["i"] = "isNumber";
	this.validMethod["d"] = "isNumber";
	this.validMethod["l"] = "isNumber";	
	this.validMethod["f"] = "isFloat";
	this.validMethod["gt"] = "isGreaterThan";
	this.validMethod["lt"] = "isLessThan";
	this.validMethod["d1"] = "isDate";
	this.validMethod["d2"] = "isFutureDate";
	this.validMethod["d3"] = "isPastDate";	
	this.validMethod["d4"] = "isNotPastDate";	
	this.validMethod["p"] = "isNumber";
	this.validMethod["e"] = "isEmail";
	this.validMethod["ccn"] = "isCC";
	this.validMethod["cvv"] = "isCVV";
	this.validMethod["ml10"] = "isValid";
	this.validMethod["z"] = "isZip";
	this.validMethod["a"] = "isAlpha";
	this.validMethod["rx"] = "isRegExp";
	this.validMethod["ip"] = "isPosInt";
	

	
	if (v.indexOf("|") >= 0 ) {
		var validation = v.substring(0,v.indexOf("|"));
		this.elementName = v.substring(v.indexOf("|") + 1, v.length);
				
		this.required = (validation == "nn");
				
		if (validation.indexOf("nn-") == 0){
			this.required = true;
			validation = validation.substring(3,validation.length);
		}
			
		if ((validation.indexOf("gt") == 0) || (validation.indexOf("lt") == 0) || (validation.indexOf("rx") == 0)){
			this.parameter = validation.substring(2,validation.length);
			validation = validation.substring(0,2);
		}

		if (this.validMethod[validation] != null) {
			// have a valid validation method;
			this.method = this.validMethod[validation];
		}
			
			// now let's see if we have a real element;	
		if (f[this.elementName] != null) {
			this.element = f[this.elementName]
				// OK element exists now let compute display name;
				
			if (d[this.elementName]) {
				this.elementDisplayName = d[this.elementName];
			} else {
				this.elementDisplayName = this.elementName.charAt(0).toUpperCase();
				for(var j=1; j < this.elementName.length; j++) {
					var c = this.elementName.charAt(j);
					if ((c >= "A") && (c <= "Z")) {
						this.elementDisplayName = this.elementDisplayName + " " + c;
					} else {
						this.elementDisplayName = this.elementDisplayName + c;
					}
				}	
			}
		}
	}
}

function ValidationMethod_isValid(){
	if (this.elementDisplayName.length > 0) {
		if (this.required) {
			return true;
		} else if (this.hasMethod()) {
			return true;
		} else {
			return false;
		}
	} else {
		return false;
	}
}

function ValidationMethod_getMethod(){
	return this.method;
}

function ValidationMethod_getName(){
	return this.elementName;
}

function ValidationMethod_getElement(){
	return this.element;
}

function ValidationMethod_hasMethod(){
	return this.method.length > 0;
}

function ValidationMethod_getDisplayName(){
	return this.elementDisplayName;
}

function ValidationMethod_getParameter(){
	return this.parameter;
}

function ValidationMethod_isRequired(){
	return this.required;
}

function ValidationMethod_hasParameter(){
	return this.parameter.length > 0;
}



ValidationMethod.prototype.init = ValidationMethod_init;
ValidationMethod.prototype.isValid = ValidationMethod_isValid;
ValidationMethod.prototype.hasParameter = ValidationMethod_hasParameter;
ValidationMethod.prototype.getParameter = ValidationMethod_getParameter;
ValidationMethod.prototype.getElementDisplayName = ValidationMethod_getDisplayName;
ValidationMethod.prototype.getElementName = ValidationMethod_getName;
ValidationMethod.prototype.isRequired = ValidationMethod_isRequired;
ValidationMethod.prototype.hasMethod = ValidationMethod_hasMethod;
ValidationMethod.prototype.getMethod = ValidationMethod_getMethod;
ValidationMethod.prototype.getElement = ValidationMethod_getElement;


function FormValidator(f) {
	this.init(f);
}

function FormValidator_init(f) {
	this.validationErrors = new String();
	this.requiredErrors = new String();
	this.form = f;
	this.displayNames = new Object();
}

function FormValidator_isValid() {
	this.validateForm();
	return !this.hasErrors();
}

function FormValidator_validateForm() {
	var required = false;
	var validation = null;
	var elementName = "";
	if (this.form.displayName) {
		if (this.form.displayName.length) {
			for (var i=0; i < this.form.displayName.length;i++) {
				var a = this.form.displayName[i].value.split("|");
				if (a.length==2) {	
					this.displayNames[a[0]] = a[1];
				}
			}
		} else {
			var a = this.form.displayName.value.split("|");
			if (a.length==2) {	
				this.displayNames[a[0]] = a[1];
			}
		}
	}		
	
	if (this.form.validations) {
		if (this.form.validations.length) {
			for (var i=0; i < this.form.validations.length;i++) {
				this.validate(this.form.validations[i].value);
			}
		} else {
			this.validate(this.form.validations.value);
		}
	}
}				

function FormValidator_validate(v) {
	var validation = new ValidationMethod(this.form,this.displayNames,v);
	if (validation.isValid()) {
		var e = validation.getElement();		
		
		if (!e.type) {
			// have multiple elements with the same name
			// if element is a radio button we treat all as the same 
			// otherwise we will validate each element;
			
			var ce = e[0];
			if (ce.type == "radio") {
				// have radio button;
				if (validation.isRequired()) {
					var found = false;
					for (var j=0;j<e.length; j++) {
						if (e[j].checked) {
							found = true;
						}
					}
					if (!found) {
						this.addRequiredError(validation.getElementDisplayName());
					}
				}
			} else {
				// have multiple of other element types;
				for (var i=0;i<e.length;i++){
					this.validateElement(e[i],validation);
				}
			}
		} else { 
			if (e.type == "checkbox") {
				if (validation.isRequired() && !e.checked) {
					this.addRequiredError(validation.getElementDisplayName());
				}
			} else {
				this.validateElement(e,validation);
			}
		}
	}
}

function FormValidator_validateElement(e,v) {
	if (e.type == "select-one") {
		if (v.isRequired() && e.selectedIndex == 0) {
			this.addRequiredError(v.getElementDisplayName());
		}
	} else {
		// now only have text type elements left;
		if (this.isBlank(e.value)) {
			if (v.isRequired()) {
				this.addRequiredError(v.getElementDisplayName());
			}
		} else {
			if (v.hasMethod()) {
				var dataObject = eval("new " + v.getMethod() + "(e.value,this.form.name + \".\" + e.name)");			
				if (v.hasParameter()){
					dataObject.setParameter(v.getParameter());
				}
				if (!dataObject.isValid()) {
					this.addValidationError("\t" + v.getElementDisplayName() + " " + dataObject.getError() + "\n");
				}	else if (dataObject.canUpdate()) {
					e.value = dataObject.value;
				}
			}
		}
	}
}

function FormValidator_isBlank(s) {
	for(var i = 0; i < s.length; i++){
		var c = s.charAt(i);
		if ((c != ' ') && (c != '\n') && (c != '\t')) return false;
	}
	return true;
}


function FormValidator_hasErrors() {
	return ((this.requiredErrors.length > 0) || (this.validationErrors.length > 0));
}

function FormValidator_showErrors() {
	msg = "__________________________________________________\n\n";
	msg +="The form was not submitted because of the following error(s).\n";
	msg +="Please correct these error(s) and re-submit.\n";
	msg +="__________________________________________________\n\n";

	if (this.requiredErrors.length > 0) {
		msg += " - The following required field(s) are empty:\n" + this.requiredErrors + "\n";
	};

	if (this.validationErrors.length > 0) {
		msg += " - The following validation errors have occurred:\n" + this.validationErrors + "\n";
	};
	
	return msg;
}

function FormValidator_getValidationErrors() {
	return this.validationErrors;
}

function FormValidator_getRequiredErrors() {
	return this.requiredErrors;
}

function FormValidator_addValidationError(error) {
	this.validationErrors +=  error;
}

function FormValidator_addRequiredError(error) {
	this.requiredErrors += "\t" + error + "\n";
}

function FormValidator_addUnformattedError(error) {
	this.addValidationError("\t" + error + "\n");
}

FormValidator.prototype.init = FormValidator_init;
FormValidator.prototype.isValid = FormValidator_isValid;
FormValidator.prototype.validateElement = FormValidator_validateElement;
FormValidator.prototype.validateForm = FormValidator_validateForm;
FormValidator.prototype.validate = FormValidator_validate;
FormValidator.prototype.hasErrors = FormValidator_hasErrors;
FormValidator.prototype.showErrors = FormValidator_showErrors;
FormValidator.prototype.getValidationErrors = FormValidator_getValidationErrors;
FormValidator.prototype.getRequiredErrors = FormValidator_getRequiredErrors;
FormValidator.prototype.addRequiredError = FormValidator_addRequiredError;
FormValidator.prototype.addValidationError = FormValidator_addValidationError;
FormValidator.prototype.addUnformattedError = FormValidator_addUnformattedError;
FormValidator.prototype.isBlank = FormValidator_isBlank;

function verify(f) {
	var fv = new FormValidator(f);
	if (fv.isValid()) {
		return true;
	} else {
		alert(fv.showErrors());
		return false;
	}
}

function submitForm(f){
	if (verify(f)){
		eval(f.submit());
	}
}