
//-------- form validation functions

var RegEx_Postal = "^\\d{5}-\\d{4}|\\d{5}|[ABCEGHJKLMNPRSTVXY]\\d[A-Z]\\s?\\d[A-Z]\\d$"
var RegEx_EMail = "^[A-Z0-9._%-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$"
var RegEx_Phone = "^\\(?[0-9]{3}\\)?[ -.]?[0-9]{3}[ -.]?[0-9]{4}[ -.]?[0-9]*$"

var RegEx_Phone_Prompt = "Please enter a valid phone number, including area code.\nValid formats include:\n\n(555)-555-5555\n555-555-5555\n555.555.5555\n\nAn extension may also be added (one or more digits)."


// Reg Ex references: 
//		http://www.regular-expressions.info/reference.html
//		http://msdn.microsoft.com/en-us/library/1400241x(VS.85).aspx
//
// meta characters:  [\^$.|?*+()	to match these, add \\ in front
//		? match preceding token 0 or more times
//		+ match preceding token 1 or more times
//		. match any character
//		^ match the start of the string
//		$ match the end of the string
//		\d match digit
//		\D match non-digit
//		\w match word character
//		\W match non-word
//		\s match space
//		\S match non-space
//		[^ negate match (caret inside [

/*
* Modified 2011-05-06 radek k @inmca.com
* Using class names instead of extended custom attributes ('required', 'validation') for html compliance.
*/

//*********** server side validation

function TestForTags (data, name)
{
	data = new String (data)
	if (data != "")
		if (data.indexOf (String.fromCharCode(60)) > -1)
			return "Invalid data for field: " + name + ". HTML tags are not allowed."
	return ""
}

function TestForMalformed (TestDoc, data, name)
{
	if (data != "")
	{
		//* remove ampersand from text before testing xml
		data = StrReplace (data, "&", "")
		TestDoc.loadXML ("<test>" + data + "</test>")
		if (TestDoc.xml == "")
			return "Malformed XML error in field: " + name
	}
	return ""
}

function ValidateFormServerSide (fieldNodes)
{
	//*** server side form validation
	//*** check submitted form for valid data.  If an error is found, return an error message otherwise return a blank stirng
	var ErrMsgHead = "<h3>Invalid Data</h3><br />"

	var RegEx_Postal = "^\\d{5}-\\d{4}|\\d{5}|[ABCEGHJKLMNPRSTVXY]\\d[A-Z]\\s?\\d[A-Z]\\d$"
	var RegEx_EMail = "^[A-Z0-9._%-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$"

	if (typeof(OVERRIDE_RegEx_Phone) != "undefined")
		var RegEx_Phone = OVERRIDE_RegEx_Phone
	else
		var RegEx_Phone = "^\\(?[0-9]{3}\\)?[ -.]?[0-9]{3}[ -.]?[0-9]{4}[ -.]?[0-9]*$"


	var TestDoc = Server.CreateObject("MSXML2.DOMDocument");

	for (var i=3;i<fieldNodes.length;i++)
	{
		var fldName = fieldNodes.item(i).getAttribute("name")
		var FormFldIndex = FindFormField (fldName)
		if (FormFldIndex < FormNames.length)
		{
			var fldData = FormValues[FormFldIndex]

			if (fieldNodes.item(i).getAttribute("allowXML") == null)
			{
				var malformedError = TestForTags (fldData, fldName)
				if (malformedError != "")
					return malformedError
			}
			var malformedError = TestForMalformed (TestDoc, fldData, fldName)
			if (malformedError != "")
				return malformedError

			if (fieldNodes.item(i).nodeName.toLowerCase() == "input")
			{
				if( isRequiredField(fieldNodes.item(i)) && fldData == "" )
					return ErrMsgHead + "Required Field " + fldName + " was not entered.";
				var validateAs = getValidationType( fieldNodes.item(i) );
				if( validateAs != "" )
				{
					switch( validateAs )
					{
						case "number":
							if (isNaN(fldData))
								return ErrMsgHead + "Invalid data for field: " + fldName + ". Please enter a number."
							break
						case "postal":
							if ((fldData != "") && (!ValidateRegExSrv (fldData, RegEx_Postal)))
								return ErrMsgHead + "Invalid data for field: " + fldName + "(" + fldData + "). Please enter a valid postal/zip code."
							break
						case "email":
							if ((fldData != "") && (!ValidateRegExSrv (fldData, RegEx_EMail)))
								return ErrMsgHead + "Invalid data for field: " + fldName + "(" + fldData + "). Please enter a valid email address."
							break
						case "phone":
							if ((fldData != "") && (!ValidateRegExSrv (fldData, RegEx_Phone)))
							{
								if (typeof(OVERRIDE_RegEx_Phone_Prompt) != "undefined")
									var ErrMsg = OVERRIDE_RegEx_Phone_Prompt
								else
									var ErrMsg = "Please enter a valid phone number, including area code.<br />Valid formats include:<br />(555)-555-5555<br />555-555-5555<br />555.555.5555<br />An extension may also be added (one or more digits)."
								return ErrMsgHead + "Invalid data for field: " + fldName + "(" + fldData + "). <br />" + ErrMsg 
							}
							break
						case "date":
							if ((fldData != "") && (!isValidDate (fldData)))
								return ErrMsgHead + "Invalid data for field: " + fldName + ". Please enter a valid date either as MMM DD YYYY (eg. Jan 31 2000), or MM/DD/YYYY (eg. 1/31/2000) ."
							if (fldData != "")
							{
								try
								{
									var d = new Date (fldData)
									if (isNaN(d))
										return ErrMsgHead + "Invalid data for field: " + fldName + ". Please enter a valid date either as MMM DD YYYY (eg. Jan 31 2000), or MM/DD/YYYY (eg. 1/31/2000) ."
									if (d.getFullYear() < 1900)
										return ErrMsgHead + "Invalid data for field: " + fldName + ". Please enter a year 1900 or greater."
									break
								}
								catch (e)	
								{	
									return ErrMsgHead + "Invalid data for field: " + fldName + ". Please enter a valid date either as MMM DD YYYY (eg. Jan 31 2000), or MM/DD/YYYY (eg. 1/31/2000) ."
								}
							}
							break
					}
				}
			}
		}
	}
	return ""
}


function ValidateRegExSrv (strSearch, expr)
{
	try
	{
		var regEx = new RegExp (expr, "i")
	}
	catch (e)
	{
		Response.Write ('regular expression error: ' + e)
		Response.End
	}
	var arr = strSearch.match(regEx)
	return ((arr != null) && (arr.length == 1) && (strSearch == arr[0]))
}






//*********** client side validation

function ValidateForm (theForm)
{
	//*** client side form validation
	//*** auto field validation 
	for (var i=3;i<theForm.elements.length;i++)
	{
		var e = theForm.elements[i]
		if( isRequiredField(e) && NotFilled(e) )
			return false
		switch( getValidationType(e) )
		{
			case "number":
				if (NotNumeric(e))
					return false
				break
			case "email":
				if (NotEmail(e))
					return false
				break
			case "date":
				if (NotDate(e))
					return false
				break
			case "postal":
				if (NotPostalZip(e))
					return false
				break
			case "phone":
				if (NotPhoneNumber(e))
					return false
				break
		}
		if (e.name == "CAPTCHA")
			if (e.value == "")
			{
				alert ("Please enter the confirmation code.")
				e.focus ()
				return false
			}
	}
	return true
}


function NotSelected (fld, msg)
{
	if (fld.selectedIndex == -1)
	{
		alert (msg)
		fld.focus ()
		return true
	}
	return false
}

function NotFilled (fld)
{
	if (fld.type == "checkbox")
		if (!fld.checked)
		{
			alert ("Checkbox must be checked.")
			fld.focus ()
			fld.select ()
			return true
		}
	if (fld.value == "")
	{
		alert ("Required field is missing.  Please enter.")
		fld.focus ()
		return true
	}
	return false
}

function NotYearFilled (fld)
{
	if (NotFilled (fld))
		return true
	if (isNaN(fld.value) || (fld.value < 1900))
	{
		alert ("Please enter a four digit year.")
		try
		{
			fld.focus ()
			fld.select ()
		}
		catch (e) {}
		return true
	}
	return false
}

function NotNumeric (fld)
{
	if (fld.value == "")
		return false
	if (isNaN(fld.value))
	{
		alert ("Please enter a number.")
		FocusField (fld)
		return true
	}
	return false
}

function NotDate (fld, cantBeBlank)
{
	if (fld.value == "")
		if (cantBeBlank)
		{
			alert ("Please enter a Date either as MMM DD YYYY (eg. Jan 31 2000), or MM/DD/YYYY (eg. 1/31/2000) .")
			FocusField (fld)
			return true
		}
		else
			return false
	try
	{
		if (!isValidDate (fld.value))
//		if (isNaN(d))
		{
			alert ("Please enter a Date either as MMM DD YYYY (eg. Jan 31 2000), or MM/DD/YYYY (eg. 1/31/2000) .")
			FocusField (fld)
			return true
		}
		var d = new Date (fld.value)
		if (d.getFullYear() < 1900)
		{
			alert ("Please enter a year 1900 or greater.")
			FocusField (fld)
			return true
		}
		return false
	}
	catch (e){}
	alert ("Please enter a Date either as MMM DD YYYY (eg. Jan 31 2000), or MM/DD/YYYY (eg. 1/31/2000) .")
	FocusField (fld)
	return true
}

function NotPostalZip (fld)
{
	if ((fld.value != "") && (!ValidateRegEx (fld.value, RegEx_Postal)))
	{
		alert ("Please enter a valid postal code or zip code.")
		FocusField (fld)
		return true
	}
	return false
}

function NotEmail (fld)
{
	if ((fld.value != "") && (!ValidateRegEx (fld.value, RegEx_EMail)))
	{
		alert ("Please enter a valid email address.")
		FocusField (fld)
		return true
	}
	return false
}


function NotPhoneNumber (fld)
{
	if ((fld.value != "") && (!ValidateRegEx (fld.value, RegEx_Phone)))
	{
		alert (RegEx_Phone_Prompt)
		FocusField (fld)
		return true
	}
	return false
}

function ValidateRegEx (strSearch, expr)
{
	try
	{
		var regEx = new RegExp (expr, "i")
	}
	catch (e)
	{
		alert ('regular expression error: ' + e)
	}
	var arr = strSearch.match(regEx)
	return ((arr != null) && (arr.length == 1) && (strSearch == arr[0]))
}


function FocusField (fld)
{
	try
	{
		fld.focus ()
		fld.select ()
	}
	catch (e) {}
}

function FormBlankFieldTest (frm, fldIndexList)
{
	// fldIndexList delimit with  ,(or) |(and)
	var unfilled = -1
	var ind = fldIndexList.split ("|")
	for (var i=0;i<ind.length;i++)
	{
		var filled = false
		var ind2 = ind[i].split (",")
		for (var j=0;j<ind2.length;j++)
			if (frm.elements[ind2[j]].value!="")
				filled = true
			else
				unfilled = ind2[j]
		if (!filled)
			return unfilled
	}
	return -1
}

function isValidDate (str)
{
	var MonthAbbr = new Array ("jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec")
	var MonthNames = new Array ("January","February","March","April","May","June","July","August","September","October","November","December")
	try
	{
		var d = new Date (str)
		var a = str.split ("/")
		if (a.length == 3)
		{
			// *** date in MM/DD/YYYY format
			if (a[1] != d.getDate())
				return false
			if (a[0] != (d.getMonth()+1))
				return false
			return true
		}
		// *** date in MMM DD YYYY format
		var a = str.split (" ")
		if (a.length != 3)
			return false
		if (a[1] != d.getDate())
			return false
		if (MonthAbbr[d.getMonth()] != a[0].toLowerCase())
			return false
		return true
	}
	catch (e) {}
	return false
}

/* 2011-05 rk
* Instead of <required="true"> use class "isRequired", and
* instead of <validate="email"> use class "validateAs:email" (or validateAs:phone, etc.)
*/
function isRequiredField( element )
{
	return ((" "+element.getAttribute("class")+" ").indexOf(" isRequired ") > -1) || (element.getAttribute("required")=="true");
	// FIXME: Old method is attribute "required=true"
}

function getValidationType( element )
{
	// FIXME: Old method {{
	if( (""+element.getAttribute("validation")) != "" && element.getAttribute("validation") != null )
		return element.getAttribute("validation");
	// }}

	var prefixToFind = "validateAs:";
	var elementClasses = ""+element.getAttribute("class");
	var i = elementClasses.indexOf( prefixToFind );
	if( i > -1 ){
		var ss = elementClasses.substring( i + prefixToFind.length );
		return ss.substring(0, (ss+" ").indexOf(" "));
	}
	return "";
}

