var strInvalidBgColor = "#ffcccc";
var strModalBg = ".modalBg";
var strModalWindow = ".modalWindow";

/*
	Return a boolean indicating whether or not all of the checkboxes are currently checked.
	@param aSelector the JQuery selector that should be used to match all of the intended set of checkboxes to toggle
*/
function fAllCheckBoxesChecked(aSelector) {
	var output = true;
	if(aSelector != null && aSelector != undefined && aSelector != "") {
		$(strCheckBoxesSelector).each(function() {
//console.log("$(this).attr(\"checked\") = " + $(this).attr("checked") + "\n");
			if(!$(this).attr("checked")) {
				output = false;
			}
		});
	}
	return output;
}

/*
    Return a string with an HTML "<br />" tag replacing the second to last instance of the space character (" ").
*/
function fBreakLineAtSecondToLastWord(aString) {
var debug = "";

    var output = aString;
    var intIndex = aString.lastIndexOf(" ");
debug += "aString = " + aString + "\nintIndex = " + intIndex + "\n";
    if(intIndex >= 0) {
        intIndex = aString.lastIndexOf(" ", intIndex - 1);
debug += "intIndex = " + intIndex + "\n";
        if(intIndex >= 0) { //  Replace this space with an HTML line break.
            output = aString.substr(0, intIndex) + "<br />" + aString.substr(intIndex + 1);
        }
    }
    
//alert(debug);
    return output;
}

/*
	Pass a JQuery selector for an element to center it vertically on the screen.  In order for this to occur successfully, all content must be loaded within the element prior to calling this function on it.  In order to determine the 
	vertical position, the window's current height and scroll position, as well as the height of the target element, must be taken into consideration.  JQuery is required.
	@param aSelector the JQuery selector for the element to position
*/
function fCenterVerticallyOnScreen(aSelector) {
	if(!(aSelector == undefined || aSelector == null || aSelector == "")) {
		var arrWindowDimensions = fGetWindowSize();
		var intWindowHeight = arrWindowDimensions[1];
		var intScrollPosition = fGetScrollPositionVertical();
		var intTop = intScrollPosition + intWindowHeight / 2 - $(aSelector).outerHeight() / 2;
//alert("intWindowHeight = " + intWindowHeight + "\nintScrollPosition = " + intScrollPosition + "\n");
		var btnOff = $('.play-video').offset();
		var lPos = btnOff.left;
		$(aSelector).css({top:intTop,left:lPos,marginLeft:'40px'});
	}
}

/*
	Close a modal window.  Optionally pass the ID of the modal window; otherwise the default modal window class will be used.  JQuery required.
	@param aModalSelector the JQuery selector for the modal window to open (optional)
*/
function fCloseModalWindow(aModalSelector) {
	var strSelector = strModalWindow;
	if(!(aModalSelector == undefined || aModalSelector == null || aModalSelector == "")) {
		strSelector = aModalSelector;
	}
	
	$(strModalBg).unbind("click").hide();
	$(strSelector).html("").hide();
	return false;
}

//	Return a css pixel value (eg. 44px) converted to an integer
function fCssPixelToInt(strCssVal) {
	return Number(strCssVal.replace("px", ""));
}

/*
	Return a boolean indicating whether or not an input string ends with another input string.
	@param aHaystack the string in which the search will occur
	@param aNeedle the string to search for
*/
function fEndsWith(aHaystack, aNeedle) {
	return aHaystack.indexOf(aNeedle) == aHaystack.length - aNeedle.length;
}

/*
 * Return a boolean indicating whether the user pressed the enter key on their keyboard.  Normally this function will be used in the onkeypress event for <input> 
 * elements.
 * @param e an event
 */
function fEnterKeyPressed(e){
    var key;
    if(window.event) {  //  IE
        key = window.event.keyCode;
    } else {    //  Firefox
        key = e.which;
    }
    return key == 13;	//  Code for the enter key
}

/*
	Return the index of an item in an array, or -1 if it doesn't exist.
	@param aNeedle the item to find in the array
	@param aHaystack the array to search in
*/
function fGetArrayIndex(aNeedle, aHaystack) {
	var intReturn = -1;
	var boolFound = false;
	var i = 0;
	while(!boolFound && i < aHaystack.length) {
		if(aHaystack[i] == aNeedle) {
			intReturn = i;
			boolFound = true;
		}
		i++;
	}
	return intReturn;
}

/*
  Return the prefix appended to the beginning of a .NET web control by the 
  server.  The supplied string represents a classname that has been applied to 
  one of the web controls.  Using jquery, we can obtain the id attribute of a 
  form element with that class name, strip out the server-appended prefix and 
  return it.
  @param strFieldClassName the class attribute of one of the form fields
*/
function fGetDotNetPrefix(strFieldClassName) {
var debug = "";

debug += "fGetDotNetPrefix(\"" + strFieldClassName + "\") called.\n";
//alert(debug);
  var strResponse = $("." + strFieldClassName).attr("id");
debug += "strResponse = " + strResponse + "\n";
  if(strResponse == undefined) {
		strResponse = "";
  } else {
		var intIndex = strResponse.lastIndexOf("_");
		if(intIndex == -1) {
			strResponse = "";
		} else {
			strResponse = strResponse.substr(0, intIndex + 1);
debug += "strResponse = " + strResponse + "\n";
		}
  }
  
//alert(debug);
  return strResponse;
}

/*
	Return the HTML code necessary to embed an SWF, utilizing a cachebuster to prevent it from getting cached.
	@param aPath the path and filename of the Flash
	@param anID an ID to assign to the HTML object/embed tags
	@param aWidth the width of the Flash
	@param aHeight the height of the Flash
	@param flashVars the Flashvars
	@param anAlignment where to align the flash
	@param aQuality the quality, defaults to "high"
	@param aWMode the wmode, defaults to "transparent"
	@param aBgColor the background color, defaults to "ffffff"
*/
function fGetFlash(aPath, anID, aWidth, aHeight, flashVars, allowFullScreen, anAlignment, aQuality, aWMode, aBgColor) {
	var boolID = !(anID == undefined || anID == null || anID == "");
	var boolFlashvars = !(flashVars == undefined || flashVars == null || flashVars == "");
	var boolAlignment = !(anAlignment == undefined || anAlignment == null || anAlignment == "");
	if(aQuality == undefined || aQuality == null || aQuality == "") {
		aQuality = "high";
	}
	if(aWMode == undefined || aWMode == null || aWMode == "") {
		aWMode = "transparent";
	}
	if(aBgColor == undefined || aBgColor == null || aBgColor == "") {
		aBgColor = "ffffff";
	}
	if(aBgColor.substr(0, 1) != "#") {
		aBgColor = "#" + aBgColor;
	}
	var strCacheBuster = "?cacheBuster=" + fGetRandomInteger(0, 999);
	var strPath = aPath + strCacheBuster;
	
	//	Assemble the HTML string.
	var output = "";
	output += "<object classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" codebase=\"http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0\" width=\"" + aWidth + "\" height=\"" + aHeight + "\"";
	if(boolID) {
		output += " id=\"" + anID + "\"";
	}
	if(boolAlignment) {
		output += " align=\"" + anAlignment + "\"";
	}
	output += ">\n";
	output += "<param name=\"allowScriptAccess\" value=\"sameDomain\" />\n";
	if(allowFullScreen) {
		output += "<param name=\"allowfullscreen\" value=\"true\" />\n";
	}
	output += "<param name=\"Movie\" value=\"" + strPath + "\" />\n";
	output += "<param name=\"quality\" value=\"" + aQuality + "\" />\n";
	output += "<param name=\"wmode\" value=\"" + aWMode + "\" />\n";
	output += "<param name=\"bgcolor\" value=\"" + aBgColor + "\">\n";
	if(boolFlashvars) {
		output += "<param name=\"Flashvars\" value=\"" + flashVars + "\" />\n";
	}
	output += "<embed src=\"" + strPath + "\"";
	if(boolFlashvars) {
		output += " flashvars=\"" + flashVars + "\"";
	}
	output += " wmode=\"" + aWMode + "\" bgcolor=\"" + aBgColor + "\" quality=\"" + aQuality + "\" width=\"" + aWidth + "\" height=\"" + aHeight + "\"";
	if(boolID) {
		output += " name=\"" + anID + "\"";
	}
	if(boolAlignment) {
		output += " align=\"" + anAlignment + "\"";
	}
	if(allowFullScreen) {
		output += " allowfullscreen=\"true\"";
	}
	output += " allowScriptAccess=\"sameDomain\" type=\"application/x-shockwave-flash\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" />\n";
	output += "</object>";
	
	return output;
}

/*
	Pass a filename and return the file's extension.
	@param aFilename a filename
*/
function fGetFileExtension(aFilename) {
	var output = "";
	if(aFilename != null && aFilename != undefined && aFilename != "") {
		var intExtensionIndex = aFilename.lastIndexOf('.') + 1;
		output = aFilename.substr(intExtensionIndex);
	}
	return output;
}

/*
 * Append a suffix to the end of a filename directly before the '.' preceding the file extension.
 * @param aFilename the filename to append a suffix to
 * @param aSuffix the suffix to append
 */
function fGetFilenameWithAppendedSuffix(aFilename, aSuffix) {
    var output = "";
    if(aFilename != null && aFilename != undefined && aFilename != "" && aSuffix != null && aSuffix != undefined && aSuffix != "") {
    	output = aFilename;
	    var intExtensionIndex = aFilename.lastIndexOf('.');
//alert("intExtensionIndex = " + intExtensionIndex + "\n";
			if(intExtensionIndex >= 0) {
	    	output = aFilename.substr(0, intExtensionIndex) + aSuffix + aFilename.substr(intExtensionIndex);
	    }
	  }
    return output;
}

/*
	Return the URL with a modified version of the querystring.  The specified 
	querystring variable is searched for in the querystring.  If it is found, 
	the value of it is replaced.  Otherwise, the new querystring variable is 
	appended to the end of the querystring.  If strQSValue is a blank string, the 
	querystring value is excluded from the returned querystring.  If strURL is
	supplied, it is used instead of the current URL.  Note: jquery.js 
	and jqURL.js must be imported prior to using this function, and the 
	fInsertString function may also be required.
	@param strQSKey the name of the querystring variable
	@param strQSValue the value of the querystring variable
	@param strURL a specific URL, defaults to the current URL if not supplied
*/
function fGetModifiedURL(strQSKey, strQSValue, strURL) {
	var strDebug = "";
	var strQS = "";
	var boolSpecifiedURL = false;
	if(strURL == undefined || strURL == "") {	  
strDebug += "strQSKey = " + strQSKey + "\nstrQSValue = " + strQSValue + "\nstrURL = " + strURL + "\n";
		strQS = $.jqURL.qs();
		strURL = $.jqURL.strip();
	} else {
		boolSpecifiedURL = true;
		arrURL = strURL.split("?");
		strURL = arrURL[0];
		if(arrURL.length > 1) {
			strQS = arrURL[1];
		}
	}
strDebug += "boolSpecifiedURL = " + boolSpecifiedURL + "\n";
strDebug += "strQS = " + strQS + "\n";

  var intKeyLength = strQSKey.length + 1;	//	includes the equal sign

	var intKeyIndex = -1;
	if(strQS != "" && strQS != undefined) {
		intKeyIndex = strQS.indexOf(strQSKey + "=");
strDebug += "intKeyIndex = " + intKeyIndex + "\n";
	}	
	var intQsValueIndex = intKeyIndex + intKeyLength;
	if (strQS!= "" && strQS != undefined)
  	var intNextQsVarIndex = strQS.indexOf("&", intQsValueIndex);
		
strDebug += "intKeyIndex = " + intKeyIndex + "\n";
	var currentValue = "";
	if(boolSpecifiedURL) {
strDebug += "intKeyIndex = " + intKeyIndex + "\n";
		if(intKeyIndex != -1) {	//	the key exists in the querystring.
			if(intNextQsVarIndex > -1) {	//	get val from in between the '=' and the '&'
				currentValue = strQS.substr(intQsValueIndex, intNextQsVarIndex - intQsValueIndex);
			} else {	//	get val from everything after the '='
				currentValue = strQS.substr(intQsValueIndex);
			}
		}
strDebug += "currentValue = " + currentValue + "\n";
	} else {
strDebug += "$.jqURL.get(\"" + strQSKey + "\") = " + $.jqURL.get(strQSKey) + "\n";
		currentValue = $.jqURL.get(strQSKey);
	}
strDebug += "currentValue = " + currentValue + "\n";
	var boolDeleteQSVar = strQSValue == "" || strQSValue == undefined ? true : false;
	if(strQS == undefined || strQS == "") {
		strURL += boolDeleteQSVar ? "" : "?" + strQSKey + "=" + strQSValue;
	} else if(currentValue == "" || currentValue == undefined || currentValue == null) {
		if(intKeyIndex == -1) {	//	Normally this will be the case.
			strURL += boolDeleteQSVar ? "?" + strQS : "?" + strQS + "&" + strQSKey + "=" + strQSValue;
		} else {
			/*
				The key exists, but there is no value assigned to it.  For example, 
				"&txtFilterpageRoles=" in the URL below:
				editTable.php?txtFilename=pages.xml&txtFilter=&txtTranslatedField=&txtFilterField=&txtFilterID=&txtFilterpageRoles=
			*/
			if(boolDeleteQSVar) {
				strURL += "?" + strQS;
			} else {
				strURL += "?" + fInsertString(strQS, strQSValue, intKeyIndex + intKeyLength);
			}
		}
	} else {	//	replace the variable instead of appending it.
		var intStart = boolDeleteQSVar ? intKeyIndex - 1 : intQsValueIndex;
		var intLength = -1;
		if(boolDeleteQSVar) {
			if(intNextQsVarIndex > -1) {	//	there is another qs var following this one
				intLength = strQS.substr(intStart + 1).indexOf("&") + 1;
			}
		} else {
			if(intNextQsVarIndex > -1) {
				intLength = strQS.substr(intStart).indexOf("&");
			}
		}
strDebug += "intStart = " + intStart + "\n";
strDebug += "intNextQsVarIndex = " + intNextQsVarIndex + "\n";
strDebug += "intLength = " + intLength + "\n";
		if(intStart == -1) {	//	it is the first querystring var.
			if(intLength > 0) {	//	more querystring vars follow this one.
				strURL += boolDeleteQSVar ? "?" + strQS.substr(intNextQsVarIndex + 1) : "?" + strQS.substr(0, intStart) + strQSValue + strQS.substr(intStart + intLength);
			}
		} else {
			if(intLength == -1) {	//	it is the last querystring var.
				strURL += boolDeleteQSVar ? "?" + strQS.substr(0, intStart) : "?" + strQS.substr(0, intStart) + strQSValue;
			} else {	//	more querystring vars follow this one.
				strURL += boolDeleteQSVar ? "?" + strQS.substr(0, intStart) + strQS.substr(intNextQsVarIndex) : "?" + strQS.substr(0, intStart) + strQSValue + strQS.substr(intStart + intLength);
strDebug += "strQS = " + strQS + "\n";
strDebug += "strQS.substr(" + intNextQsVarIndex + ") = " + strQS.substr(intNextQsVarIndex) + "\n";
			}
		}
	}
strDebug += "strURL = " + strURL + "\n";
//alert(strDebug);
	return strURL;
}

function fGetNoFlash(anImgPath, aWidth, aHeight, anAlt) {
	return "<a href=\"http://www.adobe.com/products/flashplayer/\" target=\"_blank\"><img src=\"" + anImgPath + "\" height=\"" + aHeight + "\" width=\"" + aWidth + "\" alt=\"" + anAlt + "\" border=\"0\" /></a>";
}

function fGetNumLinksAbove(anID) {
//alert($("#" + anID).prev().is("a"));
	if(!$("#" + anID).prev().is("a")) {	//	the base case
		return 0;
	} else {
		return 1 + fGetNumLinksAbove($("#" + anID).prev().attr("id"));
	}
}

/*
	Return a random integer from a starting integer to an ending integer, inclusive.
	@param aMinimum the minimum value
	@param aMaximum the maximum value
*/
function fGetRandomInteger(aMinimum, aMaximum) {
	return Math.floor(Math.random() * aMaximum + aMinimum);
}

//	Return the vertical scroll position.
function fGetScrollPositionVertical() {
	var output = document.body.scrollTop;
	if (output == 0)
	{
    if (window.pageYOffset)
      output = window.pageYOffset;
    else
      output = (document.body.parentElement) ? document.body.parentElement.scrollTop : 0;
	}
	return output;
}

/*
	Return a list of <option> tags containing United States of America's states, 
	one of which is selected, if specified.  If not, the first option is selected.
	@param strSelected the selected state
*/
function fGetStateList(strSelected) {
	var strResponse = "";
	var arrStates = new Array();
	arrStates[0] = new Array("", "Choose State");
	arrStates[1] = new Array("AL", "Alabama");
	arrStates[2] = new Array("AK", "Alaska");
	arrStates[3] = new Array("AZ", "Arizona");
	arrStates[4] = new Array("AR", "Arkansas");
	arrStates[5] = new Array("CA", "California");
	arrStates[6] = new Array("CO", "Colorado");
	arrStates[7] = new Array("CT", "Connecticut");
	arrStates[8] = new Array("DE", "Delaware");
	arrStates[9] = new Array("DC", "Washington, DC");
	arrStates[10] = new Array("FL", "Florida");
	arrStates[11] = new Array("GA", "Georgia");
	arrStates[12] = new Array("HA", "Hawaii");
	arrStates[13] = new Array("ID", "Idaho");
	arrStates[14] = new Array("IL", "Illinois");
	arrStates[15] = new Array("IN", "Indiana");
	arrStates[16] = new Array("IA", "Iowa");
	arrStates[17] = new Array("KS", "Kansas");
	arrStates[18] = new Array("KY", "Kentucky");
	arrStates[19] = new Array("LA", "Louisiana");
	arrStates[20] = new Array("ME", "Maine");
	arrStates[21] = new Array("MD", "Maryland");
	arrStates[22] = new Array("MA", "Massachusetts");
	arrStates[23] = new Array("MI", "Michigan");
	arrStates[24] = new Array("MN", "Minnesota");
	arrStates[25] = new Array("MS", "Mississippi");
	arrStates[26] = new Array("MO", "Missouri");
	arrStates[27] = new Array("MT", "Montana");
	arrStates[28] = new Array("NE", "Nebraska");
	arrStates[29] = new Array("NV", "Nevada");
	arrStates[30] = new Array("NH", "New Hampshire");
	arrStates[31] = new Array("NJ", "New Jersey");
	arrStates[32] = new Array("NM", "New Mexico");
	arrStates[33] = new Array("NY", "New York");
	arrStates[34] = new Array("NC", "North Carolina");
	arrStates[35] = new Array("ND", "North Dakota");
	arrStates[36] = new Array("OH", "Ohio");
	arrStates[37] = new Array("OK", "Oklahoma");
	arrStates[38] = new Array("OR", "Oregon");
	arrStates[39] = new Array("PA", "Pennsylvania");
	arrStates[40] = new Array("PR", "Puerto Rico");
	arrStates[41] = new Array("RI", "Rhode Island");
	arrStates[42] = new Array("SC", "South Carolina");
	arrStates[43] = new Array("SD", "South Dakota");
	arrStates[44] = new Array("TN", "Tennessee");
	arrStates[45] = new Array("TX", "Texas");
	arrStates[46] = new Array("UT", "Utah");
	arrStates[47] = new Array("VT", "Vermont");
	arrStates[48] = new Array("VA", "Virginia");
	arrStates[49] = new Array("WA", "Washington");
	arrStates[50] = new Array("WV", "West Virginia");
	arrStates[51] = new Array("WI", "Wisconsin");
	arrStates[52] = new Array("WY", "Wyoming");
	
	var strValue = "";
	var strDisplay = "";
	for(var i = 0; i < arrStates.length; i++) {
		strValue = arrStates[i][0];
		strDisplay = arrStates[i][1];
		strResponse += "<option value=\"" + strValue + "\"";
		if(strValue == strSelected) {
			strResponse += " selected=\"selected\"";
		}
		strResponse += ">" + strDisplay + "</option>";
	}
	
	return strResponse;
}

//	Return an array with two integers: {width, height}
function fGetWindowSize(intDefaultWidth, intDefaultHeight) {
	var width = intDefaultWidth ? intDefaultWidth : -1;
	var height = intDefaultHeight ? intDefaultHeight : -1;
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    if (window.innerWidth > width)
	    width = window.innerWidth;
	  if (window.innerHeight > height)
	    height = window.innerHeight;
  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    if (document.documentElement.clientWidth > width)
	    width = document.documentElement.clientWidth;
	  if (document.documentElement.clientHeight > height)
    height = document.documentElement.clientHeight;
  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    if (document.body.clientWidth > width)
	    width = document.body.clientWidth;
  	if (document.body.clientHeight > height)
    height = document.body.clientHeight;
  }
  var arrDimensions = new Array();
  arrDimensions[0] = width;
  arrDimensions[1] = height;
  return arrDimensions;
}

/*
	Implode an array into a grammatically correct string containing the items of the array, and then return the string.  If the array has no items or is null, return an empty string.  If it
	has one item, return the text of that one item.  If it has two items, return the text of both items separated by " and ".  If there are more than two items, return a string formatted as
	follows: "item1, item2 and item3"
	@param anArray an array of stuff
*/
function fImplodeGrammatically(anArray) {
	output = "";
	if(anArray != null && anArray != undefined) {
		var intItems = anArray.length;
		if(intItems > 0) {	//	There is at least one item in the array.
			strItem = anArray[0];
			output += strItem;
			if(intItems == 2) {
				output += " and " . anArray[1];
			} else if(intItems > 2) {
				for(i = 1; i < intItems; i++) {
					strItem = anArray[i];
					if(i == intItems - 1) {	//	For the last iteration, separate this item with an " and " instead of a comma.
						output += " and ";
					} else {
						output += ", ";
					}
					output += strItem;
				}
			}
		}
	}
	
	return output;
}

/*
	Return a boolean indicating whether or not an array contains a specified value.
	@param aNeedle the item to search for in the array.
	@param aHaystack the array to search for
*/
function fInArray(aNeedle, aHaystack) {
	var intIndex = fGetArrayIndex(aNeedle, aHaystack);
	if(intIndex == -1) {
		return false;
	} else {
		return true;
	}
}

/*
	Insert a string into another string at a specified index.
	@param strInput the string to insert another string into
	@param strInsert the string to be inserted
	@param intIndex the index where the string should be inserted
*/
function fInsertString(strInput, strInsert, intIndex) {
	var strOutput = strInput.substr(0, intIndex);
	strOutput += strInsert;
	return strOutput + strInput.substr(intIndex);
}
	
/*
	Return a boolean indicating whether or not the passed value is an integer.
	@param aValue the value that we want to determine whether or not is an integer
*/
function fIsInteger(aValue) {
	return !isNaN(aValue) && aValue.indexOf('.') < 0;
}

/*
	Function to determine if it is a valid Canadian postal code.
	@param aPostalCode the Canadian postal code to test
*/
function fIsValidCanadianPostalCode(aPostalCode) {
    var objRegExp = /^([A-Za-z][0-9][A-Za-z] [0-9][A-Za-z][0-9])$/;
//alert("objRegExp.test(\"" + aPostalCode + "\") = " + objRegExp.test(aPostalCode) + "\n");
    return objRegExp.test(aPostalCode);
}

/*
	Function to determine if it is a valid us zip code
	@param aZip the zipcode to test
	@param shouldAllowNineDigits a boolean which will pass a zipcode such as "06001-1234" if passed as true
*/
function fIsValidUsZip(aZip, shouldAllowNineDigits) {
    var objRegExp;
    var boolShouldAllowNineDigits = shouldAllowNineDigits;
    if(shouldAllowNineDigits == null || shouldAllowNineDigits == undefined) {
    	boolShouldAllowNineDigits = false;		//	Disallow nine digit format by default
    }
    if(boolShouldAllowNineDigits) {
    	objRegExp = /(^\d{5}$)|(^\d{5}-\d{4}$)/;
    } else {
    	objRegExp = /(^\d{5}$)/;
    }
//alert("objRegExp.test(\"" + aZip + "\") = " + objRegExp.test(aZip) + "\n");
    return objRegExp.test(aZip);
}

/*
	Match the height of a background div to the height of a foreground div.  The heights of <img> tags used as top and bottom borders are taken into consideration.
	@param aBgSelector a JQuery selector for the background container
	@param aFgSelector a JQuery selector for the foreground container
*/
function fMatchHeights(aBgSelector, aFgSelector) {
	//	Set up vars.
	var intHeight = 0;
	var intBorderHeight = 0;	//	Combined height of both image tags that constitute the top and bottom borders
	
	$(aFgSelector).each(function() {
		intHeight = $(this).outerHeight();
		intBorderHeight = 0;
		$(this).siblings(aBgSelector).children("img").each(function() {
			intBorderHeight += $(this).height();
		});
		
		intHeight -= intBorderHeight;
//alert("intBorderHeight = " + intBorderHeight + "\nintHeight = " + intHeight + "\n");
		$(this).siblings(aBgSelector).children("div").height(intHeight);
	});
}

/*
	Open a modal window.  Optionally pass the ID of the modal window; otherwise the default modal window class will be used.  JQuery required.  You'll generally want to use the following CSS in your exteral stylesheet:
		.modalBg, .modalWindow {
			display: none;
			position: absolute;
			top: 0px;
			left: 0px;
		}
		.modalBg {
			filter: alpha(opacity = 50);
			opacity: 0.5;
			background-color: #000000;
		}
		.modalWindow {
			background-color: #ffffff;
		}
	@param aModalSelector the JQuery selector for the modal window to open (optional)
*/
function fOpenModalWindow(aModalSelector) {
	var strSelector = strModalWindow;
	if(!(aModalSelector == undefined || aModalSelector == null || aModalSelector == "")) {
		strSelector = aModalSelector;
	}
	
	$(strModalBg).width($("body").outerWidth()).height('1000px').show().click(function() {
		fCloseModalWindow();
	});
	//alert(strSelector);
	$(strSelector).show();
}

//	Resize the current window to full screen.  This doesn't work for Safari.
function fResizeWindowToFullScreen() {
	window.moveTo(0,0);
	if (document.all) {
	  top.window.resizeTo(screen.availWidth, screen.availHeight);
	} else if (document.layers||document.getElementById) {
		var oWindow = top.window;
		var intAvailableHeight = screen.availHeight;
		var intAvailableWidth = screen.availWidth;
//alert("intAvailableHeight = " + intAvailableHeight + "\nintAvailableWidth = " + intAvailableWidth + "\noWindow.outerHeight = " + oWindow.outerHeight + "\noWindow.outerWidth = " + oWindow.outerWidth + "\n");
	  if (oWindow.outerHeight < intAvailableHeight || oWindow.outerWidth < intAvailableWidth) {
	    oWindow.outerHeight = intAvailableHeight;
	    oWindow.outerWidth = intAvailableWidth;
	  }
//alert("oWindow.outerHeight = " + oWindow.outerHeight + "\noWindow.outerWidth = " + oWindow.outerWidth + "\n");
	}
	
	return true;
}

/*
	Return a boolean indicating whether or not an input string begins with another input string.
	@param aHaystack the string in which the search will occur
	@param aNeedle the string to search for
*/
function fStartsWith(aHaystack, aNeedle) {
	return aHaystack.indexOf(aNeedle) == 0;
}

//	Recursive function that returns the passed string with leading and trailing white space removed.
function fTrim(aString) {
	var output = aString;
	
	if(aString != undefined && aString != "") {
		var intFirstSpaceIndex = aString.indexOf(" ");
		var intLastSpaceIndex = aString.lastIndexOf(" ");
		var boolLeadingWhiteSpace = intFirstSpaceIndex == 0;
		var intLastCharIndex = aString.length - 1;
		var boolTrailingWhiteSpace = intLastSpaceIndex == intLastCharIndex;
			
	//alert("aString = " + aString + "\nintLastSpaceIndex = " + intLastSpaceIndex + "\nboolTrailingWhiteSpace = " + boolTrailingWhiteSpace + "\n");
		if(boolLeadingWhiteSpace) {
			output = fTrim(aString.substr(1));
		} else if(boolTrailingWhiteSpace) {
			output = fTrim(aString.substr(0, intLastCharIndex));
		} else {	//	The base case: no leading or trailing whitespace exists
			output = aString;
		}
	}
	
	return output;
}

//	Return the supplied string with the first character converted to upper case.
function fTurnFirstToUpper(strInput) {
	return strInput.substr(0, 1).toUpperCase() + strInput.substr(1);
}

/*
	Embed an SWF, utilizing a cachebuster to prevent it from getting cached.
	@param aPath the path and filename of the Flash
	@param anID an ID to assign to the HTML object/embed tags
	@param aWidth the width of the Flash
	@param aHeight the height of the Flash
	@param flashVars the Flashvars
	@param anAlignment where to align the flash
	@param aQuality the quality, defaults to "high"
	@param aWMode the wmode, defaults to "transparent"
	@param aBgColor the background color, defaults to "ffffff"
*/
function fWriteFlash(aPath, anID, aWidth, aHeight, flashVars, allowFullScreen, anAlignment, aQuality, aWMode, aBgColor) {
	var strFlash = fGetFlash(aPath, anID, aWidth, aHeight, flashVars, allowFullScreen, anAlignment, aQuality, aWMode, aBgColor);
	document.writeln(strFlash);
}

function fWriteNoFlash(anImgPath, aWidth, aHeight, anAlt) {
	document.writeln(fGetNoFlash(anImgPath, aWidth, aHeight, anAlt));
}

/*
	FORM VALIDATION
*/
function fVerifyGuiInputMaxLength(strID, intLength, strText) {
	var oInput = document.getElementById(strID);
	var strInput = oInput.value.replace(/(<([^>]+)>)/ig,"");	//	Remove the HTML tags
//alert("strInput.length = " + strInput.length);
	if(strInput.length > intLength) {
		oInput.style.background = strInvalidBgColor;
		return strText;
	} else {
		oInput.style.background = "";
		return "";
	}
}

//	This is necessary because the default text of the javascript GUI text areas is not the same across browsers.
function fVerifyGuiInput(strID, strText) {
	var oInput = document.getElementById(strID);
	var arrEmptyValues = new Array();
	arrEmptyValues[0] = "";
	arrEmptyValues[1] = " ";
	arrEmptyValues[2] = "&nbsp;";
	arrEmptyValues[3] = "\n\n";
	var boolIsEmpty = false;
	for(var i = 0; i < arrEmptyValues.length; i++) {
		if(oInput.value == arrEmptyValues[i]) {
			boolIsEmpty = true;
			break;
		}
	}
	if(boolIsEmpty) {
		oInput.style.background = strInvalidBgColor;
		return strText;
	} else {
		oInput.style.background = "";
		return "";
	}
}

function fVerifyRadio(strID, strText) {
	var oRadio = document.getElementsByName(strID);
	for(i=0; i<oRadio.length; i++) {
		if(oRadio[i].checked) {
			return "";
		}
	}
	return "Please answer " + strText + ".\n";
}

function fVerifySelect(strID, strText) {
	var oElement = document.getElementById(strID);
	if(oElement.selectedIndex == 0) {
		oElement.style.background = strInvalidBgColor;
		oElement.focus();
		return strText;
	} else {
		oElement.style.background = "#ffffff";
	}
	return "";
}

function fShow(strDiv) {
	document.getElementById(strDiv).style.visibility = "visible";
	document.getElementById(strDiv).style.display = "block";
}

function fHide(strDiv) {
	document.getElementById(strDiv).style.visibility = "hidden";
	document.getElementById(strDiv).style.display = "none";
}


function fToggle(strID) {
	if(document.getElementById(strID).style.visibility == "hidden") {
		fShow(strID);
	} else {
		fHide(strID);
	}
}
