//==========================================================================
//                     Mobius e-Solutions
//==========================================================================
//
//  COPYRIGHT 2000-2002 (c) Mobius e-Solutions
//
//  This software is proprietary to and the copyright and all
//  other intellectual property rights in this software are owned
//  by Mobius e-Solutions.
//
//==========================================================================

//OnBlur function for amount field 
function amountOnBlur(formName, fieldName)
{
	var field;

	field = eval("document." + formName + "." + fieldName);
	
	// get optional field name, if any			
	var fn = field.getAttribute("val_fieldname");    
	if (!fn) 
		fn = fieldName;
		
	// Validate amount field
	if (!validateAmount(field))
    {
		alert("Please enter valid amount for " + fn);
    }
}

//Helper function for validateForm of amount.
function validateAmount(field)
{
	var amount = field.value;
	// Amount pattern dict for amount with 2 decimal places
	var objRegExp = PatternsDict.amount
	var result = objRegExp.test(amount);
	
	//if correct amount format
	if(result)
	{
		var aIndex = amount.indexOf('.');

		//If a decimal place exists
		if(aIndex >= 0)
		{
			//Length of amount string
			var aLength = amount.length;
			
			//No of places after decimal point
			var aPos = aLength - aIndex;
			aPos = aPos - 1; //cos zero based!!!
			if (aPos > 2)
			{
				//Truncate amount so only 2 dps.
				field.value =  amount.substring(0, aIndex+3);
				return true;
			}
			else
			{
				if(aPos == 1)
				{
					//Add a zero so 2 dps
					field.value = amount + "0";  
					return true;
				}
				else
				{
					if(aPos == 0)
					{
						//There is a decimal place but no zeros, add two zeros so 2 dps
						field.value = amount + "00";
						return true;
					}
					
				}
				field.value = amount;
				return true;
			}
		}
		else
		{
			//No decimal places, add required 2dps
			field.value = amount + ".00";
			return true;
		}//aIndex
	}
	else
	{	
		//Field of invalid format
		field.value = amount;
		//Set focus on error field and return false for error
		field.focus();
		return false;
	}
}

function validateAmountMinMax(minAmount, maxAmount, valAmount, controlValue, fieldName)
{
	if ( minAmount || maxAmount )
	{
		// Sanity check
		if ( isNaN(valAmount) ) {
			return("Unexpected: Failed to parse amount: " + controlValue);
		}

		if (minAmount && maxAmount)
		{
			if ( valAmount < minAmount || valAmount > maxAmount )
			{
				return(fieldName + ": value must be between " + minAmount + " and " + maxAmount);
			}
			else
				return "";
		}
		else
		{
			if (minAmount)
			{
				if ( valAmount <= minAmount )
				{
					return(fieldName + ": value must be greater than " + minAmount);
				}
				else
					return "";
			}
			else
			{
				if ( valAmount > maxAmount )
				{
					return (fieldName + ": value must be less than or equal to " + maxAmount);
				}
				else
					return "";
			}
		}
	}
	
	// Success
	return "";
	
} // validateMinMax

//Helper function for validateForm of Date.
function validateDate( strValue ) {
		
	// use date pattern
	var objRegExp = PatternsDict.dateddmmyyyy
 
	//check to see if in correct format
	if(!objRegExp.test(strValue))
	{
		return false; //doesn't match pattern, bad date
	}
	else
	{
		var arrayDate = strValue.split(RegExp.$1); //split date into month, day, year
		var intDay = parseInt(arrayDate[0],10); 
		var intYear = parseInt(arrayDate[2],10);
		var intMonth = parseInt(arrayDate[1],10);
		
		//check for valid month
		if(intMonth > 12 || intMonth < 1) {
			return false;
		}
	
		//create a lookup for months
		var arrayLookup = new Array("31","28","31","30","31","30","31","31","30","31","30","31");
				
		//check if month value and day value agree
		if (intMonth != 2)
		{
			if(intDay <= arrayLookup[intMonth-1] && intDay != 0)
				return true; //found in lookup table, good date
		}
		else
		{
			//check for February
			var booLeapYear = (intYear % 4 == 0 && (intYear % 100 != 0 || intYear % 400 == 0));
			if( ((booLeapYear && intDay <= 29) || (!booLeapYear && intDay <=28)) && intDay !=0)
				return true; //Feb. had valid number of days
		}
      }
  return false; //any other values, bad date
}

var createValServerSide = false;
var valSSStr = "// field name, Validator, Optional, Message, Field Name\n";
var valCount = 0

function validateForm(theForm) 
{	
	var elArr = theForm.elements;			// get all elements of the form into array
	
	var count = 0;
	var dateString = "";
	
	nextloop:
	for(var i = 0; i < elArr.length; i++)
	{	
	  with ( elArr[i] ) {
		
		var v  = elArr[i].getAttribute("val");	// get validator, if any

		if (!v) // no validator property, skip the lot
		{
			continue nextloop;
		}             					    
	
		var f  = elArr[i].getAttribute("val_nofocus");		// Do not focus on an error
		var o  = elArr[i].getAttribute("val_optional");		// get optional field, if any (means validate only if a value is supplied)
		var m  = elArr[i].getAttribute("val_message");		// get optional message, if any
		var fn = elArr[i].getAttribute("val_fieldname");    // get optional field name, if any			
		var pe = elArr[i].getAttribute("val_parentDiv");	// get optional encasing parent element
		var controlValue = elArr[i].value					// get Controls Value
		var controlName = elArr[i].getAttribute("name")     // get Controls Value
		
		if (createValServerSide)
		{
			// Function for creating server side valPatterns arrays
			// Convert nulls to empty strings
			var mss = m;
			var fnss = fn;
			var oss = o;
			if ( mss == null ) 
				mss = "";
			if ( fnss == null ) 
				fnss = "";
			if ( oss == null || oss == false ) 
				oss = "";
			valSSStr = valSSStr + 'valArray[' + valCount + '] = new Array("' + controlName + '","' + v + '","' + oss + '","' + mss + '","' + fnss + '"' + ')\n';
			valCount = valCount + 1;
		}	
		
		
		// if no fieldname specified, then use html fieldname (which is not too good)
		if (!fn) fn = controlName;
		
		if(controlValue == "" && o)				// If a value is not supplied, and its optional, then dont apply the validation rule
			continue;
					
		// If its parent layer is hidden, ignore it
		if (pe) {
			// If we have specified a parent element, we can ignore
			// the validation if this element is hidden
			
			// Works for NS6 and IE4+
			var myParent;
			if ( document.all ) {
				myParent = eval("document.all." + pe);
			}
			if ( document.getElementById ) {
				myParent = document.getElementById(pe);
			}
			if (myParent.style.display == 'none')
			{
				continue;
			}
		}
					
		//amount validation
		if (v == "amount")
		{
			// This will also work effectively			
			// var myField = eval("document." + theForm.name + "." + controlName);
			//Validate amount field
			var res = validateAmount(elArr[i]);
			
			//If invalid format say so.
			if (!res)
			{
				if (m) {
						alert(m);
				} 
				else {
					alert("Please enter valid amount for '" + fn + "'");
				}
				return false;	
			}
			else 
			{
				// Valid Amount, check for Minimum and Maximum Range
				var minAmount = parseFloat(elArr[i].getAttribute("val_MinAmount"));
				var maxAmount = parseFloat(elArr[i].getAttribute("val_MaxAmount"));
				var valFloat  = parseFloat(controlValue);
				var minMaxResult = validateAmountMinMax(minAmount, maxAmount, valFloat, controlValue, fn);
				
				if ( minMaxResult != "" )
				{
					alert(minMaxResult);
					return false;
				}
				else
					continue;
			}
			
		}//end amount validation
					
		//datecontrol validation
		if (v == "dateControl")
		{
			//If empty and not optional
			if (controlValue == "" && !o)
			{
				if (m) 
				{
					alert(m);
				} 
				else 
				{
					if (fn)
						alert("Please select a valid date for " + fn);
					else
						alert("Please select a valid date");
				}
				if (!f) { focus(); }
				return false;
			} 
			
			//If not empty 
			if (controlValue != "")
			{
				count = count + 1;
					
				//Concat string
				dateString = dateString + controlValue;	
				//Don't add slash on last element
				if (count < 3)
				{	
					dateString = dateString + "/";
				}
				
				//Once got all three values = date format
				if (count == 3)
				{
					count = 0;
					//Validate format and date itself
					if (!validateDate(dateString))
					{
						if (m) 
						{
							alert(m);
						} else if (fn)
							alert("Please select a valid date for " + fn);
						else
							alert("Please select a valid date");
						if (!f) { focus(); }
						return false;
					}
					else
					{
						//Reset dateString to NULL
						dateString = "";
						//Get next val
						continue;
					}
				
				}//count=3
				else
					continue;
			}//!value
			else
			{
			  continue;
			}
		}
		//end datecontrol validation
		
		// If validator is special type of DROP DOWN LIST, RADIOBUTTON
		if (v == "dropdown" || v == "radio" || v == "checkedbox" ) {
			if (o) {
				// If optional then we can safely ignore its validator
				continue;
			}
			else
			{
				if (v == "dropdown")
				{
					var selectedItem      = elArr[i].selectedIndex;
					var selectedItemValue = elArr[i].options[selectedItem].value;
					if (selectedItemValue == "" && !o){
						if (m) {
							alert(m);
						} else {
							alert(fn + ": Please select a response from the drop-down menu");
						}
						if (!f) { focus(); }
						return false;
					} else continue;
				}
				else if (v == "radio") 
				{
					var myRadio = eval("document." + theForm.name + "." + controlName);
					var whichchecked = -1;
					for (var j=0;j<2;j++) {
					if ( myRadio[j].checked )
						whichchecked = j;
					}
			
					if (whichchecked == -1)
					{
						if (m) {
							alert(m);
						} else {
							alert(fn + ": Please provide an answer to this question");
						}
						if (!f) { focus(); }
						return false;	
					} else 
						continue;
				}
				else if (v == "checkedbox")
				{
					// Checkbox MUST be checked to allow continue
					if (!checked)
					{
						if (m) {
							alert(m);
						} else {
							alert(fn + ": You must select this box before we can continue");
						}
						if (!f) { focus(); }
						return false;
					} else
						continue;
				}
				else
				{
					alert("Internal Error: Invalid Validation Type: " + v);
					return false;
				} // end if (elArr[i].val_type == "dropdown")
			} // end if optional
		} // end if (elArr[i].val_type)

		// Get Pattern Matching for edit box inputs
		var thePat = PatternsDict[v];				// select the validating regular expr
		var gotIt = thePat.exec(controlValue);      // run it on value of elArr[i]
		
		if(!gotIt) {
			// If no message then print a standard message
			if(!m)
			{
				var errMsg = patErrors[v][1];
				// index into patError array and add val_title to end to make a user friendly message
				alert(fn + errMsg);
			}
			else
			{
				// Print specified error message
				alert(m);
			}
			
			// Focus on erroneous edit box unless told otherwise
			if (!f) { focus(); }

			// Form submittal has failed
			return false;
		}
		else
		{	
			 // extra min max check for amounts
			 if ( v == "amountInteger" || v == "integer" ) {
				// Valid Amount, check for Minimum and Maximum Range
				var minAmount = parseInt(elArr[i].getAttribute("val_MinAmount"));
				var maxAmount = parseInt(elArr[i].getAttribute("val_MaxAmount"));
				var valFloat  = parseInt(controlValue);
				var minMaxResult = validateAmountMinMax(minAmount, maxAmount, valFloat, controlValue, fn);
				
				if ( minMaxResult != "" )
				{
					alert(minMaxResult);
					return false;
				}
				else
					continue;
			} // end if (v== "a)		
		} // end if (!gotIt)
	  } // end with
	} // for elArr
		    
	if (createValServerSide)
	{
		document.getElementById("debug").innerHTML = "<pre>" + valSSStr + "</pre>";
		document.getElementById("debug").innerHTML = document.getElementById("debug").innerHTML + "<b>TO TURN THIS OFF, goto valPatterns.js and set createValServerSide to false.<b>";
		return false;
	}	
	return true;
	
	
}

/*
The following are held in a Pattern object and used to validate date entered in
form fields.

  email			- checks format of email address
  phone			- Numeric with Spaces
  numeric		- checks for valid numeric value
  alphaSpaces	- checks the value only contains characters but can also contain spaces
  alphaSpaces   -
  alphaNoSpaces -  
  alphaNumeric  -
  alphaNumericNoSpaces - 
  integer       - Checks for a valid positive integer value
  amountInteger - Checks for an amount in whole units
  dateddmmyyyy	- checks for valid date in internal format
  password		- checks format of password, 4-40 characters
  
 */

var PatternsDict = new Object();

// Legacy Patterns, Remove Whenever
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 = /^\d{2}:\d{2}$/;
// matches 12:34 but also 75:83
PatternsDict.time2=/^([1-9]|1[0-2]):[0-5]\d$/;
// matches 5:04 or 12:34 but not 75:83
PatternsDict.currency2 = /(^\$\d{1,3}(,\d{3})*\.\d{2}$)|(^\(\$\d{1,3}(,\d{3})*\.\d{2}\)$)/;
// matches ...
PatternsDict.time12Hour = /^([1-9]|1[0-2]):[0-5]\d(:[0-5]\d(\.\d{1,3})?)?$/;
//matches formats such as HH:MM or HH:MM:SS or HH:MM:SS.mmm 

// Current Patterns
PatternsDict.email = /^[a-z0-9]([a-z0-9_\-\.]*)@([a-z0-9_\-\.]*)(\.[a-z]{2,3}(\.[a-z]{2}){0,2})$/i;  //Accounts for email with country appended does not validate that email contains valid URL type (.com, .gov, etc.) 
PatternsDict.phone = /^[0-9 ]*$/;
PatternsDict.numeric = /(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/;  //matches valid numbers

PatternsDict.alphaSpaces          = /^([a-zA-z\s\.\-\;,:!\(\)\[\]]+)$/;					//
PatternsDict.alphaNoSpaces        = /^([a-zA-z\.\-\;,:!\(\)\[\]]+)$/;                   //
PatternsDict.alphaNumeric         = /^[\w][\w\s\.\-;,:!\(\)\[\]]*$/;	                // cannot start with spaces
PatternsDict.alphaNumericNoSpaces = /^[\w+\.\-;,:!\(\)\[\]][\w+\.\-;,:!\(\)\[\]]*$/;    // matches any character and number, must be at least 1 character

PatternsDict.alphaSpacesLoose          = /^([a-zA-z\s\.\-\'\;,:!\(\)\[\]]+)$/;               //
PatternsDict.alphaNoSpacesLoose        = /^([a-zA-z\.\-\'\;,:!\(\)\[\]]+)$/;                 //
PatternsDict.alphaNumericLoose         = /^[\w][\w\s\.\-\';,:!\(\)\[\]]*$/;	                 // cannot start with spaces
PatternsDict.alphaNumericNoSpacesLoose = /^[\w+\.\-\';,:!\(\)\[\]][\w+\.\-;,:!\(\)\[\]]*$/;  // matches any character and number, must be at least 1 character

PatternsDict.dateddmmyyyy = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/;  //matches valid dates with 2 digit day, 2 digit month, 4 digit year. Date separator can be ., -, or /. Ex. mm/dd/yyyy or mm-dd-yyyy or mm.dd.yyyy

PatternsDict.password = /^([0-9a-zA-z\s]{4,40})$/;          //matches any character or integer between 4-40 characters
PatternsDict.amount   = /(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/;
// Actual amount after trimming should match ^[0-9]+[0-9]{2}$

PatternsDict.integer       = /^[0-9]+$/;       // Instead of numeric which checks for 999.999, have integer check for whole number
PatternsDict.amountInteger = /^[0-9]+$/;       // Whole Numbered Amount, gives a specific money error message

//Pattern error arrays.  Used to send errors back to forms if not specified on Input string
var patErrors = new Array;

patErrors['zip'] = new Array("Incorrect Zip code Entered", "Error2");
patErrors['currency'] = new Array("Incorrect Currency entered", "an invalid amount");
patErrors['currency2'] = new Array("Incorrect Currency entered", "an invalid amount");
patErrors['time'] = new Array("Incorrect Time entered", "invalid time, values allowed: 5:04, 12:34");
patErrors['time2']= new Array("Incorrect Time entered", "invalid time, values allowed: 5:04, 12:34, 75:38");
patErrors['time12Hour']= new Array("Incorrect time entered", ": invalid time, values allowed: HH:MM, HH:MM:SS, HH:MM:SS.mmm" );
patErrors['phone'] = new Array("Incorrect phone number entered", ": Invalid phone number, please enter only numbers and optional spaces.");
patErrors['email'] = new Array("Incorrect email format", ": Please check your email address");
patErrors['numeric'] = new Array("Incorrect value entered", ": Please use numbers only");
patErrors['date']= new Array("Incorrect date entered", ": Invalid date, values allowed: dd/mm/yyyy, dd-mm-yyyy, dd.mm.yyyy");
patErrors['alphaSpaces'] = new Array("Incorrect value entered", ": Please use letters only");
patErrors['alphaNoSpaces'] = new Array("Incorrect value entered", ": Please use letters with no spaces only");
patErrors['alphaNumeric'] = new Array("Incorrect value entered", ": Please use letters and/or numbers only. Please avoid special characters.");
patErrors['alphaNumericNoSpaces'] = new Array("Incorrect value entered", ": Please use letters and/or numbers only. Please avoid special characters and spaces.");
patErrors['alphaSpacesLoose'] = new Array("Incorrect value entered", ": Please use letters only");
patErrors['alphaNoSpacesLoose'] = new Array("Incorrect value entered", ": Please use letters with no spaces only");
patErrors['alphaNumericLoose'] = new Array("Incorrect value entered", ": Please use letters and/or numbers only. Please avoid special characters.");
patErrors['alphaNumericNoSpacesLoose'] = new Array("Incorrect value entered", ": Please use letters and/or numbers only. Please avoid special characters and spaces.");
patErrors['password'] = new Array("Incorrect value entered", ": Your password must be at least 4 characters long");
patErrors['amountInteger'] = new Array("Incorrect value entered", ": is not a valid amount, please enter the amount in whole pounds only");
patErrors['integer'] = new Array("Incorrect value entered", ": Please use whole numbers only");
