/********************************************
Function: validateForm
Purpose:  Validate all form fields.
Inputs:   Form Object
Returns:  boolean
********************************************/
// Create new event handlers
function validateForm(frm)
{
/*
	// Execute onbeforevalidate processing
	if(typeof this.onbeforevalidate=="function" && this.onbeforevalidate()==false)
		return false;
*/
	var i, oElement, iElements=frm.elements.length;
	// Validate individual elements
	for(i=0;i<iElements;i++)
	{
		oElement=frm.elements[i];
		// Perform default validation for element
		if (!elmValid(oElement))
		{
			return false;
		}
	}
/*
	// Execute onaftervalidate processing
	if(typeof this.onaftervalidate=="function" && this.onaftervalidate()==false)
		return false;

	// Perform original onsubmit event handler
	if (fnSubmit && fnSubmit()==false)
		return false;
*/
	return true;
}

/**********************************************
Method:   elmValid
Purpose:  Validate an element based on the
	  attributes provided in the HTML text
Inputs:   Form Element Object
Returns:  boolean
**********************************************/
function elmValid(oElement)
{
	// Trim leading and trailing spaces
	if(oElement.value)
		oElement.value = trimAll(oElement.value);
	var sValue = getValueOf(oElement);
	// REQUIRED
	if(oElement.REQUIRED && !sValue)
	{
		validationErr(oElement, "Please enter a value");
		return false;
	}
	// FLOAT
	var bSigned=oElement.SIGNED;
	if (oElement.FLOAT && sValue)
	{
		var re=new RegExp("^"+((bSigned)?"-?":"")+"(\\d*(,?\\d{3})*\\.?\\d+|\\d+(,?\\d{3})*\\.?\\d*)$");
		if (!re.test(sValue))
		{
			validationErr(oElement, "Please enter a number");
			return false;
		}
		// MIN
		var iMin = oElement.MIN;
		if(iMin==parseFloat(iMin) && sValue.replace(/,/,"")<iMin)
		{
			validationErr(oElement, "Please enter a value greater than or equal to "+formatNumber(iMin));
			return false;
		}
		// MAX
		var iMax = oElement.MAX;
		if(iMax==parseFloat(iMax) && sValue.replace(/,/,"")>iMax)
		{
			validationErr(oElement, "Please enter a value less than or equal to "+formatNumber(iMax));
			return false;
		}
	}
	// AMOUNT
	if (oElement.AMOUNT && sValue)
	{
		var sSigned = "(\\$?-?|-?\\$?)";
		var re = new RegExp("^"+((bSigned)?sSigned:"\\$?")+"((\\d{1,3})*(,?\\d{3})*\\.?\\d{2}|\\d{1,3}(,?\\d{3})*\\.?(\\d{2})?)$");
		if(!re.test(sValue))
		{
			validationErr(oElement, "Please enter a dollar amount");
			return false;
		}
		// MIN
		var iMin = oElement.MIN;
		if(iMin==parseFloat(iMin) && sValue.replace(/[\$,]/,"")<iMin)
		{
			validationErr(oElement, "Please enter a value greater than or equal to $"+formatNumber(iMin));
			return false;
		}
		// MAX
		var iMax = oElement.MAX;
		if(iMax==parseFloat(iMax) && sValue.replace(/[\$,]/,"")>iMax)
		{
			validationErr(oElement, "Please enter a value less than or equal to $"+formatNumber(iMax));
			return false;
		}
	}
	// INTEGER
	if (oElement.INTEGER && sValue)
	{
		var re=new RegExp("^"+((bSigned)?"-?":"")+"\\d{1,3}(,?\\d{3})*$");
		if (!re.test(sValue))
		{
			validationErr(oElement, "Please enter an integer");
			return false;
		}
		// MIN
		var iMin = oElement.MIN;
		if(iMin==parseInt(iMin) && sValue.replace(/,/,"")<iMin)
		{
			validationErr(oElement, "Please enter a value greater than or equal to "+formatNumber(iMin));
			return false;
		}
		// MAX
		var iMax = oElement.MAX;
		if(iMax==parseInt(iMax) && sValue.replace(/,/,"")>iMax)
		{
			validationErr(oElement, "Please enter a value less than or equal to "+formatNumber(iMax));
			return false;
		}
	}
	// DATE
	if (oElement.DATE && sValue)
	{
		// Set default date format
		var sFormat = "MM/DD/YYYY";
		if (!isDate(sValue,sFormat))
		{
			validationErr(oElement, "Please enter a date as MM/DD/YYYY");
			return false;
		}
	}
	// REGEXP
	var oRegexp=oElement.REGEXP;
	if(oRegexp && oRegexp.constructor==RegExp && sValue)
	{
		if(!oRegexp.test(sValue))
		{
			validationErr(oElement, "Please enter a valid value");
			return false;
		}
	}
	// EQUALS
	var oEqualValue=oElement.EQUALS;
	if(typeof(oEqualValue) != 'undefined')
	{
		var sEqualValue = getValueOf(oEqualValue);
		if (sValue)
		{
			if(String(sEqualValue) != String(sValue))
			{
				validationErr(oElement, "Please enter a correct value");
				return false;
			}
		}
	}
	// PHONE
	if(oElement.PHONE && sValue)
	{
		var sPhone  = sValue.replace(/\D/g,"");
		var iDigits = sPhone.length;
		if( !(iDigits==10 || iDigits==11 && /^1/.test(sPhone)) )
		{
			validationErr(oElement, "Please enter a valid phone number");
			return false;
		}
	}
	// MAXLEN
	if(sValue && oElement.MAXLEN && isNum(oElement.MAXLEN) && sValue.length>oElement.MAXLEN)
	{
		validationErr(oElement, "Please enter a value with no more than " + formatNumber(oElement.MAXLEN) + " characters");
		return false;
	}
	// MINLEN
	if(sValue && oElement.MINLEN && isNum(oElement.MINLEN) && sValue.length<oElement.MINLEN)
	{
		validationErr(oElement, "Please enter a value with at least " + formatNumber(oElement.MINLEN) + " characters");
		return false;
	}
	// EMAIL
	if(oElement.EMAIL && sValue)
	{
		if(!/^[\w_-]+(\.[\w_-]+)*@[\w_-]+(\.[\w_-]+)*\.\w*$/i.test(sValue))
		{
			validationErr(oElement, "Please enter a valid email address");
			return false;
		}
	}
	// ZIP Code
	if(oElement.ZIP && sValue)
	{
		if(!/^\d{5}(-?\d{4})?$/.test(sValue))
		{
			validationErr(oElement, "Please enter a valid ZIP code");
			return false;
		}
	}
	// AND
	var vAnd=oElement.AND;
	if(vAnd && sValue)
	{
		// If not an array, create one
		if(vAnd.constructor!=Array)
			vAnd = vAnd.toString().split(/,/);
		// Require each element in the list
		var i, iFields=vAnd.length;
		for(i=0; i<iFields; i++)
		{
			var oNewElement =
				(vAnd[i].form)
				? vAnd[i]
				: oElement.form.elements[vAnd[i].trim()];
			if(oNewElement)
			{
				if(!getValueOf(oNewElement))
				{
					validationErr(oNewElement, "Please enter a value");
					return false;
				}
			}
		}
	}
	// OR
	var vOr=typeof oElement.OR=="object";
	if(vOr && !sValue)
	{
		vOr = oElement.OR["fields"];
		if(vOr)
		{
			// If not an array, create one
			if(vOr.constructor!=Array)
				vOr = vOr.toString().split(/,/);
			// Require each element in the list
			var i, iFields=vOr.length;
			var bValue=false;
			for(i=0; i<iFields; i++)
			{
				var oNewElement =
					(vOr[i].form)
					? vOr[i]
					: oElement.form.elements[vOr[i].trim()];
				if(oNewElement)
					bValue |= !!getValueOf(oNewElement);
			}
			if(!bValue)
			{
				validationErr(oElement, oElement.OR["msg"]?oElement.OR["msg"]:"Please enter a value");
				return false;
			}
		}
	}
	// NOSPACE
	if (oElement.NOSPACE && oElement.value)
		oElement.value=oElement.value.replace(/\s/g,"");
	// UPPERCASE
	if (oElement.UPPERCASE && oElement.value)
		oElement.value=oElement.value.toUpperCase();
	// LOWERCASE
	if (oElement.LOWERCASE && oElement.value)
		oElement.value=oElement.value.toLowerCase();

	// Perform onvalidate event handler
	if(typeof oElement.onvalidate=="function" && oElement.onvalidate()==false)
		return false;

	return true;
}
/********************************************
Function: getValueOf
Purpose:  Return the value of a form field as seen at server
Inputs:   oElement - form field
Returns:  boolean
********************************************/
function getValueOf(oElement)
{
	var sReturnValue = null;
	switch (oElement.type)
	{
		case "text" : case "textarea" : case "file" : case "password" : case "hidden" :
			sReturnValue = oElement.value;
			break;
		case "select-one" :
			sReturnValue = oElement.options[oElement.selectedIndex].value;
			break;
		case "select-multiple" :
			var i, iOptions = oElement.options.length;
			for(i=0; i<iOptions; i++)
				if(oElement.options[i].selected && oElement.options[i].value.toString().trim())
				{
					sReturnValue = true;
					break;
				}
			break;
		case "radio" : case "checkbox" :
			if(oElement.checked)
				sReturnValue = oElement.value ? oElement.value : true;
			break;
	}
	return sReturnValue;
}

/*====================================================================
Function: Err
Purpose:  Custom object constructor
Inputs:   None
Returns:  undefined
====================================================================*/
function validationErr()
{
	var oSource  = arguments[0];
	var sMessage = arguments[1];

	var sName = oSource.NAME;
	var sMsg  = oSource.MSG;

	// Alert appropriate error message
	sMsg = sMsg ? sMsg : sMessage + (sName ? " in the "+sName+" field" : "");
	alert(sMsg);

	// Give invalid field focus
	if(oSource.focus)
		oSource.focus();
	if(oSource.select)
		oSource.select();
}


/************************************************
DESCRIPTION: Removes leading and trailing spaces.

PARAMETERS: Source string from which spaces will
  be removed;

RETURNS: Source string with whitespaces removed.
*************************************************/ 
function trimAll( strValue ) {

 var objRegExp = /^(\s*)$/;

    //check for all spaces
    if(objRegExp.test(strValue)) {
       strValue = strValue.replace(objRegExp, '');
       if( strValue.length == 0)
          return strValue;
    }
    
   //check for leading & trailing spaces
   objRegExp = /^(\s*)([\W\w]*)(\b\s*$)/;
   if(objRegExp.test(strValue)) {
       //remove leading and trailing whitespace characters
       strValue = strValue.replace(objRegExp, '$2');
    }
  return strValue;
}