// Use NonEmpty='1' or DataType='Date|Int|Float|Money' to assist in data validation:
//		<input NonBlank='1' DataType='Date' FieldName='My Date'> is tested to avoid an empty field and ensure a valid date
function ValidateFormFields(oForm)
{
	var oElements = oForm.elements;
	var nElementCount = oElements.length;
	
	// Clear any prior error style settings
	for (nEle = 0; nEle < nElementCount; ++nEle)
	{
		var oElement = oElements[nEle];
		if (undefined != oElement.style)
		{
			if ("red" == ("" + oElement.style.borderColor).toLowerCase())
			{
			    if (null != oElement.runtimeStyle)
			    {
			        oElement.style.borderColor = oElement.runtimeStyle.borderColor;
			        oElement.style.borderStyle = oElement.runtimeStyle.borderStyle;
			    }
			    else
			    {
			        oElement.style.borderColor = "";
			        oElement.style.borderStyle = "";
			    }
			}
		}	
	}
	
	for (nEle = 0; nEle < nElementCount; ++nEle)
	{			
		var oElement = oElements[nEle];
		if ("hidden" == ("" + oElement.type).toLowerCase())
			continue;		
		
		// Look for <input NonBlank='1'> to avoid empty fields
		if (false == ValidateNonBlank(oElement))
			return false;
			
		// SpellCheck unchecked fields
		if (false == SpellCheck(oElement))
		    return false;
		
		// Look for <input DataType='Date'> to avoid invalid dates
		strDateType = oElement.getAttribute("DataType");
		if (undefined != strDateType && (undefined != oElement.value && "" != oElement.value))
		{
			switch(strDateType.toLowerCase())
			{
				case "date":
				if (false == ValidateDateField(oElement))
					return false;
				break;
				
				case "int":
				case "integer":
				if (false == ValidateInteger(oElement))
					return false;
				break;
				
				case "float":
				case "real":
				if (false == ValidateFloat(oElement))
					return false;
				break;
				
				case "email":
				if (false == ValidateEmail(oElement))
					return false
				break;
				
				case "money":
				if (false == ValidateMoneyField(oElement))
					return false;
				break;
				
				default:
				alert("Unknown DataType value: " + oElement.getAttribute("DataType"));
				return false;
				break;
			}
		}
		
		// Check that the text isn't too long
        strMaxLength = oElement.getAttribute("MaxLength");
        if (undefined != strMaxLength)
        {
            nMaxLen = parseInt(strMaxLength);
            if (!isNaN(nMaxLen))
            {
                if (nMaxLen < oElement.value.length)
                {
                    return IndicateInvalidData(oElement, "You are only allowed " + strMaxLength + " characters for the selected field but you have entered " + oElement.value.length + " characters.");
                }
            }
        }
	}
	return true;
	
	function SpellCheck(oElement)
	{
        var strElementName = oElement.getAttribute("Name");
        var strErrMsg = "";
        if (undefined == strElementName)
            strErrMsg = "Please complete spell check.";
        else
            strErrMsg = "Please complete spell check for " + strElementName;
            
	    //the SpellChecked attribute is set in the Tf7GoogieSpellUtil.js script
	    //which is where spelling objects are attached to text areas
	    var strSpellChecked = String(oElement.getAttribute("SpellChecked"));
        switch (strSpellChecked)
	    {
	        case undefined: //only fields with a SpellChecked attribute will be spell checked
	        break; 
	        
	        //if the text area has not been checked
	        case "no":
	        {
	            //check to make sure the crc32 function is available
	            if (undefined == crc32)
	            {
	                alert("The crc32 function not defined.  CRC32.js needs to be included in the calling page");
	                return false;
	            }
	            
	            //check to see if the text area has changed
	            var nOriginalCRC = oElement.getAttribute("CRC32"); //original crc32 value is calculated in Tf7GoogieSpellUtil.js                 
	            var nCurrentCRC = crc32(oElement.value);
	            if (nOriginalCRC != nCurrentCRC)
	            {   
	                //if the crc values dont match, the text has changed
	                alert(strErrMsg);
	                
	                return false;
	            }
	            else
	                return true; //no changes to spellcheck
	        }
	        break;
	        
	        case "yes":
	        return true;
	        break;
	    }
	    
	}

	
	function ValidateNonBlank(oElement)
	{
		// Look for <input NonBlank='1'> to avoid empty fields
		strFieldName = String(oElement.getAttribute("NonBlank"));
		switch (strFieldName)
		{
			case undefined:
			break;
			
			case "1":
			case "true":
			case "yes":
			if (IsBlankField(oElement))
				return IndicateInvalidData(oElement, "The selected field cannot be blank");
			break;
		}	
	}
		
	// Validate integer numbers
	function ValidateInteger(oElement)
	{
		// Make sure a date value is obvious 
		strInt = oElement.value;	
		if (-1 != strInt.search(/[^0-9-]+/))
			return IndicateInvalidData(oElement, "You can only enter a interger number (no decimal point) for the selected field");
		return true;
	}
	
	// Validate a floating point number
	function ValidateFloat(oElement)
	{
		// Make sure a date value is obvious 
		strFloat = oElement.value;	
		if (-1 != strFloat.search(/[^0-9\.-]+/))
			return IndicateInvalidData(oElement, "You can only enter a decimal number for the selected field");
		return true;
	}
	
	// Validate an email address
	function ValidateEmail(oElement)
	{
		if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(oElement.value))
			return true;
			
		return IndicateInvalidData(oElement, "You must enter a valid email for the selected field");
	}
	
	// Validate a money field
	function ValidateMoneyField(oElement)
	{
		strAmountAsNumber = oElement.value.replace(/,/g, '').replace(/\$/g, '');
		if (-1 != strAmountAsNumber.search(/[^0-9\.-]+/))
			return IndicateInvalidData(oElement, "You must enter a valid numeric currency value for the for the selected field");
		
		if (isNaN(strAmountAsNumber))
			return IndicateInvalidData(oElement, "You must enter a valid currency amount for the selected field");
		return true;
	}
}

// Determine if a field is blank
function IsBlankField(oElement)
{
	if ("" == oElement.value || undefined == oElement.value)
		return true;
	return false;
}

// Validate the specified element and return false or the date
//	Mon dd, yyyy or Mon-dd-yyyy format is required
function ValidateDateField(oElement)
{
	var strFmt = "\n\nDates must use the following format:  Mon-dd-yyyy or Mon dd, yyyy";
	
	// Make sure a date value is obvious 
	var strDate = oElement.value;
	strDate = strDate.replace(/\s/g, '');	// Strip spaces

	// Check the month name
	var strMonth = strDate.substr(0, 3);
	if (-1 == strMonth.search(/^jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec/i))
		return IndicateInvalidData(oElement, "You must use a valid month abbreviation for the selected field:\n\tJan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec" + strFmt);
		
	// Strip the month
	strDate = "" + strDate.substr(3);
	if (0 == strDate.search(/-/))
		strDate = strDate.replace(/-/, '');
			
	// Get the day of the month
	var nDay = parseInt(strDate.substr(0, 2).replace(/,| |-/, ''), 10);
	if (isNaN(nDay) || nDay < 1)
		return IndicateInvalidData(oElement, "You must enter a valid day of the month for the selected field" + strFmt);
					
	// Get the year	
	var strYear = "" + strDate.substr(2).replace(/,| |-/, '');
	if (isNaN(parseInt(strYear, 10)) || (strYear.length != 2 && strYear.length!= 4))
		return IndicateInvalidData(oElement, "You must enter a valid year for the selected field" + strFmt);
	if (0 == parseInt(strYear, 10))
		return IndicateInvalidData(oElement, "You must enter a valid year for the selected field (ie. Do not use 0, use 1900 or 2000)" + strFmt);
	if (parseInt(strYear, 10) >= 100 && parseInt(strYear, 10) <= 999)
		return IndicateInvalidData(oElement, "You must enter a 2 digit or 4 digit year for the selected field." + strFmt);
	
	// Check the number of days (except Feb)
	if (nDay > 31)
		return IndicateInvalidData(oElement, "You must enter a valid day of the month for the selected field (Cannot be greater than 31)" + strFmt);
	if (0 == strMonth.search(/apr|jun|sep|nov/i) && nDay > 30)
		return IndicateInvalidData(oElement, "You must enter a valid day of the month for the selected field (Cannot be greater than 30 for the specified month)" + strFmt);
	if (0 ==  strMonth.search(/feb/i))
	{
		nYear = parseInt(strYear, 10);
		var nValidDays = 28;
		if (nYear%4==0 && (nYear%100!=0 || nYear%400==0))
			nValidDays = 29;
		if (nDay > nValidDays) 
			return IndicateInvalidData(oElement, "You must enter a valid day of the month for the selected field (Cannot be greater than " + nValidDays + " for the February in the specified year)" + strFmt);
	}
	return new Date(parseInt(strYear, 10), parseInt(strMonth.replace(/jan/i, "1").replace(/feb/i, "2").replace(/mar/i, "3").replace(/apr/i, "4").replace(/may/i, "5").replace(/jun/i, "6").replace(/jul/i, "7").replace(/aug/i, "8").replace(/sep/i, "9").replace(/oct/i, "10").replace(/nov/i, "11").replace(/dec/i, "12"), 10)-1, nDay);
}

function IndicateInvalidData(oElement, strError)
{
	// Replace the field name into the error string??
	strFieldName = oElement.getAttribute("FieldName");
	if (undefined != strFieldName && "" != strFieldName)
		strError = strError.replace(/selected field/gi, "\"" + strFieldName + "\" field");
	
	alert(strError);
	oElement.focus();	

	// Highlight with a border color
	try
	{
		oElement.style.borderColor = "red";
		oElement.style.borderStyle = "solid";
	}
	catch(e)	{}
	return false;
}