var isIE3 = (navigator.appVersion.indexOf('MSIE 3') != -1);

/***************************************************************
** define and instantiate validation objects
** the validation object accepts the following parameters:
**
** ResponseText: name used in the alerts (same as label on the page)
**
** ObjectName: this must be the name of the corresponding
** HTML form element; make it the same as the object name
**
** ValidationType: element type (we have to create this since IE3
** doesn't support the type property for for elements)
** text
** textarea
** checkbox
** radio
** select
**
** ValidationString: function call that's evaluated during validation check
** isText(str)
** isSelect(formObj)
** isRadio(formObj)
** isImage(formObj)
** isCheck(formObj)
** isCheckConfirm(formObj)
** isEmail(str)
** isDate(str)
** isSame(str,"passwordb")
** isTextNumber(str) 
** isFileName(str)
** isDateDiff(str,"eval_dateTo")
** IsNumeric(str)
** IsFloat(str)
** IsNotZero(str)
**
** Format: text representation of required Format;
** pass 'null' if no required Format;
** used in alert as an aid to user
**
**  
** create a new object for each form element you need to validate
** 

HERE IT IS! - Examples...
===============================================================================================
var valText = new validation('last name', 'lastName', 'text', 'isText(str)', null);
var valSelect = new validation('astrological sign', 'zodiac', 'select', 'isSelect(formObj)', null);
var valRadio = new validation('favorite ice cream flavor', 'iceCream', 'radio', 'isRadio(formObj)', null);
var valImage = new validation('myimage.jpg', 'iceCream', 'image', 'isImage(formObj)', null);
var valCheck = new validation('reason for reading this', 'reason', 'checkbox', 'isCheck(formObj)', null);
var valCheckConfirm = new validation('reason for reading this', 'reason', 'checkboxconfirm', 'isCheck(formObj)', null);
var valEmail = new validation('email address', 'email', 'text', 'isEmail(str)', null);
var validEmail = new validation('valid email address', 'email', 'text', 'isIfEmail(str)', null);
var valDate = new validation('date', 'date', 'text', 'isDate(str)', 'dd/mm/yyyy');
var valSame = new validation ('(confirmed) password', 'passwordb', 'match', 'isSame(str,"passworda")', null);
***NOTE: When using isSame make sure that the original (i.e. passworda) is referenced by ID in the code 
var valNumeric = new validation('maximum capacity', 'capacity', 'text', 'isNumeric(str)', null);
var varTextNumber = new validation('average quantity', 'places', 'text', 'isTextNumber(str)', null);
var varFloat = new validation('cash back', 'cashback', 'text', 'isFloat(str)', null);
var varNumber = new validation('number of attendees', 'attendees', 'text', 'isNotZero(str)', null);
var varLonger = new validation ('username', 'username', 'longer', 'isAtLeast(str,6)', null);
var varShorter = new validation ('username', 'username', 'shorter', 'isAtMost(str,4)', null);
var varLength = new validation ('username', 'username', 'length', 'isLength(str,6)', null);
var varFilename = new validation ('because it contains an illegal character such as an &. Please rename your file and try again.', 'FILE1', 'text', 'isFileName(str)', null);
var valDateDiff = new validation('To date occurs after the From date', 'fromdate', 'datecheck', 'isDateDiff(str,"todate")', null);
***NOTE: When using isDateDiff make sure that the to date (i.e. todate) is referenced by ID in the code 
===============================================================================================

***************************************************************
** Define the elts array:
** Add a new item to the array for each object you create above
** Make sure the value of the array element is the same as
** the name of the object, and that the array elements are listed
** in the same order the corresponding objects appear in the form
** (it's more clear to the user that way)
** Example...

var elts = new Array(lastName,email,date,zodiac,iceCream,reason);

***************************************************************/
// object definition
function validation(ResponseText, ObjectName, ValidationType, ValidationString, Format) {
  this.ResponseText = ResponseText;
  this.ObjectName = ObjectName;
  this.ValidationType = ValidationType;
  this.ValidationString = ValidationString;
  this.Format = Format;
}

/************************************************** *************
** The main function keeps track of which fields the user missed
** or filled in incorrectly, and alerts the user so they can go
** back and fix what's wrong.
** Set allAtOnce to true if you want this "validation help" to
** alert the user to all mistakes at once; set it to false if
** you want it to show one mistake at a time
************************************************** *************/
var allAtOnce = true;

var beginRequestAlertForText = "Please include ";
var beginRequestAlertGeneric = "Please choose ";
var beginRequestAlertConfirm = "Please confirm ";
var endRequestAlert = ".";
var beginInvalidAlert = " is an invalid ";
var endInvalidAlert = "!";
var beginFormatAlert = "  Use this format: ";
var beginInvalidSelect = "Nothing has been selected from the list of ";
var endInvalidSelect = " options.";
var beginLength = "Please ensure that "
var endIsAtLeast = " is at least "
var endIsNoMoreThan = " is no more than "
var endIsLength = " is equal to "
var beginMatchString = "The " 
var endMatchString = " does not match" 

/***************************************************************
** these functions validate the string or form object passed in,
** and return true or false based on whether the test succeeds or fails
**
** validate existence of input (formObj)
** validate text in text input or textarea matches pattern (str)
***************************************************************/
// isText(str): verifies text input or textarea is not empty
function isText(str) {
	return (str != "");
}

function validateText(evt) {
	evt = (evt) ? evt : window.event
		 var charCode = (evt.which) ? evt.which : evt.keyCode
		if (charCode > 31 && (charCode < 48 || charCode > 57) && (charCode < 65 || charCode > 90) && (charCode < 97 || charCode > 122)) 
				{
			   alert('This field accepts a-z and numbers only.')
			   status = "This field accepts a-z and numbers only."
					return false
			   }
		  status = ""
return true
}

// isSelect(formObj): verifies item from a select menu is chosen
function isSelect(formObj) {
	if (formObj)
	{
		if (formObj.multiple)
		{
			return (formObj.selectedIndex != -1);
		} else {
			return (formObj.selectedIndex != 0);
		}
	}
	return false;
}

// isRadio(formObj): verifies one of a group of radio buttons is chosen
function isRadio(formObj) {
	for (j=0; j<formObj.length; j++) {
		if (formObj[j].checked) {
			return true;
		}
	}
	return false;
}

// isDateDiff is used to make sure that the first date is not after the second date
function isDateDiff(str, strdateto) {
	var datefrom = str;
	var dateto = document.getElementById(strdateto).value;
//	alert(Date.parse(datefrom));
//	alert(Date.parse(dateto));
	if (dateto == "")
	{
		return true;
	} else {
		if (Date.parse(datefrom) <= Date.parse(dateto)) {
			return true;
		}	else {
			if (datefrom.value == "" || dateto.value == "") 
				return false;
			else 
				return false;
		}
		return false;
	}
}

// isImage(formObj): verifies an image is chosen - i.e. for when uploading a file that must be an image
function isImage(str) {
var str2 = str.toUpperCase();
  return ((str2 != "") && 
	(
	  ((str2.indexOf("JPG") != -1) && (str2.indexOf(".") != -1) | (str2.indexOf("GIF") != -1) && (str2.indexOf(".") != -1))));
}

// isCheck(formObj, form, [begin], [num]): verifies at least one
//  of a group of checkboxes is checked
//  for [begin], fill in the index number in the elements array
//  of the first checkbox (remember to start counting from zero)
//  for [num], fill in the number of checkboxes in the group
function isCheck(formObj) {
	if (formObj.length)
	{
		for (j = 0; j < formObj.length; j++) {
			if (formObj[j].checked) {
				return true;
			}
		}
	}	
	else 
	{
		if (formObj.checked) {
			return true;
		}
	}
	return false;
}

function isTextNumber(str) {
  return (!isNaN(parseFloat(str)) && parseFloat(str) != 0);
}

function isFloat(str) {
  return (!isNaN(parseFloat(str)));
}

function isFileName(str) {
	//filenames must not contain certain characters
  return ((str.indexOf("&") == -1));
}

function isNumeric(str)
{
  if (str)
	{
		 if (str != parseInt(str))
		{
					 return false;
		 }
	}
	 return true;
}

function isEmail(str) {
	//Force entry of an email address (i.e. email address is mandatory)
	var at="@"
	var dot="."
	var lat=str.indexOf(at)
	var lstr=str.length
	var ldot=str.indexOf(dot)
	if (str.indexOf(at)==-1){
		 return false
	}
	if (str.indexOf(at)==-1 || str.indexOf(at)==0 || str.indexOf(at)==lstr){
		 return false
	}
	if (str.indexOf(dot)==-1 || str.indexOf(dot)==0 || str.indexOf(dot)==lstr){
			return false
	}
	if (str.indexOf(at,(lat+1))!=-1){
			return false
	}
	if (str.substring(lat-1,lat)==dot || str.substring(lat+1,lat+2)==dot){
			return false
	}
	if (str.indexOf(dot,(lat+2))==-1){
			return false
	}
	if (str.indexOf(" ")!=-1){
			return false
	}
	return true					
}

function isIfEmail(str) {
	//Only check the email if there is one (i.e. email address not mandatory)
	if (str)
	{
		var at="@"
		var dot="."
		var lat=str.indexOf(at)
		var lstr=str.length
		var ldot=str.indexOf(dot)
		if (str.indexOf(at)==-1){
			 return false
		}
		if (str.indexOf(at)==-1 || str.indexOf(at)==0 || str.indexOf(at)==lstr){
			 return false
		}
		if (str.indexOf(dot)==-1 || str.indexOf(dot)==0 || str.indexOf(dot)==lstr){
				return false
		}
		if (str.indexOf(at,(lat+1))!=-1){
				return false
		}
		if (str.substring(lat-1,lat)==dot || str.substring(lat+1,lat+2)==dot){
				return false
		}
		if (str.indexOf(dot,(lat+2))==-1){
				return false
		}
		if (str.indexOf(" ")!=-1){
				return false
		}
	}
	return true					
}

// isDate(str): verifies date of form dd/mm/yyyy
function isDate(str) {
	if (str.length != 10) { return false }

	for (j=0; j<str.length; j++) {
		if ((j == 2) || (j == 5)) {
			if (str.charAt(j) != "/") { return false }
		} else {
			if ((str.charAt(j) < "0") || (str.charAt(j) > "9")) { return false }
		}
	}	
	var day = str.charAt(0) == "0" ? parseInt(str.substring(1,2)) : parseInt(str.substring(0,2));
	var month = str.charAt(3) == "0" ? parseInt(str.substring(4,5)) : parseInt(str.substring(3,5));
	var begin = str.charAt(6) == "0" ? (str.charAt(7) == "0" ? (str.charAt(8) == "0" ? 9 : 8) : 7) : 6;
	var year = parseInt(str.substring(begin, 10));

	if (day == 0) { return false }
	if (month == 0 || month > 12) { return false }
	if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
	if (day > 31) { return false }
	} else {
		if (month == 4 || month == 6 || month == 9 || month == 11) {
			if (day > 30) { return false }
		} else {
			if (year%4 != 0) {
				if (day > 28) { return false }
			} else {
				if (day > 29) { return false }
			}
		}
	}
	return true;
}

function isValidFullDate(strDate) {
	var dateStr=document.getElementById(strDate).value;
	// Checks for the following valid date Formats:
	// DD/MM/YY   DD/MM/YYYY   DD-MM-YY   DD-MM-YYYY
	// Also separates date into month, day, and year variables

	var datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{2}|\d{4})$/;

	// To require a 4 digit year entry, use this line instead:
	// var datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{4})$/;

	var matchArray = dateStr.match(datePat); // is the Format ok?
	if (matchArray == null) {
		return false;
	}
	month = matchArray[3]; // parse date into variables
	day = matchArray[1];
	year = matchArray[4];
	if (month < 1 || month > 12) { // check month range
		return false;
	}
	if (day < 1 || day > 31) {
		return false;
	}
	if ((month==4 || month==6 || month==9 || month==11) && day==31) {
		alert("Month "+month+" doesn't have 31 days!")
		return false
	}
	if (month == 2) { // check for february 29th
		var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
		if (day>29 || (day==29 && !isleap)) {
			return false;
	   }
	}
	return true;  // date is valid
}

function isValidDate(DayValfield,MonthValfield,YearValfield)
{
	var DayVal = document.getElementById(DayValfield).value;
	var MonthVal = document.getElementById(MonthValfield).value;
	var YearVal = document.getElementById(YearValfield).value;
	var DaysInMonth = 31;
	var Remainder = 0;
	if (MonthVal==4 || MonthVal==6 || MonthVal==9 || MonthVal==11)
	{
	DaysInMonth = 30;
	}
	if (MonthVal==2)
	{
			Remainder = Mod(YearVal,4);
			if (Remainder==0)
			{
				DaysInMonth = 29;
			}
			else
		{
			DaysInMonth = 28;
		}
	}
	return (DayVal <= DaysInMonth);
}

//Superceded by isSelect
function isSelected(str) {
  return (str != "0") && (str != " ");
}

//Checks that two strings are the same (make sure str2 is referenced by ID)
function isSame(str,str2) {
	var val2 = document.getElementById(str2).value;
  return  val2 == str;
}

//Checks the length of a string must be at least nn characters
function isAtLeast(str,strlength) {
	if (str.length != '0')
	{
		return str.length >= strlength
	}
	return true;
}

//Checks the length of a string must be no more than nn characters
function isAtMost(str,strlength) {
	if (str.length != '0')
	{
		return str.length <= strlength
	}
	return true;
}

//Checks the length of a string must be nn characters
function isLength(str,strlength) {
	if (str.length != '0')
	{
		return str.length == strlength
	}
	return true;
}

function isNotZero(str)
{
	if (str)
	{
		if (str == '0')
		{
		return false;
		}
	}
	return true;
}

function Mod(a, b) { return a-Math.floor(a/b)*b } 

/***************************************************************
** The validateForm() function validates the form elements
** previously defined as validation objects and as members of
** the elts array. We loop through the elts array, testing each
** element in turn, and alerting the user when they've missed
** a required field
***************************************************************/

function validateForm(form) {
	var ObjectName = "";
	var formObj = "";
	var str = "";
	var ResponseText = "";
	var alertText = "";
	var firstMissingElt = null;
	var hardReturn = "\r\n";

	for (i=0; i<elts.length; i++) {
		ObjectName = elts[i].ObjectName;
		//alert(elts[i].length);
		//alert(ObjectName);
		formObj = eval("form." + ObjectName);
		ResponseText = elts[i].ResponseText;
		if (elts[i].ValidationType == "text") {
			//do text type validation
			str = formObj.value;
			// remove leading and trailing spaces
			str = str.replace(/^([\s\t\n]|\&nbsp\;)+|([\s\t\n]|\&nbsp\;)+$/g, '');

			if (eval(elts[i].ValidationString)) continue;
			
			if (str == "") {
				if (allAtOnce) {
					alertText += beginRequestAlertForText + ResponseText + endRequestAlert + hardReturn;
					if (firstMissingElt == null) {firstMissingElt = formObj};
				} else {
					alertText = beginRequestAlertForText + ResponseText + endRequestAlert + hardReturn;
					alert(alertText);
				}
			} else {
				if (allAtOnce) {
					alertText += str + beginInvalidAlert + ResponseText + endInvalidAlert + hardReturn;
				} else {
					alertText = str + beginInvalidAlert + ResponseText + endInvalidAlert + hardReturn;
				}
				if (elts[i].Format != null) {
					alertText += beginFormatAlert + elts[i].Format + hardReturn;
				}
				if (allAtOnce) {
					if (firstMissingElt == null) {firstMissingElt = formObj};
				} else {
					alert(alertText);
				}
			}
		} else {
			if (elts[i].ValidationType == "longer" || elts[i].ValidationType == "shorter" || elts[i].ValidationType == "length")
			{	
				str = formObj.value;
				//length check validation
				if (eval(elts[i].ValidationString)) continue;
				//pick out the length that has been passed for validation
				var startofLength = elts[i].ValidationString.indexOf(',')
				var lengthoflength = elts[i].ValidationString.indexOf(')',elts[i].ValidationString.indexOf(','))
				var lengthofstring = elts[i].ValidationString.substring(startofLength + 1,lengthoflength)
				if (lengthofstring==1)
				{
					var txtchar = " character"
				} else {
					var txtchar = " characters"
				}
				if (elts[i].ValidationType == "longer")
				{
					if (allAtOnce) {
						alertText += beginLength + ResponseText + endIsAtLeast + lengthofstring + txtchar + hardReturn;
						if (firstMissingElt == null) {firstMissingElt = formObj};
					} else {
						alertText = beginLength + ResponseText + endIsAtLeast + lengthofstring + txtchar + hardReturn;
					alert(alertText);
					}
				} else {
					if (elts[i].ValidationType == "length")
					{
						if (allAtOnce) {
							alertText += beginLength + ResponseText + endIsLength + lengthofstring + txtchar + hardReturn;
							if (firstMissingElt == null) {firstMissingElt = formObj};
						} else {
							alertText = beginLength + ResponseText + endIsLength + lengthofstring + txtchar + hardReturn;
						alert(alertText);
						}
					}
					else
					{
						if (allAtOnce) {
							alertText += beginLength + ResponseText + endIsNoMoreThan + lengthofstring + txtchar + hardReturn;
							if (firstMissingElt == null) {firstMissingElt = formObj};
						} else {
							alertText = beginLength + ResponseText + endIsNoMoreThan + lengthofstring + txtchar + hardReturn;
						alert(alertText);
						}
					}
				} 
			} else {
				if (elts[i].ValidationType == "datecheck")
				{
					str = formObj.value;
					if (eval(elts[i].ValidationString)) continue;
					if (allAtOnce) {
						alertText += beginLength + ResponseText + hardReturn;
						if (firstMissingElt == null) {firstMissingElt = formObj};
					} else {
						alertText = beginLength + ResponseText + hardReturn;
					alert(alertText);
					}
				} else {
					if (elts[i].ValidationType == "match")
					{
						str = formObj.value;
						if (eval(elts[i].ValidationString)) continue;
						if (allAtOnce) {
							alertText += beginMatchString + ResponseText + endMatchString + hardReturn;
							if (firstMissingElt == null) {firstMissingElt = formObj};
						} else {
							alertText += beginMatchString + ResponseText + endMatchString + hardReturn;
						alert(alertText);
						}
					} else {
						if (elts[i].ValidationType == "checkboxconfirm")
						{
							if (eval(elts[i].ValidationString)) continue;
							if (allAtOnce) {
								alertText += beginRequestAlertConfirm + ResponseText + endRequestAlert + hardReturn;
								if (firstMissingElt == null) {firstMissingElt = formObj};
							} else {
								alertText = beginRequestAlertConfirm + ResponseText + endRequestAlert + hardReturn;
							alert(alertText);
							}
						} else {
						//do other type validation
							if (eval(elts[i].ValidationString)) continue;
							if (allAtOnce) {
								alertText += beginRequestAlertGeneric + ResponseText + endRequestAlert + hardReturn;
								if (firstMissingElt == null) {firstMissingElt = formObj};
							} else {
								alertText = beginRequestAlertGeneric + ResponseText + endRequestAlert + hardReturn;
							alert(alertText);
							}
						}
					} 
				}
			}
		}
		if (!isIE3) {
			var goToObj = (allAtOnce) ? firstMissingElt : formObj;
			if (goToObj)
			{
				if (goToObj.select) goToObj.select();
				if (goToObj.focus) {
						try
						{
							goToObj.focus();
						}
						catch (e)
						{
							// alert("can't focus because of\n\n" + e) 
						}
				}
			}
		}
			if (!allAtOnce) {return false};
	}
	if (allAtOnce) {
		if (alertText != "") {
			alert(alertText);
			return false;
		}
	}
	return true; 
}

function ChangeDate(strDate) {
	var mm = strDate.substring(3,5);
	var dd = strDate.substring(0,2);
	var yyyy = strDate.substring(6,10);

	var mmddyyyy = mm + '/' + dd + '/' + yyyy;

	return mmddyyyy;
}

/**
 * If the element is a checkbox and it is checked then hide 
 * all elements referenced by the id mandatoryField. 
 * If it is not checked then show them
 */
function changeMandatoryFields( element, mandatoryFieldName ) {
	if( element.checked ) {
		hideAllElements( mandatoryFieldName );
	} else {
		showAllElements( mandatoryFieldName );
	}	
}

/**
 * Loop through a list of elements and apply 
 * a function to hide the element
 */
function hideAllElements( name ) {
		var elementList = document.getElementsByName( name )
		count = elementList.length;
		for( i = 0; i < count; i++ ) {
			hideElement( elementList[ i ].id );
		}
}

/**
 * Loop through a list of elements and apply 
 * a function to show the element
 */
function showAllElements( name ) {
		var elementList = document.getElementsByName( name)
		count = elementList.length;
		for( i = 0; i < count; i++ ) {
			showElement( elementList[ i ].id );
		}
}

/**
 * hide an element in the dom 
 */
function hideElement(id) {
	//safe function to hide an element with a specified id
	if (document.getElementById) { // DOM3 = IE5, NS6
		document.getElementById(id).style.display = 'none';
	}
	else {
		if (document.layers) { // Netscape 4
			document.id.display = 'none';
		}
		else { // IE 4
			document.all.id.style.display = 'none';
		}
	}
}

/**
 * Show an element in the dom 
 */
function showElement(id) {
	//safe function to show an element with a specified id
		  
	if (document.getElementById) { // DOM3 = IE5, NS6
		document.getElementById(id).style.display = 'inline';
	}
	else {
		if (document.layers) { // Netscape 4
			document.id.display = 'inline';
		}
		else { // IE 4
			document.all.id.style.display = 'inline';
		}
	}
}

function removeEltsElement(elementToRemove) {
	// 0,1,2,3 - index
	// e.g. removeEltsElement(elementName);

	var ree = elts.indexOf(elementToRemove);

	if (ree != -1)
	{
		elts.splice(ree, 1);
	}
}

function addEltsElement(elementBefore,elementToAdd) {
	// 0,1,2,3 - index
	// e.g. addEltsElement(elementBefore,elementToAdd);
	// check to see if element already exists - only continue if it doesn't exist. (i.e. result is -1)
	var see = elts.indexOf(elementToAdd);
	if (see == -1)
	{
		var ree = elts.indexOf(elementBefore);
		if (ree != -1)
		{
			elts.splice(ree+1, 0,elementToAdd);
		}
		else
		{
			elts.push(elementToAdd);
		}
	}
}

function removeEltsElementJQuery(elementToRemove) {
	// 0,1,2,3 - index
	// e.g. removeEltsElement(elementName);
	var ree = $.inArray(elementToRemove, elts);

	if (ree != -1)
	{
		elts.splice(ree, 1);
	}
}

function addEltsElementJQuery(elementBefore,elementToAdd) {
	// 0,1,2,3 - index
	// e.g. addEltsElement(elementBefore,elementToAdd);
	// check to see if element already exists - only continue if it doesn't exist. (i.e. result is -1)
	var see = $.inArray(elementToAdd, elts);
	if (see == -1)
	{
		var ree = $.inArray(elementBefore, elts);
		if (ree != -1)
		{
			elts.splice(ree+1, 0,elementToAdd);
		}
		else
		{
			elts.push(elementToAdd);
		}
	}
}

function UnhideStar(fieldid) {
	if (document.getElementById('star'+fieldid))
	{
		document.getElementById('star'+fieldid).style.display = '';
	}
}

function HideStar(fieldid) {
	if(document.getElementById('star'+fieldid))
	{
		document.getElementById('star'+fieldid).style.display = 'none';
	}
}
function clearArray(thisarray) {

    thisarray.length = 0;

    return thisarray;

  }
