/*	Company: PFK e-Business Systems
	Created on: 3/28/2001 by Keith Townsend
	Updated on: 4/3/2001 by Keith Townsend
	
	Description:
		This set of functions provides a handy library for Regular Expression validation.
		These functions are useful for both client-side and server-side validation.  
	Usage:
		To include this file for use on the client and the server, use two script tag sets.
		Set the "src" attribute of both script tags to point to this file.  In one of the
		script tags, add runat="server".  That will make this file available to your client
		scripts and server scripts.
		
		Example: (omit periods from script tags...they are only there because real script tags
			would break this script file)
			
			<.script language="javascript" src="RegExpValidation.js"></.script>
			<.script language="javascript" src="RegExpValidation.js" runat="server"></.script>
			
			NOTE:	Including script files in this manner does not work on the server-side in IIS 4.0.
					You must be using IIS 5.0 for the above syntax (second script tag) to work.  If 
					you must deploy on IIS 4.0, you can copy the script from the RegExpValidation.js 
					file and put it directly in the ASP	between <.script language="javascript" 
					runat="server"> and </.script> tags.  Unfortunately, this defeats the reusability 
					of having one source file.  The script itself will function perfectly under both
					IIS 4.0 & IIS 5.0.  The limitation is purely IIS 4.0's failure to properly include
					the source file.  I have tried using the #include directive to include the file,
					without success.  If anyone knows a way to get IIS 4.0 to use the source file,
					please let me know.
			
		To use the validateClientForm & validateServerForm functions, you must have one hidden form 
		field for every visible	field you wish to validate.  The hidden field name must be identical 
		to the visible field name, but prefixed by "v_".  The value of the hidden field then needs 
		to be a regular	expression mask, one of the PatternsDict property names, or the name of a 
		specialized	validation function (function names starting with "func_").  The hidden validation
		fields can reside anywhere in the form.  With your form set up this	way, you won't have to add 
		any specialized client-side or server-side validation script to your web page for validating 
		normal text fields.  Special selection-based validation for radio buttons, check-boxes, and 
		select lists will still need to be handled with specialized code, based	on your needs.  The 
		functions in this file are really only applicable to text-based fields,	such as 
		<input type="text">, <input type="password"> and <textarea>.  Perhaps in the future we will be 
		able to add more robust validation logic for checkboxes, radio buttons, and select lists.
		
		You can also specify a custom error message to display when the validation fails.  All you have
		to do is use another hidden input, much like the validation input, but prefixed with "m_".
		Whatever value you have for that input will automatically override the default error message
		that is generated by the validation script.
		
		If you need to compare two fields together, you can specify the two fields to compare by setting
		up a hidden input prefixed with "c_" for one field, and specify the name of the other field in
		the hidden input's value attribute.  Use "cm_" to prefix the input representing the custom error
		message for the comparison.
		
		For client-side validation, you can call the validateClientForm from the onClick event of your
		FORM tag.  This function will loop through all of the form elements and display an alert box
		listing all errors found.  If you have other specialized validation requirements, you can call
		your special validation function instead, then call validateClientForm from your function after
		your other validation is successful.
		
		For server-side validation, you can call the validateServerForm function from VBScript.  This
		function will do exactly the same validation checking that the validateClientForm does, except
		it returns a string containing the error list instead of directly displaying an alert box.
		
		The ValidateRegExp function is also very handy.  It is used by the validateClientForm and 
		validateServerForm functions, but if you need to do specific regular expression comparisons for 
		strings, you can call the ValidateRegExp function directly from VBScript.  Since regular 
		expressions aren't a feature of VBScript, this can be a very useful	tool for simplifying your 
		VBScript logic.
		
	To Do:
		Incorporate a flexible way to validate checkboxes, radio buttons, and select lists.
*/
	
//	Define the pattern dictionary object & fill it with patterns
var PatternsDict = new Object();
PatternsDict.zip = /\d{5}(-\d{4})?/;								// matches zip codes
PatternsDict.currency = /\$\d{1,3}(,\d{3})*\.\d{2}/;				// matches $17.23 or $14,281,545.45 or ...
PatternsDict.time = /^([1-9]|1[0-2]):[0-5]\d$/;						// matches 5:04 or 12:34 but not 75:83

//	Total form validator (client-side only)
function validateClientForm(theForm){
	var elArr = theForm.elements; 														// get all elements of the form into array
	var ErrorList = new String();														// variable to hold error results
	for(var i = 0; i < elArr.length; i++)												// for each element of the form...
		with(elArr[i]){
			if (name.substr(0, 2) == "v_"){												// if previxed with v_ then we have a validation field
				var Validator = value; 													// get validator
				var TargetName = name.substr(2, name.length - 2);						// identify target field
				var TargetValue = elArr[TargetName].value;								// get target value
				if (!ValidateRegExp(TargetValue, Validator)){							// see if validation fails
					//add error message to final message string
					if (elArr["m_" + TargetName])										// look for custom error message
						ErrorList = ErrorList + "\n-" + elArr["m_" + TargetName].value;
					else																// no custom message for this error...build one
						ErrorList = ErrorList + "\n-failure to match " + Validator 
							+ " from the " + TargetName 
							+ " field to '" + TargetValue + "'";
				}
			}else if (name.substr(0, 2) == "c_"){
				var CompareFromField = name.substr(2, name.length - 2);
				var CompareFromValue = new String(elArr[CompareFromField].value);
				var CompareToField = elArr[name].value;
				var CompareToValue = new String(elArr[CompareToField].value);
				if (CompareFromValue.toString() != CompareToValue.toString()){			// compare fields
					//add error message to final message string
					if (elArr["cm_" + CompareFromField])								// look for custom error message
						ErrorList = ErrorList + "\n-" 
							+ elArr["cm_" + CompareFromField].value;
					else																// no custom message for this error...build one
						ErrorList = ErrorList + "\n-failure to match " 
							+ CompareFromField + " to " + CompareToField;
				}
			}
		}
	if(ErrorList.length > 0){															// see if we have any errors to report
		alert("The following errors were found:\n" + ErrorList);						// report all errors found
		return false;																	// return failure status
	}else
		return true;																	// return success status
}

//	Total form validator (server-side only)
function validateServerForm(objForm){
	var ErrorList = new String();														// variable to hold error results
	for (var i = 1; i < objForm.count + 1; i++){										// for each element of the form...
		if (objForm.Item(i).name)														// test to see which form collection we are dealing with (ASP vs. SmartUpload) because they don't both support the same way of getting an element's name
			var ElementName = objForm.Item(i).name;										// get element name (works with SmartUpload's form collection, not with ASP's Request.Form)
		else
			var ElementName = objForm.Key(i);											// get element name (works with ASP's Request.Form, not with SmartUpload's form collection)
		if (ElementName.substr(0, 2) == "v_"){											// if previxed with v_ then we have a validation field
			var Validator = objForm.Item(i);											// get validator
			var TargetName = ElementName.substr(2, ElementName.length - 2);				// identify target field
			var TargetValue = objForm.Item(TargetName);									// get target value
			if (!ValidateRegExp(TargetValue, Validator)){								// see if validation fails
				//add error message to final message string
				if (String("" + objForm.Item("m_" + TargetName))!="undefined")			// note: the string manipulation is key to getting this check to work...has something to do with what ASP returns when an item isn't found
					ErrorList = ErrorList + "<li>" + objForm.Item("m_" + TargetName);
				else
					ErrorList = ErrorList + "<li>failure to match <i>" + Validator 
						+ "</i> from the <i>" + TargetName + "</i> field to '<i>" 
						+ TargetValue + "</i>'";
			}
		}else if (ElementName.substr(0, 2) == "c_"){									// if prefixed with c_ then we have a comparison validation to do
			var CompareFromField = ElementName.substr(2, ElementName.length - 2);		// identify CompareFrom field
			var CompareFromValue = new String(objForm.Item(CompareFromField));			// get CompareFrom value
			var CompareToField = objForm.Item(i)										// identify CompareTo field
			var CompareToValue = new String(objForm.Item(CompareToField));				// get CompareTo value
			if (CompareFromValue.toString() != CompareToValue.toString()){				// compare fields
				//add error message to final message string
				if (String("" + objForm.Item("cm_" + CompareFromField))!="undefined")	// note: the string manipulation is key to getting this check to work...has something to do with what ASP returns when an item isn't found
					ErrorList = ErrorList + "<li>" 
						+ objForm.Item("cm_" + CompareFromField);
				else
					ErrorList = ErrorList + "<li>failure to match <i>" 
						+ CompareFromField + "</i> to <i>" + CompareToField + "</i>";
			}
		}
	}
	if(ErrorList.length > 0)															// see if we have any errors to report
		return "The following errors were found:<ol>" + ErrorList + "</ol>";			// report all errors found
	else
		return "";																		// return no errors
}

//	generic function that can be called to validate either supplied regular 
//	expressions, named dictionary expressions, or specialized functions
function ValidateRegExp(Value, rExp){
	var y = /^func_*/
	if(y.test(rExp)){
		return eval(rExp + "(\"" + Value + "\");");
	}else if(PatternsDict[rExp]){
		var x = PatternsDict[rExp];
	}else{
		var x = new RegExp(rExp);
	}
	if(x.test(Value))
		return true;
	return false;
}

//	specialized e-mail validation
function func_ValidateEMail(Address){
	var reg1str = "(@.*@)|(\\.\\.)|(@\\.)|(\\.@)|(^\\.)";
	var reg2str = "^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$";
	var reg1 = new RegExp(reg1str);
	var reg2 = new RegExp(reg2str);
	if (!reg1.test(Address) && reg2.test(Address))
		return true;
	return false;
}
