
// GLOBAL VARIABLES ---------------------------------------------------------------------------------------

var divMain = null;
var divHide = null;
var strFocusOnClose = "";
var strOnLoadScript = "";		// holds Javascript to eval() in the WindowOnLoad() event
var blnMac = (navigator.userAgent.toLowerCase().indexOf("mac") != -1) ? true : false;
var blnNs4 = (document.layers) ? true : false;
var blnIe4 = (document.all && !document.getElementById) ? true : false;
var blnIe5 = (document.all && document.getElementById) ? true : false;
var blnNs6 = (!document.all && document.getElementById) ? true : false;
var blnOpera = (navigator.userAgent.toLowerCase().indexOf("opera") != -1) ? true : false;


// BROWSER DEPENDENCE CORE FUNCTIONS -----------------------------------------------------------------------
function ftnGetObjectString(strObjectId) {
/*Purpose	:	Used to return a string that represents the path to an object in the DOM
				    dependent on the browser being used.
	Effects	:	None
	Inputs	:	strObjectId - String - the id of an object
	Returns	:	String - the path to the object in the DOM
*/
	if(blnNs4) return "document." + strObjectId;
	if(blnIe4) return "document.all." + strObjectId;
	if(blnIe5 || blnNs6 || blnOpera){
		if (blnMac && blnIe5)
			return "document.all['" + strObjectId + "']";
		else
			return "document.getElementById('" + strObjectId + "')";
	}
}

function ftnGetObject(strObjectId) {
/*Purpose	:	Used to return an object in the DOM.
	Effects	:	None
	Inputs	:	strObjectId - String - the id of an object
	Returns	:	Object - the object in the DOM
*/
	var strEval = ftnGetObjectString(strObjectId);
	return eval(strEval);
}

// VALIDATION FUNCTIONS -----------------------------------------------------------------------------

function ftnCheckNumeric(varValue) {
/*Purpose	:	Checks that a value is numeric.
	Effects	:	None.
	Inputs	:	varValue - Variant - the value to check.
	Returns	:	Boolean - True if the value was numeric, False otherwise
	Comments:	None.
*/
	if(varValue.length > 0) {
		if(isNaN(varValue)) {
			return false;
		}
	}
	return true;
}

function ftnCheckDateRangeByMonth(strStartDate, strEndDate, intMonth)
{
/*Purpose  :  Checks that two dates specify a valid month range.
  Effects  :  None.
  Inputs   :  strDate - Date - the start of the date range.
              strEndDate - Date - the end of the date range.
              intMonth - Integer - Maximum duration in month.
  Returns  :  Boolean - True if the dates specify a valid range, False otherwise
  Comments :  None.
  */
    
  var dteStartDate = new Date(strStartDate.replace('-','/'));
  var dteEndDate = new Date(strEndDate.replace('-','/'));  
  var strExpiryDate = strStartDate;
  var dteExpiryDate = new Date(strExpiryDate.replace('-','/'));
  dteExpiryDate = dteExpiryDate.setMonth(dteExpiryDate.getMonth()+intMonth);

  if(dteStartDate > dteEndDate)     { alert(dteStartDate + ' > ' + dteEndDate); return false; }
  else if(dteEndDate > dteExpiryDate)    { alert(dteEndDate + ' > ' + dteExpiryDate); return false; }
  else { return true;}
}

function ftnCheckMandatory(strValue) {
/*Purpose	:	Checks that a value exists, after stripping off leading and trailing white space.
	 			    Also checks for a single period, commonly used in an attempt to fool validation 
	 			    on our sites.
	Effects	:	None.
	Inputs	:	strValue - String - the value to check.
	Returns	:	Boolean - True if the value contains more than white space, False otherwise
	Comments:	None.
*/	
	// Strip leading and trailing white space
	strValue = strValue.replace(/^\s*(\b.*\b|)\s*$/, "$1");

	if (strValue == '' || strValue == '.') {
		return false;
	}
	return true;
}

function ftnCheckPassword(strValue) {
/*Purpose	:	Checks that a value exists, after stripping off leading and trailing white space.
					  Also checks for a minimum length of 6 alphanumeric characters
	Effects	:	None.
	Inputs	:	strValue - String - the value to check.
	Returns	:	Boolean - True if the value contains more than white space, False otherwise
	Comments:	None.
*/	
	// Strip leading and trailing white space
	strValue = strValue.replace(/^\s*(\b.*\b|)\s*$/, "$1");

	if (strValue == '' || strValue == '.' || strValue.length < 6) {
		return false;
	}
	return true;
}

function ftnCheckDate(strDate) {
/*Purpose	:	Checks the validity of a date string.
	Effects	:	None.
	Inputs	:	strDate - String - the date string to check in the format yyyy-mm-dd.
	Returns	:	Boolean - true if the date was valid, false otherwise
	Comments:	None.
*/
	var blnError = 0;
	var intYear, blnLeapYear;
	var aiDaysInMonth = new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);

	if(strDate.length != 0) {
		if(strDate.length > 10){
			blnError = true;
		}
		else {
			if(strDate.substr(4,1) != "-" || strDate.substr(7,1) != "-") {
				blnError = true;
			} 
			else {
				if(!ftnCheckNumeric(strDate.substr(0,4)) || !ftnCheckNumeric(strDate.substr(5,2)) || !ftnCheckNumeric(strDate.substr(8,2))) {
					blnError = true;
				} 
				else {
					// all elements are numeric so check for leap year
					intYear = strDate.substr(0,4);
					blnLeapYear = ftnCheckLeapYear(intYear);
					if(blnLeapYear) {
						aiDaysInMonth[2] = 29;
					}
					// check month between 1 and 12
					if(parseInt(strDate.substr(5,2),10) < 1 || parseInt(strDate.substr(5,2),10) > 12) {
						blnError = true;
					} 
					else {
						// check days in month correct
						if(parseInt(strDate.substr(8,2),10) < 1 || strDate.substr(8,2) > aiDaysInMonth[parseInt(strDate.substr(5,2),10)]) {
							blnError = true;
						}
					}
				}
			}
		}
		return(!blnError);
	}
}

function ftnCheckDateBetween(dteDateToCheck, dteStartDate, dteEndDate) {
/*Purpose	:	Checks that a date falls in a date range.
	Effects	:	None.
	Inputs	:	dteDateToCheck - Date - the date string to check.
				    dteStartDate - Date - the start of the date range.
				    dteEndDate - Date - the end of the date range.
	Returns	:	Boolean - True if the date falls in the range, False otherwise
	Comments:	Use ftnStringToDate() to convert an ISO formatted date string into a Date object.
*/
	// check valid dates has been given
	if(isNaN(Date.parse(dteDateToCheck))) { alert("ftnCheckDateBetween() - dteDateToCheck parameter is invalid."); return false; }
	if(isNaN(Date.parse(dteStartDate))) { alert("ftnCheckDateBetween() - dteStartDate parameter is invalid."); return false; }
	if(isNaN(Date.parse(dteEndDate))) { alert("ftnCheckDateBetween() - dteEndDate parameter is invalid."); return false; }
	
	// check date range is valid
	if(!ftnCheckDateRange(dteStartDate, dteEndDate)) { alert("ftnCheckDateBetween() - The specified date range is invalid."); return false; }
	
	// check date is in the range
	if(dteDateToCheck >= dteStartDate && dteDateToCheck <= dteEndDate) {
		return true;
	} else {
		return false;
	}
}

function ftnCheckDateRange(dteStartDate, dteEndDate) {
/*Purpose	:	Checks that two dates specify a valid date range.
	Effects	:	None.
	Inputs	:	strStartDate - Date - the start of the date range.
				strEndDate - Date - the end of the date range.
	Returns	:	Boolean - True if the dates specify a valid range, False otherwise
	Comments:	Use ftnStringToDate() to convert an ISO formatted date string into a Date object.
*/
	if(isNaN(Date.parse(dteStartDate))) { alert("ftnCheckDateRange() - dteStartDate parameter is invalid."); return false; }
	if(isNaN(Date.parse(dteEndDate))) { alert("ftnCheckDateRange() - dteEndDate parameter is invalid."); return false; }
	
	if(dteStartDate <= dteEndDate) {
		return true;
	} else {
		return false;
	}
}

function ftnCheckLeapYear(intYear)
{
/*Purpose	:	Determines if the year is a leap year.
	Effects	:	None.
	Inputs	:	intYear - Integer - the year to check
	Returns	:	Boolean - true if intYear is a leap year, false otherwise
	Comments:	None.
*/
	return (((intYear % 4 == 0) && (intYear % 100 != 0)) || (intYear % 400 == 0)) ? 1 : 0;
}

function ftnCheckEmailAddress(strEMail) {
/*Purpose	:	Checks to see if the string is a valid email address.
	Effects	:	None.
	Inputs	:	strEMail - String - the string to check.
	Returns	:	Boolean - true if the string was valid, false otherwise
	Comments:	None.
*/
	var strAt = "@";
	var strDot = ".";
	var intLastAt = strEMail.indexOf(strAt);
	var intLength = strEMail.length;
	
	if(strEMail.indexOf(strAt) == -1) {
		return false;
	}
	if(strEMail.indexOf(strAt) == -1 || strEMail.indexOf(strAt) == 0 || strEMail.indexOf(strAt) == intLength) {
		return false;
	}
	if(strEMail.indexOf(strDot) == -1 || strEMail.indexOf(strDot) == 0 || strEMail.indexOf(strDot) == intLength) {
		return false;
	}
	if(strEMail.indexOf(strAt,(intLastAt + 1)) != -1) {
		return false;
	}
	if(strEMail.substring(intLastAt - 1,intLastAt) == strDot || strEMail.substring(intLastAt + 1,intLastAt + 2) == strDot) {
		return false;
	}
	if(strEMail.indexOf(strDot,(intLastAt + 2)) == -1) {
		return false;
	}
	if(strEMail.indexOf(" ") != -1) {
		return false;
	}
 	return true;		
}

function ftnCheckOnlyReservedWords(strText) {
/*Purpose	:	Checks to see if the string only contains SQL Server Full-text reserved words.
	Effects	:	None.
	Inputs	:	strText - String - the string to check.
	Returns	:	Boolean - true if the string did contain only reserved words, false otherwise
	Comments:	None.
*/
	var arrFT_RESERVED_WORDS = new Array("about", "1", "after", "2", "all", "also", "3", "an", "4", "and", "5", "another", "6", "any", "7", "are", "8", "as", "9", "at", "0", "be", "$", "because", "been", "before", "being", "between", "both", "but", "by", "came", "can", "come", "could", "did", "do", "each", "for", "from", "get", "got", "has", "had", "he", "have", "her", "here", "him", "himself", "his", "how", "if", "in", "into", "is", "it", "like", "make", "many", "me", "might", "more", "most", "much", "must", "my", "never", "now", "of", "on", "only", "or", "other", "our", "out", "over", "said", "same", "see", "should", "since", "some", "still", "such", "take", "than", "that", "the", "their", "them", "then", "there", "these", "they", "this", "those", "through", "to", "too", "under", "up", "very", "was", "way", "we", "well", "were", "what", "where", "which", "while", "who", "with", "would", "you", "your", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z");
	var arrWords = strText.split(" ");
	var intWordsLoop, intReservedWordsLoop;
	var strWord;
	var blnResult = null;
	
	// loop around the words specified
	for(intWordsLoop = 0; intWordsLoop < arrWords.length; intWordsLoop++) {
		// if the word is not a reserved word
		if(blnResult == false) { break; }

		strWord = arrWords[intWordsLoop];
		blnResult = false;
		
		// loop through the reserved words to see if strWord is present
		for(intReservedWordsLoop = 0; intReservedWordsLoop < arrFT_RESERVED_WORDS.length; intReservedWordsLoop++) {
			if(arrFT_RESERVED_WORDS[intReservedWordsLoop] == strWord) {
				blnResult = true;
				break;
			}
		}
	}
	return blnResult;
}

function ftnCheckMoney(strText) {
/*Purpose	:	Checks to see if the string is a monetary value.
	Effects	:	None.
	Inputs	:	strText - String - the string to check.
	Returns	:	Boolean - true if the string if a monetary value, false otherwise
	Comments:	None.
*/
	if ((strText > 922337203685477.5807) || isNaN(strText) || (strText < 0.00)) {
		return false;
	} else {
		return true;
	}
}

function subValidateFileExts(strInput, strInputName, blnExts, strExts, blnIsMandatory) {
/*Purpose	:	Validates subUploadBox - validates file & valid extensions.
	Effects	:	None.
	Inputs	:	strInput -								The name/id of the file input field to be validated
						strInputName (optional) -	The display name of the file input field to be validated
						strExts (optional) -			a comma seperated list of file extentions e.g "mp3,wav,jpg"
																			must be used in conjuction with blnExts
						blnExts (optional) -			determines whether or not to allow or dis-allow file types 
																			listed in strExts to be uploaded
																			must be used in conjuction with strExts
																			true = allow only file extentions listed in strExts to be uploaded
																			false = dis-allow any file extentions listed in strExts to be uploaded
						blnMandatory              
	Returns	:	Boolean -									True if file present and exts valid (if passed to function)) and returns
																			False and displays a dialog box in not valid
	Comments:	Requires the subMsgBox function
*/
  if (blnIsMandatory) {
	  if (!ftnCheckMandatory(ftnGetObject(strInput).value)) 
	  {
		  if (strInputName == '')
		  {
			  subMsgBox('File Error', 'You must select a file to upload.');
		  }
		  else
		  {
			  subMsgBox('File Error', 'You must select a file to upload in the \'' + strInputName + '\' field.',strInput);
		  }
		  return false;		
	  }
	}
	
	if (ftnGetObject(strInput).value != '') {
	  if (strExts != '')
	  {
		  var arrExts = strExts.split(",");
		  var strFlag = false;
		  var strFilename = ftnGetObject(strInput).value;
		  var intLength = strFilename.length;
		  var strExtention = strFilename.substring((intLength-3), intLength);
		  if (blnExts == true)
		  {
			  for (i = 0; i < arrExts.length; i++) 
			  {
				  if (strExtention.toLowerCase() == arrExts[i].toLowerCase()) 
				  {
					  strFlag = true;
				  }	
			  }
			  if (strFlag == false)
			  {
				  if (strInputName == '')
				  {
					  subMsgBox('File Error', 'You are only allowed to uplaod files with the following extensions: \'' + arrExts + '\'');
				  }
				  else
				  {
					  subMsgBox('File Error', 'You are only allowed to uplaod files with the following extensions: \'' + arrExts + '\' in the \'' + strInputName + '\' field.',strInput);
				  }
				  return false;
			  }
		  }
		  if (blnExts == false)
		  {
			  for (i = 0; i < arrExts.length; i++) 
			  {
				  if (strExtention.toLowerCase() == arrExts[i].toLowerCase()) 
				  {
					  strFlag = true;
				  }	
			  }
			  if (strFlag == true)
			  {
				  if (strInputName == '')
				  {
					  subMsgBox('File Error', 'You are not allowed to upload files with the following extensions: \'' + arrExts + '\'');
				  }
				  else
				  {
					  subMsgBox('File Error', 'You are not allowed to upload files with the following extensions: \'' + arrExts + '\' in the \'' + strInputName + '\' field.',strInput);
				  }
				  return false;
			  }
		  }
	  }
	}
	return true;
}


function ftnCheckPostCode (strCode) {
  // Permitted letters depend upon their position in the postcode.
  var alpha1 = "[abcdefghijklmnoprstuwyz]";                       // Character 1
  var alpha2 = "[abcdefghklmnopqrstuvwxy]";                       // Character 2
  var alpha3 = "[abcdefghjkstuw]";                                // Character 3
  var alpha4 = "[abehmnprvwxy]";                                  // Character 4
  var alpha5 = "[abdefghjlnpqrstuwxyz]";                          // Character 5
  
  // Array holds the regular expressions for the valid postcodes
  var pcexp = new Array ();

  // Expression for postcodes: AN NAA, ANN NAA, AAN NAA, and AANN NAA
  pcexp.push (new RegExp ("^(" + alpha1 + "{1}" + alpha2 + "?[0-9]{1,2})(\\s*)([0-9]{1}" + alpha5 + "{2})$","i"));
  
  // Expression for postcodes: ANA NAA
  pcexp.push (new RegExp ("^(" + alpha1 + "{1}[0-9]{1}" + alpha3 + "{1})(\\s*)([0-9]{1}" + alpha5 + "{2})$","i"));

  // Expression for postcodes: AANA  NAA
  pcexp.push (new RegExp ("^(" + alpha1 + "{1}" + alpha2 + "?[0-9]{1}" + alpha4 +"{1})(\\s*)([0-9]{1}" + alpha5 + "{2})$","i"));
  
  // Exception for the special postcode GIR 0AA
  pcexp.push (/^(GIR)(\s*)(0AA)$/i);
  
  // Standard BFPO numbers
  pcexp.push (/^(bfpo)(\s*)([0-9]{1,4})$/i);
  
  // c/o BFPO numbers
  pcexp.push (/^(bfpo)(\s*)(c\/o\s*[0-9]{1,3})$/i);
  
  // Overseas Territories
  pcexp.push (/^([A-Z]{4})(\s*)(1ZZ)$/i);

  // Load up the string to check
  var postCode = strCode;

  // Assume we're not going to find a valid postcode
  var valid = false;
  
  // Check the string against the types of post codes
  for ( var i=0; i<pcexp.length; i++) {
    if (pcexp[i].test(postCode)) {
    
      // The post code is valid - split the post code into component parts
      pcexp[i].exec(postCode);
      
      // Copy it back into the original string, converting it to uppercase and
      // inserting a space between the inward and outward codes
      postCode = RegExp.$1.toUpperCase() + " " + RegExp.$3.toUpperCase();
      
      // If it is a BFPO c/o type postcode, tidy up the "c/o" part
      postCode = postCode.replace (/C\/O\s*/,"c/o ");
      
      // Load new postcode back into the form element
      valid = true;
      
      // Remember that we have found that the code is valid and break from loop
      break;
    }
  }
  
  // Return with either the reformatted valid postcode or the original invalid 
  // postcode
  if (valid) {return postCode;} else return false;
}