function Validation(formRef, alertType) {
	//this object is for simple validation only
	//if an item's validation relies upon multiple factors
	//other than its own value, then other means are necessary
	//as of this writing
	this.f = formRef;
	this.alertType = alertType; //1 = window.alert only, 2 = hilite only, anything else = both
	this.alertOverride = ""; //will replace default alert if present
	this.borderClr = "red";
	this.backgroundClr = "yellow";
	this.textClr = "#b50000";
	var arFormItems = new Array();
	this.addItem = function(formElementName, alertMsg, validationType, numericComparison) {
		arFormItems.push({	e:formElementName, //req
							m:alertMsg, //req
							t:validationType, //opt
							l:numericComparison, //opt num, for validation requiring numeric comparison such as string length
							ok:true //internal use
						});
	}
	this.callAlert = function() {
		var i = arFormItems.length-1;
		var arMsg = new Array();
		var thisItem = this.f[arFormItems[i].e];

		while(i >= 0) {
			thisItem = this.f[arFormItems[i].e];
			if(!thisItem.ok) {
				switch(this.alertType) {
					case 1 :
						arMsg.push(arFormItems[i].m);
						break;
					case 2 :
						if(thisItem.style) {
							thisItem.style.borderColor = this.borderClr;
							thisItem.style.backgroundColor = this.backgroundClr;
							thisItem.style.color = this.textClr;
						}
						break;
					default :
						arMsg.push(arFormItems[i].m);
						if(thisItem.style) {
							thisItem.style.borderColor = this.borderClr;
							thisItem.style.backgroundColor = this.backgroundClr;
							thisItem.style.color = this.textClr;
						}
						break;
				}
			}
			i--;
		}
		if(arMsg.length > 0) {
			if(this.alertOverride.length > 0) {
				window.alert(this.alertOverride);
				return false;
			}
			window.alert("Please correct the following:\n" + arMsg.join("\n"));
		}
		return false;
	}
	this.validate = function() {
		this.clearHilites();
		var i = arFormItems.length-1;
		
		var thisItem = this.f[arFormItems[i].e];
		var er = false;
		while(i >= 0) {
			try {
				thisItem = this.f[arFormItems[i].e];
				switch(arFormItems[i].t) {
					case 'radio' : case 'checkbox' :
						thisItem.ok = this.isChecked(thisItem);
						break;
					default :
						thisItem.ok = this.validateString(arFormItems[i]);
						break;
				}
				if(!thisItem.ok) { er = true; }
				i--;
			} catch(e) {
				//fail silently
				//this is a safeguard against 
				//creating a form item that doesn't
				//exist in the real form
			}
		}
		if(er == true) {
			return this.callAlert();
		} else {
			return true;
		}
		
	}
};
Validation.prototype.clearHilites = function() {
	var i = this.f.elements.length-1;
	while(i >= 0) {
		this.f.elements[i].style.borderColor = '';
		this.f.elements[i].style.backgroundColor = '';
		this.f.elements[i].style.color = '';
		i--;
	}
};
Validation.prototype.isChecked = function(checkGroup) {
	/**** RETURNS FALSE IF NO BOXES ARE CHECKED, TRUE OTHERWISE ****/
	if(checkGroup === undefined) { return false; }
	var i = checkGroup.length-1;
	while(i >= 0) {
		if(checkGroup[i].checked == true) {
			return true;
		}
		i--;
	}
	return false;
};

Validation.prototype.validateString = function(formItem) {
		var strType = formItem.t;
		var strVal = "";
		try { strVal = this.f[formItem.e].value; }
		catch(e) { window.alert("Error: " + formItem.e + " does not exist."); }
		var objRegExp;
		switch(strType) {
			case 'phone_full' : //xxX-XXX-XXX-XXXX w/req country code digits, strict
				objRegExp  = /^\d{1,3}\-\d{3}\-\d{3}\-\d{4}$/;
				break;
			case 'phone' :  //xxx-XXX-XXX-XXXX w/opt country code digits and req area code.
				objRegExp  = /^(\d{1,3}\-)?\d{3}\-\d{3}\-\d{4}$/;
				break;
			case 'phone_part' :  //xxx-XXX-XXXX w/opt area code
				objRegExp  = /^(\d{3}\-)?\d{3}\-\d{4}$/;
				break;
			case 'email' :
				objRegExp  = /^[a-z0-9]([a-z0-9_\-\.]*)@([a-z0-9_\-\.]*)(\.[a-z]{2,3}(\.[a-z]{2}){0,2})$/i;
				break;
			case 'state' :
				objRegExp = /^(AK|AL|AR|AZ|CA|CO|CT|DC|DE|FL|GA|HI|IA|ID|IL|IN|KS|KY|LA|MA|MD|ME|MI|MN|MO|MS|MT|NB|NC|ND|NH|NJ|NM|NV|NY|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VA|VT|WA|WI|WV|WY)$/i; 
				break;
			case 'zip' :
				objRegExp  = /(^\d{5}$)|(^\d{5}-\d{4}$)/;
				break;
			case 'ssn' :
				objRegExp  = /^\d{3}\-\d{2}\-\d{4}$/;
				break;
			case 'alpha' :
				objRegExp = /[^A-Za-z]/;
				break;
			case 'numeric' :
				objRegExp = /[^0-9]/;
				break;
			case 'alphanumeric' : //numbers and letters only
				objRegExpr = /[^A-Za-z0-9]/;
				break;
			case 'maxlength' :
				var l = (formItem.l === undefined || isNaN(formItem.l) ? 1 : formItem.l);
				return (strVal.length <= l ? true : false);
			case 'minlength' :
				var l = (formItem.l === undefined || isNaN(formItem.l) ? 1 : formItem.l);
				return (strVal.length >= l ? true : false);
			default : //any non-empty string
				var v = strVal.replace(/^\s+/,'').replace(/\s+$/,''); //trim spaces
				return (v.length > 0 ? true : false);
		};
		
		return (strVal.search(objRegExp) > -1 ? true : false);
	
};