// ##LOG: 
//	07/02/02	Leedrick 	Added functionality for validURL,validDate and validEmail.
//	17/04/02	bsmith		Added if statement so focusField wouldnt break on 
//											radio buttons or checkboxes
//	27/02/02	bkel			Added 'focusField' which makes cursor focus on the first invalid field after it has displayed the list of invalid fields to the user.
//	27/02/02	bkel			Added aditional validation to the email checking (checked for existance of characters that cannot exist in email addresses).
//	12/02/02	bsmith		Changed select box _required code to handle -multi/-one
//	16/01/02	bsmith		Added password to _Required checks

//	31/12/01	shane			Added pre/post formchecks.
//	20/12/01 	Lee 			Altered to return true or false so it can be used in an onsubmit event
//											This allows the form to still have validation when using a submit button
//											which means that the user can submit the form using the enter key.
//	08/10/01	bkel			Added email validation.
//	05/10/01	ben				Created.

// Suffixes used in ins_javascript_formcheck.cfm
// '_validURL'		used to define fields used for URLS
// '_validDate' 	used to define fields used for dates.
// '_validEmail' 	used to define fields used for email addresses.
// '_required'  	used to check if  required fields are filled.

// check / submit the form
	function checkForm(theForm) {
		
		checkForm(theForm, "");
		
	}

	function checkForm(theForm, fieldNamePrefix) {	
		var fieldValid = false;
		var fieldElement;
		var focusField = 'unfocused';
		
		// strAlert is updated if an invalid field is found, so it has to be in this page.
		var strAlert = 'You have not entered some required data, please check the following:\n\n'
		var strControl = strAlert;
		
		//control used to ensure external checks passed (pre and post form checks)
		var externalCheck = true;
		
		var fieldNamePrefixLength = 0;
		
		// use function preFormCheck() to do any extra checks before general form checks
		// function should return a boolean which when false voids extra checking and form submitting. 
		// Function must produce its own error messages		
		
		if(window.preFormCheck != null)
		{
			externalCheck = preFormCheck(theForm);
		}	
	
		
		
		if (externalCheck) {
		
			// loop over all elements of the form
			for(var i=0;i<theForm.elements.length;i++)
			{
				if (fieldNamePrefix) {
					fieldNamePrefixLength = fieldNamePrefix.length;
				} 
				else {
					fieldNamePrefixLength = 0;					
				}
				// if a fieldNamePrefix exists, make sure this field is part of the form section we want to check
				if (fieldNamePrefixLength == 0 || theForm.elements[i].name.substring(0, fieldNamePrefixLength) == fieldNamePrefix)
				{
					//  '_number'
					// check if any fields need to contain a numerical value
					if (theForm.elements[i].name.indexOf('_number') > 0) {
						// field name minus '_number
						var fieldName = theForm.elements[i].name.split('_number')[0];
						var fieldElement = eval('document.forms[\"' + theForm.name + '\"].elements[\"' + fieldName + '\"]');
						
						if(fieldElement.value != '') {
							fieldValid = false;
							if((fieldElement.value * 0) == 0 && fieldElement.value.replace(/\s/g, "").length > 0)
							{
								fieldValid = true;
							}
							
							// if field is not valid
							if(fieldValid == false)
							{
								// add the value of the required field to the alert
								strAlert = strAlert + theForm.elements[i].value + '\n';
							}	
						}									
					}
					
					
					//  '_required'
					// check if any fields need to contain some value
					else if(theForm.elements[i].name.indexOf('_required') > 0 && theForm.elements[i].type != 'file')
					{
						fieldValid = false;
						// field name minus '_required'
						var fieldName = theForm.elements[i].name.split('_required')[0];
						var fieldElement = eval('document.forms[\"' + theForm.name + '\"].elements[\"' + fieldName + '\"]');
						/* field type so we can figure out what to do
							valid field types:
								text
								textarea
								checkbox
								radio
								select-one
								select-multi
						*/
		
		
						// if the field contains multiple instances, get the type of the first one
						var fieldType
						fieldType = fieldElement.type;
		
						if(fieldElement.length > 0 && (fieldElement.type.indexOf('select') < 0))
						{
							var fieldType = fieldElement[0].type;
						}
						
						// if the field is a straight text input
						if(fieldType == 'text' || fieldType == 'textarea' || fieldType == 'password')
						{
							// check to see if a value has been entered
							if(fieldElement.value != '')
							{
								// if is has field is valid
								fieldValid = true;
							}
						}
						else if(fieldType == 'file')
						{
							fieldValid = true;
						}
						// if the field is a checkbox
						else if(fieldType == 'checkbox' || fieldType == 'radio')
						{
							// if there is only one checkbox length will be undefined
							if(fieldElement.length) {
								for(var j=0;j<fieldElement.length;j++)
								{
									// make sure at least one is checked
									if(fieldElement[j].checked == true)
									{
										fieldValid = true;
									}
								}
							}
							else {
								fieldValid = fieldElement.checked;
							}
						}
						// if the field is a select box of some type
						else if((fieldType == 'select-multiple' && fieldElement.selectedIndex != -1) || (fieldType == 'select-one' && fieldElement.selectedIndex != 0))
						{
							fieldValid = true;
						}
		
						// if field is not valid
						if(fieldValid == false)
						{
							// add the value of the required field to the alert
							strAlert = strAlert + theForm.elements[i].value + '\n';	
						}
					}
					//else if the field should contain a valid date
					else if(theForm.elements[i].name.indexOf('_validDate') > 0)
					{
						// field name minus '_validDate'
						var fieldName = theForm.elements[i].name.split('_validDate')[0];
						var fieldElement = eval('document.forms[\"' + theForm.name + '\"].elements[\"' + fieldName + '\"]');
						
						//if the field is not empty (the field is allowed to be empty, unless the _required function is used
						if(fieldElement.value != '')
						{
							//if the date is not valid, add it to the list of fields to alert
							if(!checkValidDate(fieldElement.value))
							{
								// add the value of the required field to the alert
								strAlert = strAlert + theForm.elements[i].value + '\n';	
							}
						}
					}
					//else if the field should contain a valid date
					else if(theForm.elements[i].name.indexOf('_validFile') > 0)
					{
						// field name minus '_validDate'
						var fieldName = theForm.elements[i].name.split('_validFile')[0];
						var fieldElement = eval('document.forms[\"' + theForm.name + '\"].elements[\"' + fieldName + '\"]');
						
						//if the field is not empty (the field is allowed to be empty, unless the _required function is used
						if(fieldElement.value != '')
						{
							//if the date is not valid, add it to the list of fields to alert
							if(!validFile(fieldElement.value))
							{
								// add the value of the required field to the alert
								strAlert = strAlert + theForm.elements[i].value + '\n';	
							}
						}
					}
					//else if the field should contain a valid URL
					else if(theForm.elements[i].name.indexOf('_validURL') > 0)
					{
						// field name minus '_validURL'
						var fieldName = theForm.elements[i].name.split('_validURL')[0];
						var fieldElement = eval('document.forms[\"' + theForm.name + '\"].elements[\"' + fieldName + '\"]');
						
						//if the field is not empty (the field is allowed to be empty, unless the _required function is used
						if(fieldElement.value != '')
						{
							//if the url is not valid, add it to the list of fields to alert
							if(!validURL(fieldElement.value))
							{
								// add the value of the required field to the alert
								strAlert = strAlert + theForm.elements[i].value + '\n';	
							}
						}
					}
					//else if the field should contain a valid email address
					else if(theForm.elements[i].name.indexOf('_validEmail') > 0)
					{
						// field name minus '_validEmail'
						var fieldName = theForm.elements[i].name.split('_validEmail')[0];
						var fieldElement = eval('document.forms[\"' + theForm.name + '\"].elements[\"' + fieldName + '\"]');
						
						//if the field is not empty (the field is allowed to be empty, unless the _required function is used
						if(fieldElement.value != '')
						{
							//if the Email is not valid, add it to the list of fields to alert
							if(!validEmail(fieldElement.value))
							{
								// add the value of the required field to the alert
								strAlert = strAlert + theForm.elements[i].value + '\n';	
							}
						}
					}
					
					// if the strAlert is not equal to strControl and focusField has not yet been set to anything.				
					if(strAlert != strControl && focusField == 'unfocused')
					{
						focusField = fieldElement;
					}
				}				
			}		
			
			// if any required fields arent checked by the above include, include code to do it here.
		
			// use function postFormCheck() to do any extra checks after general form checks
			// function should return a boolean which when false voids the form submitting. 
			// Function must produce its own error messages		
			
			if(window.postFormCheck != null)
			{
				externalCheck = postFormCheck(theForm);
			}	
			
			
			if (externalCheck)
			{						
				// if the strings are equal, all good, submit the form		
				if(strAlert == strControl)
				{
					return true;
				}
				else
				{					
					// tell the user whats wrong
					alert(strAlert);
					if(focusField.focus)
					{
						focusField.focus();
					}
					return false;					
				}
			}
			else
			{
				// from postform check
				return false;
			}

		}
		else
		{
			// from preform check
			return false;
		}
	}	
	
	
	//this function returns true or false based on whether the date passed to it is in a valid format
function checkValidDate(theDate)
{
	var delimiter
	//create an array containing all the months
	var monthArr = new Array('january','february','march','april','may','june','july','august','september','october','november','december')
	//create an array containing the months with 30 days as numbers
	var int30Arr = new Array(9,4,6,11)
	var proceed = true
	//firstly, find the date's delimiter
	//if a space is found in the date
	if(theDate.indexOf(' ') > -1)
	{
		//set the delimiter to ' '
		delimiter = ' '
	}
	//else if a - is found
	else if(theDate.indexOf('-') > -1)
	{
		//set the delimiter to '-'
		delimiter = '-'
	}
	//else if a / is found
	else if(theDate.indexOf('/') > -1)
	{
		//set the delimiter to '/'
		delimiter = '/'
	}
	else
	{
		proceed = false
	}
	//if a delimiter was found
	if(proceed == true)
	{
		//now i will split the field into the various sections. day, month, year.
		var dateArr = theDate.split(delimiter)
		//if the date has the correct number of attributes
		if(dateArr.length == 3)
		{
			var yearOK = false
			var monthOK = false
			var dayOK = false
			//create variables for each attribute
			var theDay = dateArr[0]
			var theMonth = dateArr[1]
			var theYear = dateArr[2]
			//i will check the attributes from year to day because the day validation will depend on the year and month.
			//make sure the year is a number.
			if(isNaN(theYear) == false)
			{
				if(theYear > 999)
				{
					yearOK = true
				}
			}
			//if the year is ok, move onto the month
			if(yearOK == true)
			{
				//if the month is a number, make sure it is less than or equal to 12
				//if the month is a number
				if(isNaN(theMonth) == false)
				{
					if(theMonth <= 12 && theMonth > 0)
					{
						//the month is valid so we will set the ok flag to true
						monthOK = true
						var monthAsInt = theMonth
					}
				}
				//else if the month is a string
				else
				{
					//loop over each item in the month array
					for(i=0;i<monthArr.length;i++)
					{
						//check if the month = the current element or the first 3 chars of the element
						if(theMonth.toLowerCase() == monthArr[i].toLowerCase() || theMonth.toLowerCase() == monthArr[i].substring(0,3).toLowerCase())
						{
							//the month is valid so we will set the ok flag to true
							monthOK = true
							//create a var of the month as an integer
							var monthAsInt = i + 1
							//break out of the loop
							break
						}
					}
				}
				//if the month is ok, continue to the day
				if(monthOK == true)
				{
					/*The day part of the validation is going to be a bit more difficult than the other validation
					because I need to check that it is not more than the month allows (ie, 30 days for sept
					,april,jun,nov and 28 and 29 based on whether it is a leap year)*/
					
					//firstly, make sure the day is a number
					if(isNaN(theDay) == false)
					{
						var is30 = false
						//loop over the 30 day month array
						for(i=0;i<int30Arr.length;i++)
						{
							//if the month is in the 30 list
							if(monthAsInt == int30Arr[i])
							{
								//set the is30 flag to true
								is30 = true
								//break out of the loop
								break
							}
						}
						//if the month is a 30 day month
						if(is30 == true)
						{
							//make sure the day is lte 30
							if(theDay <= 30 && theDay > 0)
							{
								dayOK = true
							}
						}
						//else if the month is feb
						else if (monthAsInt == 2)
						{
							//check to see if the year is a leap year and the day is 29 or less or the year is not a leap year and the day is 28 or less.
							if((checkYear(theYear) && theDay < 30 && theDay > 0) || (!checkYear(theYear) && theDay > 0 && theDay < 29))
							{
								dayOK = true
							}
						}
						//else if the day is 31 or less
						else if(theDay < 32 && theDay > 0)
						{
							dayOK = true
						}
						//if the day is valid
						if(dayOK == false)
						{
							return false								
						}
						else
						{
							return true;
						}
					}
					//else if the day is not a number
					else
					{
						//return false
						return false
					}
				}
				//else if the month is not valid, return false
				else
				{
					return false
				}
			}
			//else if the year is no good, return false
			else
			{
				return false
			}
		}
		//else if the date does not have the correct number of attributes, return false.
		else
		{
			return false
		}	
	}
	//else if a delimiter was not found, return false
	else
	{
		return false
	}
}

//this function checks if a year is a leap year
function checkYear(theYear) 
{ 
	return (((theYear % 4 == 0) && (theYear % 100 != 0)) || (theYear % 400 == 0)) ? 1 : 0;
}
	
	
//this function returns true or false depending on whether a url is valid.
//The criteria required is http://*.*.*
function validURL(theURL)
{
	//if the url matches our criteria
	if(theURL.match(/http:\/\/[^.]+\.[^.]+\.[^;]+/i))
	{
		//return true
		return true
	}
	else//else if the url is invalid
	{
		//return false
		return false
	}
}

//returns true or false based on whether the email address is valid.
//critia: [alphaNumeric,-,~] + [@] + [alphaNumeric,-,~] + [.] + [alphaNumeric,-,~]
function validEmail(theEmail)
{
	//if the email address matches our criteria
	if(theEmail.match(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/))
	{
		//return true
		return true
	}
	else//else if the email address is invalid
	{
		//return false
		return false
	}
}

//limits the length of the textarea to the numbers of characters passed
// pass formfeild object
// pass charLimit
function limitTextArea (objField, charLimit)
{
	if(objField.value.length > charLimit)
	{
		alert('The text area is too long. Please review the text')
		objField.focus()
	}
}
	
function checkSearchCriteria( searchCriteria )
{
	if(searchCriteria.substring(0,4) == 'and ' || searchCriteria.substring(0,3) == 'or '  || searchCriteria == 'and' || searchCriteria == 'or')
	{
		alert("You can not start a query with \"and\" or \"or\"") 
		return false
	}
	else if(searchCriteria.split(" ").length > 8)
	{
		alert("please simplify your query") 
		return false
	}
	
	return true
}

/*
This function will stop a user from entering a value that, when encoded, will exceed
the maxlength of the form field.
*/
function restrictLength(theField,fieldTitle,maxLength) {
	var illegalCharList = new Array();
	var encodedValue = "";
	var newValue = "";
	var encodedChar = "";
	var illegalChar = false;
	var lengthExceeded = false;
	var fieldValue = theField.value;
	
	// start by truncating the value to the maxLength
	if(fieldValue.length > maxLength) {
		fieldValue = fieldValue.substring(0,maxLength);
		lengthExceeded = true;
	}
	
	illegalCharList[0] = "&";
	illegalCharList[1] = "<";
	illegalCharList[2] = ">";
	
	//encode each character and append to string until maxlength reached
	for(i=0; i<fieldValue.length; i++) {
		//check if the char is in the illegal char list
		illegalChar = false;
		for(j=0; j<illegalCharList.length; j++) {
			if(fieldValue.charAt(i) == illegalCharList[j]) {
				illegalChar = true;
			}
		}
		if(illegalChar) {
			encodedChar = escape(fieldValue.charAt(i)).replace("%", "&#") + ";";
		}
		else {
			encodedChar = fieldValue.charAt(i);
		}
		if((encodedValue + encodedChar).length <= maxLength) {
			encodedValue = encodedValue + encodedChar;
			newValue = newValue + fieldValue.charAt(i);
		}
		else {
			lengthExceeded = true;
		}
	}
	if(lengthExceeded) {
		alert('Your entry for ' + fieldTitle + ' is longer than the maximum allowed length (' + maxLength + ') and will be truncated.');
		theField.value = newValue;
		theField.focus();
	}
}

//returns true if path is valid
function validFile(fileName) {
	if(!fileName.match(/^[a-z]:\\([^\\]+\\)*[^\.]+\.([a-z]|[0-9])+$/i)) {
		return false;
	} else {
		return true;
	}
}
