function FormManager(form,submitDisable) {
	this.form = form;
	this.submitDisable = submitDisable;
	this.validations = new Array();
	this.exceptions = new Array();
	this.setup();
}

FormManager.prototype.setup = function () {
	this.alerts = new Array();
	this.focusField = '';
};

FormManager.prototype.checkForm = function () {
	if (this.submitDisable) {
		this.buttonsDisabled(true);
	}
	if ($(this.form.name+'SubmitValue')) {
		if ($(this.form.name+'SubmitValue').value == 'Cancel') {
			return true;
		}
	}
	var i;
	var fieldElement;
	// first reset classes to defaults
	for (i=0; i<this.validations.length; i++) {
		fieldElement = $(this.validations[i].field);
		if (fieldElement == undefined) {
			fieldElement = $$('input[type="radio"][name="'+this.validations[i].field+'"]');
			if (fieldElement == '') {
				alert('No field exists with ID '+this.validations[i].field);
				return false;
			}
		} else {
			this.resetClass(fieldElement);
		}
	}
	// then validate
	for (i=0; i<this.validations.length; i++) {
		if (!this.isException(this.validations[i].field)) {
			this.validate(this.validations[i]);
		}
	}
	if (this.alerts.length > 0) {
		if ($(this.form.name+'SubmitValue')) {
			$(this.form.name+'SubmitValue').value = '';
		}
		if (this.submitDisable) {
			this.buttonsDisabled(false);
		}
		alert(this.alerts.join("\n"));
		$(this.focusField).focus();
		this.setup();
		return false;
	}
	if ($(this.form.name+'SubmitValue')) {
		if ($(this.form.name+'SubmitValue').value == 'Excel' || $(this.form.name+'SubmitValue').value == 'PDF') {
			this.form.target = '_blank';
			this.form.action = 'source/?';
			this.buttonsDisabled(false);
		} else {
			this.form.target = '';
			this.form.action = '?';
		}
	}
	return true;
};

FormManager.prototype.addAlert = function (field,msg) {
	this.alerts.push(msg);
	if (this.focusField == '') {
		this.focusField = field;
	}
};

FormManager.prototype.addValidation = function (types,field,display) {
	var validation = new FormValidation(types,field,display);
	this.validations.push(validation);
};

FormManager.prototype.addException = function (affectedFields,testFields,testValues) {
	var exception = new FormException(affectedFields,testFields,testValues);
	this.exceptions.push(exception);
};

FormManager.prototype.resetClass = function (field) {
	if (field.defaultClass != undefined) {
		field.className = field.defaultClass;
	} else {
		field.className = '';
	}
};

FormManager.prototype.isException = function (field) {
	// loop through the exceptions
	var i;
	for (i=0; i<this.exceptions.length; i++) {
		// if the field in question exists in the affectedFields of one of the exceptions, examine further
		if (this.exceptions[i].affectedFields.toString().indexOf(field) != -1) {
			// loop through the exception textFields to determine eligibility for an exception
			var k;
			for (k=0; k<this.exceptions[i].testFields.length; k++) {
				// the testField must exist
				if ($(this.exceptions[i].testFields[k])) {
					// if the testField value doesn't match the testValue, return false
					if ($(this.exceptions[i].testFields[k]).value != this.exceptions[i].testValues[k]) {
						return false;
					}
				} else {
					// the testField doesn't exist, return false
					return false;
				}
			}
			// this field passes the tests for an exception, so we do not need to validate it, return true
			return true;
		}
	}
	return false;
};

FormManager.prototype.validate = function (validation) {
	var i;
	for (i=0; i<validation.validations.length; i++) {
		this['validate'+validation.validations[i]](validation.field,validation.display);
	}
};

FormManager.prototype.setFieldError = function (field) {
	field.defaultClass = field.className;
	field.className = 'formError';
}

FormManager.prototype.validateNonempty = function (field,display) {
	var fieldElement = $(field);
	if (fieldElement == undefined) {
		if ($$('input:checked[type="radio"][name="'+field+'"]').pluck('value') == '') {
			this.alerts.push(display + ' must be selected.');
			return false;
		}
	}
	if (fieldElement.disabled == false) {
		if (fieldElement.value == '') {
			this.setFieldError(fieldElement);
			this.addAlert(fieldElement.name,display + ' cannot be empty.');
			return false;
		}
	}
	return true;
};

FormManager.prototype.validateNumeric = function (field,display) {
	var field = $(field);
	if (field.disabled == false) {
		if (field.value != '') {
			var pattern = /^\-?\d*\.?\d*$/;
			if (!field.value.match(pattern)) {
				this.setFieldError(field);
				this.addAlert(field.name,display + ' must be numeric.');
				return false;
			}
		}
	}
	return true;
};

FormManager.prototype.validateInteger = function (field,display) {
	var field = $(field);
	if (field.disabled == false) {
		var pattern = /^\d*$/;
		if (!field.value.match(pattern)) {
			this.setFieldError(field);
			this.addAlert(field.name,display + ' may only contain numbers.');
			return false;
		}
	}
	return true;
};

FormManager.prototype.validateZip = function (field,display) {
	var field = $(field);
	if (field.disabled == false) {
		if (field.value != '') {
			var testVal = field.value.replace(/\D/g,'');
			if (!testVal.match(/^\d{5}$|^\d{9}$/)) {
				this.setFieldError(field);
				this.addAlert(field.name,display + ' must be a valid zip code.');
				return false;
			}
		}
	}
	return true;
};

FormManager.prototype.validatePhone = function (field,display) {
	var field = $(field);
	if (field.disabled == false) {
		if (field.value != '') {
			var testVal = field.value.replace(/\D/g,'');
			if (!testVal.match(/^\d{10,20}$/)) {
				this.setFieldError(field);
				this.addAlert(field.name,display + ' must be a valid phone number.');
				return false;
			}
		}
	}
	return true;
};

FormManager.prototype.validateAlphanumeric = function (field,display) {
	var field = $(field);
	if (field.disabled == false) {
		var pattern = /^[\d\w]*$/;
		if (!field.value.match(pattern)) {
			this.setFieldError(field);
			this.addAlert(field.name,display + ' may only contain letters and numbers.');
			return false;
		}
	}
	return true;
};

FormManager.prototype.validateAlpha = function (field,display) {
	var field = $(field);
	if (field.disabled == false) {
		var pattern = /^[A-za-z]*$/;
		if (!field.value.match(pattern)) {
			this.setFieldError(field);
			this.addAlert(field.name,display + ' may only contain letters.');
			return false;
		}
	}
	return true;
};

FormManager.prototype.validateEmail = function (field,display) {
	var field = $(field);
	if (field.disabled == false) {
		if (field.value != '') {
			var pattern = /^[a-zA-Z0-9\._-]+@[a-zA-Z0-9][a-zA-Z0-9-]*(\.[a-zA-Z0-9_-]+)*\.([a-zA-Z]{2,6})$/;
			if (!field.value.match(pattern)) {
				this.setFieldError(field);
				this.addAlert(field.name,display + ' must be a valid email address.');
				return false;
			}
		}
	}
	return true;
};

FormManager.prototype.validateDate = function (field,display) {
	var field = $(field);
	if (field.disabled == false) {
		if (field.value != '') {
			if (field.value.match(/^(\d{1,2})\D+(\d{1,2})\D+(\d{2}|\d{4})$/)) {
				var d = new Date();
				var limitYear = d.getFullYear();
				limitYear += 5;
				if (RegExp.$3.length == 4) {
					var yyyy = parseInt(RegExp.$3,10);
				} else if (RegExp.$3.length == 2) {
					var yy = parseInt(RegExp.$3,10);
					if (yy < '70') {
						var yyyy = parseInt('20'+RegExp.$3,10);
					} else {
						var yyyy = parseInt('19'+RegExp.$3,10);
					}
				}
				if (yyyy < 1990 || yyyy > limitYear) {
					this.addAlert(field.name,display + ' has an invalid year. Valid years are 1990-'+limitYear.toString()+'.');
					this.setFieldError(field);
					return false;
				}
				var dd = parseInt(RegExp.$2, 10);
				var mm = parseInt(RegExp.$1, 10) - 1;
				if ( mm < 0 || mm > 11 ) {
					this.addAlert(field.name,display + ' has an invalid month. Valid months are 1-12.');
					this.setFieldError(field);
					return false;
				}
				
				// get last day in month
				var d = (11 == mm) ? new Date(yyyy + 1, 0, 0) : new Date(yyyy, mm + 1, 0);
				
				// if date out of range
				if (dd < 1 || dd > d.getDate()) {
					var monthNames = "January February March April May June July August September October November December".split(" ");
					this.addAlert(field.name,display + ' has an invalid date. Valid dates for ' + monthNames[mm] + ' are 1 through '+d.getDate().toString()+'.');
					this.setFieldError(field);
					return false;
				}
				
				return true;
			}
			this.addAlert(field.name,display + ' must be in the format mm/dd/yy.');
			this.setFieldError(field);
			return false;
		}
	}
	return true;
};

FormManager.prototype.validateTerm = function (field,display) {
	var field = $(field);
	if (field.disabled == false) {
		if (field.value != '') {
			if (field.value.match(/^(\d{1,2})\D+(\d{2}|\d{4})$/)) {
				var d = new Date();
				var limitYear = d.getFullYear();
				limitYear += 5;
				if (RegExp.$2.length == 4) {
					var yyyy = parseInt(RegExp.$2,10);
				} else if (RegExp.$2.length == 2) {
					var yy = parseInt(RegExp.$2,10);
					if (yy < '70') {
						var yyyy = parseInt('20'+RegExp.$2,10);
					} else {
						var yyyy = parseInt('19'+RegExp.$2,10);
					}
				}
				if (yyyy < 1990 || yyyy > limitYear) {
					this.addAlert(field.name,display + ' has an invalid year. Valid years are 1990-'+limitYear.toString()+'.');
					this.setFieldError(field);
					return false;
				}
				var mm = parseInt(RegExp.$1, 10) - 1;
				if ( mm < 0 || mm > 11 ) {
					this.addAlert(field.name,display + ' has an invalid month. Valid months are 1-12.');
					this.setFieldError(field);
					return false;
				}
				
				return true;
			}
			this.addAlert(field.name,display + ' must be in the format mm/yy.');
			this.setFieldError(field);
			return false;
		}
	}
	return true;
};

FormManager.prototype.buttonsDisabled = function (state) {
	for (i=0; i<this.form.elements.length; i++) {
		var tempobj = this.form.elements[i];
		if (tempobj.type) {
			var lcType = tempobj.type.toLowerCase();
			if (lcType == "submit" || lcType == "reset" || lcType == "button") {
				tempobj.disabled = state;
			}
		}
	}
};

function FormValidation(validations,field,display) {
	this.validations = validations.split(',');
	this.field = field;
	this.display = display;
}

function FormException(affectedFields,testFields,testValues) {
	this.affectedFields = affectedFields.split(',');
	this.testFields = testFields.split(',');
	this.testValues = testValues.split(',');
}

function setFormChanged() {
	document.formChanged = 1;
}

function checkFormChanged() {
	if (document.formChanged == 1) {
		return 'WARNING: Changes you have made have not been saved and will be lost.';
	}
}

function ComboChanged(id) {
	var text = $(id+'Text');
	var dropdown = $(id+'Dropdown');
	if (text.value != '') {
		dropdown.selectedIndex = 0;
		dropdown.className = 'lightgrayBG';
		dropdown.disabled = true;
	} else if (dropdown.value != '') {
		text.value = '';
		text.className = 'lightgrayBG';
		text.disabled = true;
	} else {
		text.className = '';
		text.disabled = false;
		dropdown.className = '';
		dropdown.disabled = false;
	}
}