// ==============================================================================
//                     JavaScript Form Validation Libarary
// ==============================================================================

// Validate the fields on a form using specific, custom attributes
// required="true" => this field must have something in it. Use this
//	in combination with another rule normally.
// validate="true" => validate this field, provided it has a rule
// rule="rule" => use the rule specified to validate this input "value"
//	Options for "rule":
//		"txt"		= Text Only (and spaces)
//		"num"		= Numbers Only (allow decimal)
//		"int"		= Integers only
//		"phone" 	= Phone number, (0-9()-+)
//		"date"		= Date Format (dd/mm/yyyy)
//		"email" 	= Email addresses
//		"alnum" 	= Alpha-Numeric Values
//		"curr"		= Currency ($xxxx..."."xx)
//		"addr"  	= Address characters (a-zA-Z0-9-,#)
//		"name" 		= Most likely characters in a name  (a-zA-Z,.-)
//		"free"		= Freeform text (a-zA-Z0-9+-_()[]/&)
//		"nobadsql"	= Denies harmful SQL syntax
//		"notnull"	= Must enter something
//		RegExp		= Any valid regular expression you may specify
//					ie. "/^[\d]{0,3}.[\d]{0,3}.[\d]{0,3}$/" = an IP number
// error="Extended String" => the error message if validation fails. (without a
//	newline character at the end or a bullet at the start, they are added)
// ==============================================================================


/* 
* Apply a regular expression to the specified form element. 
* Returns true if the pattern matches, false if it doesn't.
*/
function validateField(field, validation_code) {
	result = false;

	// Check if they supplied a custom RegExp or just a rule name
	if (validation_code.charAt(0) != "/") {
		switch (validation_code.toLowerCase()) {
			case "txt" : 			// Text only allowed
				re = /^[a-z ]*$/i
				break;
			case "num" :			// Only numbers (allow decimal)
				re = /^[\d\.]*$/
				break;
			case "int" :			// Integers only
				re = /^\d*$/
				break;
			case "phone" :			// Phone number characters
				re = /^[\d \-\(\)\+]*$/
				break;
			case "date" :			// Well-formed Dates
				re = /^(()|(\d{1,2}(\/|-)\d{1,2}(\/|-)\d{2,4}))$/
				break;
			case "email" :			// Something valid-ish for an email
				re = /^[a-z\d\.\-_]+@[a-z\d\.\-_]{2,}\.[a-z]{2,10}$/i
				break;
			case "alnum" :			// Alpha-numeric characters
				re = /^[\w ]*$/i
				break;
			case "curr" :			// Currency (using "$", "," and ".")
				re = /^\$?\d*,?\.?\d{0,2}$/i
				break;
			case "addr" :			// Base Address rule
				re = /^[\w- \.,#]*$/gi
				break;
			case "name" :			// Good for validating names
				re = /^[a-z,\-\. ]*$/gi
				break;
			case "free" :			// Freeform, text, num and some chars
				re = /^[\w\-\+\(\)\[\]\\/&, ]*$/i
				break;
			case "nobadsql" :		// Denies SQL which could be harmful
				re = /((delete|drop|update|replace|kill|lock|processlist) )/gi
				result = true;
				break;
			case "notnull" :		// Requires *anything*
				re = /.+/
				break;
			default :			// Default - See "free"
				re = /^[\w\-\+\(\)\[\]\\/&, ]*$/i
		}
	}
	
	// This means they specified a RegExp of their own, which should be
	// in the form "/<RegExp>/" and needs to be "eval"ed before using.
	else {
		re = eval(validation_code);
	}
	
	// Do the actual regular expression testing against the string
	// and return the result.
	if (re.test(field.value)) {
		// If this rule uses result inversion, then return the opposite
		if (result == true) {
			return false;
		}
		else {
			return true;
		}
	}
	else {
		// If this rule uses result inversion, then return the opposite
		if (result == true) {
			return true;
		}
		else {
			return false;
		}
	}
}

/*
 * FormData: html element, rule text, error message
 **/
function FormData(ele, rule, error) {
	this.ele = ele;
	this.rule = rule;
	this.error = error;
}

/*
 * Validate all FormData in an array
 **/
function validateFormDataArray(allFds){
	var errorMsg ="";
	var focusElement;
	
	for (i = 0; i< allFds.length; i++){
		fd = allFds[i];
		
		if (!validateField(fd.ele, fd.rule)){
			errorMsg += fd.error +"\n";
			
			//if (focusElement==undefined){ 
			// above statement doesn't work for IE5, error: 'undefined' is undefined
			// foo === void 0: foo was either null or undefined.
			// Boolean(foo): foo is not undefined, null, false, 0, or ""
			if (focusElement === void 0) {
				focusElement = fd.ele;
			}
		}
	}		
	
	if (errorMsg == ""){
		//return true;
		return "";
	} else {
		//alert(errorMsg);
		focusElement.focus();		
		//return false;	
		return errorMsg;
	}	
}

// ==============================================================================