/*
	VERSION:
	3/5/2008	1.0.1	Updated 'numeric' regular expression to accept
						negative and decimal numeric values
				1.0.0	Begin versioning.
*/
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";
	this.inputs = new Array();
	
	this.addItem = function(formElementName, alertMsg, validationType, comparison) {
		//validationType can be any of the valType's in this.validateString
		// or one of the following special validationTypes:
		//	select - returns true if item selected is not equal to comparison
		//				if comparison is not provided, then returns true if select.selectedIndex > 0
		//	selectmultiple - returns true if at least one item is selected
		//	radio, checkbox - returns true if at least one item is checked
		this.inputs.push({	elem: formElementName, //req
							msg: alertMsg, //req
							valType: (typeof(validationType) != "string" ? "" : validationType), //opt
							comparison: comparison, //opt
							ok: true //internal use
						});
	}
	
	this.callAlert = function() {
		var i = this.inputs.length-1;
		var arMsg = new Array();
		var thisItem;
		var thisElem;
		while(i >= 0) {
			thisItem = this.inputs[i];
			thisElem = this.f[thisItem.elem];
			if(!thisItem.ok) {
				switch(this.alertType) {
					case 1 :
						arMsg.push(thisItem.msg);
						break;
					case 2 :
						if(thisElem.style) {
							thisElem.style.borderColor = this.borderClr;
							thisElem.style.backgroundColor = this.backgroundClr;
							thisElem.style.color = this.textClr;
						}
						break;
					default :
						arMsg.push(thisItem.msg);
						if(thisElem.style) {
							thisElem.style.borderColor = this.borderClr;
							thisElem.style.backgroundColor = this.backgroundClr;
							thisElem.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 = this.inputs.length-1;
		var thisItem;
		var thisElem;
		var er = false;
		while(i >= 0) {
			thisItem = this.inputs[i];
			thisElem = this.f[thisItem.elem];
			switch(thisItem.valType) {
				case 'radio' : case 'checkbox' :
					thisItem.ok = this.isChecked(thisElem);
					break;
				case 'select' :
					if(thisItem.comparison === undefined) {
						if(thisElem.selectedIndex == 0) {
							thisItem.ok = false;
						}
					} else {
						if(thisElem[thisElem.selectedIndex].value == thisItem.comparison) {
							this
						}
					}
					break;
				case 'selectmultiple' :
					if(thisElem.selectedIndex == -1) {
						thisItem.ok = false;
					}
					break;
				default :
					thisItem.ok = this.validateString(thisElem.value, thisItem.valType);
					break;
			}
			if(!thisItem.ok) { er = true; }
			i--;
		}
		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(str, valType) {
		var objRegExp;
		if(str === undefined || str == null) { return false; }
		
		switch(valType) {
			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]+\.?[0-9]+?$/;
				break;
			case 'alphanumeric' : //numbers and letters only
				objRegExpr = /[^A-Za-z0-9]/;
				break;
			case 'maxlength' :
				var l = (formItem.comparison === undefined || isNaN(formItem.comparison) ? 1 : formItem.comparison);
				return (str.length <= l ? true : false);
			case 'minlength' :
				var l = (formItem.comparison === undefined || isNaN(formItem.comparison) ? 1 : formItem.comparison);
				return (str.length >= l ? true : false);
			default : //any non-empty string
				var v = str.replace(/^\s+/,'').replace(/\s+$/,''); //trim spaces
				return (v.length > 0 ? true : false);
		};
		
		return (str.search(objRegExp) > -1 ? true : false);
	
};