/**
 * Global variables - re-usable regular expressions for common field
validation
 */ 
 
var REGEXTYPES = {
	EMAIL: /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/,
	INTEGER: /^[1234567890]+$/,
	NOTBLANK: /\w+/,
	CREDITCARD: /^\d{4}\s*\d{4}\s*\d{4}(\s*\d{4})$/,
	NOTZERO: /^[123456789][0-9]*$/,
	STATE: /[A-Z]{2}/,
	ZIP: /^[0-9]{5}(\-?[0-9]{4})?$/
}

/**
 * Required helper functions
 */
 
function switchClass (dEl, sClassName, bShow)
{
	if ("boolean" != typeof bShow)
	{
		throw ("bShow is not a boolean");
	}
	var reHasClass = new RegExp("\s*" + sClassName + "\s*", "g");
	if (bShow)
	{
		if (!reHasClass.test(dEl.className))
		{
			dEl.className += " " + sClassName;
		}
	} else {
		dEl.className = dEl.className.replace(reHasClass, "");
	}
}

function cancelEvent(e)
{

	if (e)
	{
		if (e.stopPropagation)
		{
			e.stopPropagation();
		} else {
			e.cancelBubble = true;
		}
		if (e.preventDefault)
		{
			e.preventDefault();
		} else {
			e.returnValue = false;
		}
	}
	return false;
}

function hitch(oObject, fnMethod)
{
	return function ()
	{
		if ("function" == typeof fnMethod)
		{
			return fnMethod.apply(oObject, arguments);
		} else {
			return oObject[fnMethod].apply(oObject, arguments);
		}
	}
}

/**
 * Field object - make one of these for every field that needs to be
validated
 */ 
 
Field = function(oInstantiator) 
{
	this.regEx  = oInstantiator.regEx;
	this.sError = oInstantiator.sError;
	this.dField = oInstantiator.dField; // dom element: input field
	this.dLabel = oInstantiator.dLabel;	// dom element: label
}

Field.prototype.getIsValid = function()
{

	if ("lblstate" == this.dLabel.id)
	{
		var country = document.getElementById("cust_country");
		if (country.value != "U.S.")
		{
			this.unlight();
			return true;
		}
	}

	if (this.matchPattern(this.dField.value, this.regEx))
	{
		this.unlight();
		return true;
	} else {
		this.highlight();
		return false;
	}
}

Field.prototype.matchPattern = function( strText, regExp) {
	if ( regExp.test(strText)==true ) {
		return true;
	} else {
		return false;
	}
}

Field.prototype.highlight = function()
{
	switchClass(this.dLabel, "error", true);
}

Field.prototype.unlight = function()
{
	switchClass(this.dLabel, "error", false);
}


/**
 * FormValidator object - the main object
 */ 

FormValidator = function(dForm)
{
	this.dForm = dForm; // dom element: the form that contains the elements
	this.rFields = [];
	this.errMsg = "";
	dForm.onsubmit = hitch(this, this.submitHappening);
}

FormValidator.prototype.addField = function(oInstantiator)
{
	this.rFields.push(
		new Field(oInstantiator)
	);
}

FormValidator.prototype.submitHappening = function (e)
{
	e = e || window.event;

	var sErr = this.getValidationErrors();
	if (sErr)
	{
		cancelEvent(e);
		alert (sErr);
	}
}

FormValidator.prototype.getValidationErrors = function()
{
	var errMsg = [];
	var isValid;
	var iFirstFail = -1;
	for (var i in this.rFields)
    {
		isValid = this.rFields[i].getIsValid();
		if (!isValid)
		{
			errMsg.push(this.rFields[i].sError);
			if (iFirstFail == -1)
			{
				iFirstFail = i;
			}
		}
	}
	
	if (errMsg.length > 0)
	{
		this.rFields[iFirstFail].dField.focus();
		return ("The form did not validate\n\n" + errMsg.join("\n"));
	} else {
		return false;
	}
}


