// ##LOG: 
// -----------------------------------------------------------------------------------------------
//	04/09/02	bkel			Altered '_validEmail' regular expression to make it exclude caharacters
//											that can't be used in email addessess.
//	06/08/02	bkel			Added functionality for forcing a field to be numeric '_isNumeric' 
//	07/02/02	Leedrick 		Added functionality for '_validURL', '_validDate' and made '_validEmail'
//											use regular expressions.
//	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 '_validEmail'.
//	05/10/01	ben				Created.
// -----------------------------------------------------------------------------------------------


// Suffixes used in checkForm_insert.js
// '_isNumeric'		used to check if chosen field contains a numerical number
// '_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.


// additional functions within checkForm_insert.js
// 'restrictLength'				Restricts form field to a defined length.
// 'checkSearchCriteria'	Restricks Search Criteria.



// check / submit the form
	function checkForm(theForm)
	{
		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;
		
		// 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++)
			{					
				// We must restict our checks to field elements that have a name.
				if ( theForm.elements[i].name )
				{
				
					//  '_isNumeric'
					// check if any fields need to contain a numerical value
					if(theForm.elements[i].name.indexOf('_isNumeric') > 0)
					{
					
						fieldValid = false;
						
						// field name minus '_isNumeric'
						var fieldName = theForm.elements[i].name.split('_isNumeric')[0];
						var fieldElement = eval( 'theForm.' + fieldName );
						if((fieldElement.value * 0) == 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( 'theForm.' + 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 (fieldType == null)
						{
							var fieldType = fieldElement[0].type;
						}
							
						
						// if the field is a straight text input
						if(fieldType == 'text' || fieldType == 'textarea' || fieldType == 'password' || fieldType == 'hidden' || fieldType == 'file')
						{
							// check to see if a value has been entered
							if(fieldElement.value != '')
							{
								// if is has field is valid
								fieldValid = true;
							}
						}
						
						// if the field is a checkbox
						else if ( fieldType == 'checkbox' || fieldType == 'radio' )
						{							
							// We need to check for the existance of length attribute.
							// So we know if we need to treat field as an array or not.
							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;
									}
								}
							}
							// If there is only one checkbox or radio button
							// then the field will not be returned as an array.
							else if ( fieldElement.checked == true )
							{
								fieldValid = true;							
							}
						}
						
						// if the field is a select box of some type
						else if((fieldType == 'select-multiple' && fieldElement.selectedIndex != -1) || (fieldType == 'select-one' && fieldElement[fieldElement.selectedIndex].value != ''))
						{		
							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( 'theForm.' + 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 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( 'theForm.' + 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( 'theForm.' + 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.type != 'hidden' && focusField.style.visibility != 'hidden' )
					{
						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,4})+$/) )
	{
		//return true
		return true
	}
	else//else if the email address is invalid
	{
		//return false
		return false
	}
}
	

	
/* :: [restrictLength] ::
This function will stop a user from entering more than a specified number of characters into 
a text area. The function should be run in the onBlur event of the text area.
Args are:
theField: Text area field object
fieldTitle: Name you want displayed in the alert.
maxLength: the maximum length you want the text to reach.
*/
function restrictLength(theField,fieldTitle,maxLength) 
{
	//if the field value is too long
	if(theField.value.length > maxLength) 
	{
		//alert the user that the string will be truncated.
		alert('Your entry for ' + fieldTitle + ' is longer than the maximum allowed length (' + maxLength + ') and will be truncated.')
		theField.value = theField.value.substr(0,maxLength)
		theField.focus()
	}
}



/* :: [checkSearchCriteria] ::
This function will stop a user from entering searchCriteria with more than 8 words and does not allow searchCriteria to start with 'and ' or 'or '.
*/
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
}	


// confirm form reset
function conReset(theForm)
{
	if(confirm('Return the form to the last saved values?'))
	{
		theForm.reset();
	}
}
