/// <reference path="MetafuseBase.js" />

//STW 2011-05-17 these should be renamed possibly...
function IsIE8Browser()
{
	var rv = -1;
	var ua = navigator.userAgent;
	var re = new RegExp("Trident\/([0-9]{1,}[\.0-9]{0,})");

	if (re.exec(ua) != null)
	{
		rv = parseFloat(RegExp.$1);
	}

	return (rv == 4);
};


//GLOBAL SYSTEM FUNCTIONS
//Set Hidden Input On Form
function SHV(hiddenInput, hiddenValue)
{
	///	<summary>
	///		Short cut method to set the hidden input on a form. 
	///	</summary>
	///	<param name="hiddenInput" type="string">name or id of the hidden input element</param>
	///	<param name="hiddenValue" type="string">value of the input to set</param>
	/// <returns type="void" />
	FormTools.SetFormElementValue(hiddenInput, hiddenValue);
};

var AdditionalHiddenElementNamesToAppendToReturnUrl = null;
///	<summary>
///	 var Array of hidden element names to append to the return URL
///	</summary>
var AdditionalHiddenElementNamesToAppendToHyperLink = null;

//Generic Link Creator Makes ReturnUrl and Scroll Position
var metafuseGlobalCancelAppendReturnUrl = false;
var metafuseGlobalHttpProtocolAndServerName = "";
var metafuseGlobalLinkOpenInNewWindow = null; //used by PI to allow a link to open in a new window with the CNTRL key, hooked up by the document onload dynamically
function L(scriptPath, excludeReturnUrl, openInNewWindow)
{
	///	<summary>
	///	Default hyperlink function, automatically appends the ReturnURL and any hidden elements being monitored into the URL string.   Root is prepended to the URL, so Root is not required.
	///	</summary>
	///	<param name="scriptPath" type="string">relative (from after Root) path to the file to load.  (i.e. /content/display.aspx)</param>
	///	<param name="excludeReturnUrl" type="bool">flag indicating whether or not to exclude the return url (default false, the ReturnURL will be appended)</param>
	///	<param name="excludeReturnUrl" type="bool">flag indicating whether or not to open the URL in a new window (default false)</param>
	/// <returns type="bool" />

	//alert(Root + scriptPath);
	//alert(AppendReturnUrl(Root + scriptPath));
	var hyperLink = AppendAdditionalHiddenElementNamesToHyperLink(scriptPath);
	var hyperlinkToTest = hyperLink.toLowerCase();

	//if the HTTP protocol wasn't supplied then add the root and any global HTTP Protocol and Server Name to invoke through JS Links
	if (hyperlinkToTest.indexOf("http://", 0) != 0 && hyperlinkToTest.indexOf("https://", 0) != 0 && hyperlinkToTest.indexOf(Root.toLowerCase()) != 0)
	{
		hyperLink = metafuseGlobalHttpProtocolAndServerName + Root + hyperLink;
	}



	var url = "";
	if (excludeReturnUrl || metafuseGlobalCancelAppendReturnUrl)
	{
		url = hyperLink;
	}
	else
	{
		try
		{
			url = AppendReturnUrl(hyperLink);
		}
		catch (e)
		{
			url = hyperLink;
		}

	}

	if (openInNewWindow) // || UITools.GlobalIsControlKeyDown)
	{
		window.open(url, "_blank");
	}
	else
	{
		window.location.href = url;
	}

	return false;
};


function CL(confirmMessage, scriptPath, excludeReturnUrl, excludeReturnUrl)
{
	///	<summary>
	///	Confirms the message and then invokes the hyperlink function to append an Id (default parameter) to a script name, then invoke the default L function to perform the hyperlink
	///	</summary>
	/// <param name="confirmMessage" type="string">confirmation message to display</param>
	///	<param name="scriptPath" type="string">relative (from after Root) path to the file to load.  (i.e. /content/display.aspx)</param>
	///	<param name="id" type="string"> value of the id to pass</param>
	///	<param name="optionalNameString" type="string"> optional name of the "Id" paramter, use when the paramter is NOT "Id"</param>
	/// <returns type="bool" />
	if (confirm(confirmMessage))
	{
		return L(scriptPath, excludeReturnUrl, excludeReturnUrl);
	}
	return false;
};

//generic link object, takes script path and concatenates id to path.
function LI(scriptPath, id, optionalNameString)
{
	///	<summary>
	///	Hyperlink function to append an Id (default parameter) to a script name, then invoke the default L function to perform the hyperlink
	///	</summary>
	///	<param name="scriptPath" type="string">relative (from after Root) path to the file to load.  (i.e. /content/display.aspx)</param>
	///	<param name="id" type="string"> value of the id to pass</param>
	///	<param name="optionalNameString" type="string"> optional name of the "Id" paramter, use when the paramter is NOT "Id"</param>
	/// <returns type="bool" />
	if (scriptPath.indexOf("?") >= 0)
	{
		scriptPath += "&";
	}
	else
	{
		scriptPath += "?";
	}

	if (!optionalNameString)
	{
		optionalNameString = "Id";
	}

	return L(scriptPath + optionalNameString + "=" + id);

};

function ConfirmAndPostBack(confirmMessage, target, args)
{
	///	<summary>
	///	Basic method to perform __doPostBack(target, args); event, after a confirmation message is presented.
	///	</summary>
	///	<param name="confirmMessage" type="string">Confirmation message to display.</param>
	///	<param name="target" type="string"> target to pass to __doPostBack</param>
	///	<param name="args" type="string"> arguments to pass to __doPostBack</param>
	/// <returns type="void" />
	if (confirm(confirmMessage))
	{
		__doPostBack(target, args);
	}
};



//Appends the ReturnUrl to the Link
function AppendReturnUrl(scriptPath, returnUrl)
{
	///	<summary>
	///	Appends the ReturnURL to the script path to form a URL.  Typically a private function, called by the default link function L.
	///	</summary>
	///	<param name="scriptPath" type="string">relative (from after Root) path to the file to load.  (i.e. /content/display.aspx)</param>
	///	<param name="returnUrl" type="string"> to append to the hyperlink</param>
	///	<param name="optionalNameString" type="string"> optional name of the "Id" paramter, use when the paramter is NOT "Id"</param>
	/// <returns type="string" />
	if (!returnUrl)
	{
		returnUrl = ReturnUrl;
	}

	returnUrl = AppendScrollLocation(returnUrl);

	if (scriptPath.indexOf("?") >= 0)
	{
		scriptPath += "&";
	}
	else
	{
		scriptPath += "?";
	}
	scriptPath += "ReturnUrl=" + escape(returnUrl);

	return scriptPath;
};
//Appends the Scroll Position to the ReturnUrl
function AppendScrollLocation(returnUrl)
{
	///	<summary>
	///	Appends the scroll location to the supplied ReturnURL.  Used for smart scrolling by the L function.
	///	</summary>
	///	<param name="returnUrl" type="string"> to append to the scroll location to.</param>
	/// <returns type="string" />

	var scrollX = GetElementById("__sx");
	var scrollY = GetElementById("__sy");

	if (scrollX && scrollX.value != "" && scrollX.value != "0")
	{
		if (returnUrl.indexOf("?") >= 0)
		{
			returnUrl += "&";
		}
		else
		{
			returnUrl += "?";
		}
		returnUrl += "_sx=" + scrollX.value;
	}
	if (scrollY && scrollY.value != "" && scrollY.value != "0")
	{
		if (returnUrl.indexOf("?") >= 0)
		{
			returnUrl += "&";
		}
		else
		{
			returnUrl += "?";
		}
		returnUrl += "_sy=" + scrollY.value;
	}

	if (AdditionalHiddenElementNamesToAppendToReturnUrl != null)
	{
		for (var i = 0; i < AdditionalHiddenElementNamesToAppendToReturnUrl.length; i++)
		{
			var elementName = AdditionalHiddenElementNamesToAppendToReturnUrl[i];
			var elementValue = FormTools.GetFormElementValue(elementName);
			if (elementValue && elementValue != "")
			{
				//add extra "_" for these columns (backward from scrolling);
				//we may want to move the prefix out of here and into the base and supply the prefix
				//in the element name, this prevents it from being added continuously into the return url.
				if (returnUrl.indexOf("?") >= 0)
				{
					returnUrl += "&"
				}
				else
				{
					returnUrl += "?";
				}
				returnUrl += "_0" + elementName + "=" + elementValue;
			}
		}
	}
	return returnUrl;
};

function AppendAdditionalHiddenElementNamesToHyperLink(hyperLink)
{
	///	<summary>
	///	Appends additional hidden element names to the hyperlink.  Used to append client side information to the link just before invoking the hyperlink.
	///	</summary>
	///	<param name="hyperLink" type="string"> to append the additional element names to.</param>
	/// <returns type="string" />

	if (AdditionalHiddenElementNamesToAppendToHyperLink != null)
	{
		for (var i = 0; i < AdditionalHiddenElementNamesToAppendToHyperLink.length; i++)
		{
			var elementName = AdditionalHiddenElementNamesToAppendToHyperLink[i];
			var elementValue = FormTools.GetFormElementValue(elementName);
			if (elementValue && elementValue != "")
			{
				//add extra "_" for these columns (backward from scrolling);
				//we may want to move the prefix out of here and into the base and supply the prefix
				//in the element name, this prevents it from being added continuously into the return url
				//and also helps the program tell the difference between parameters of control sent from
				//another script vs. the current script.
				if (hyperLink.indexOf("?") >= 0)
				{
					hyperLink += "&" + "_0" + elementName + "=" + elementValue;
				}
				else
				{
					hyperLink += "?" + "_0" + elementName + "=" + elementValue;
				}
			}
		}
	}
	return hyperLink;
};


//takes checkbox name and creates a comma separated list of the ids of these checkboxes.
function CreateGuidStringFromCheckBoxIndexes(checkBoxName)
{
	///	<summary>
	///	DEPRECATED, DO NOT USE
	///	</summary>
	f = document.forms[0];
	var ids = "";


	if (f[checkBoxName])
	{
		if (f[checkBoxName].length)
		{
			for (i = 0; i < f[checkBoxName].length; i++)
			{
				if (f[checkBoxName][i].checked)
				{
					if (ids != "")
					{
						ids += ",";
					}

					ids += GuidArray[f[checkBoxName][i].value];
				}
			}
		}
		else
		{
			if (f[checkBoxName].checked)
			{
				ids = GuidArray[f[checkBoxName].value];
			}
		}
	}

	return ids;
};

function CreateGuidStringFromIndexArray(indexArray)
{
	///	<summary>
	///	DEPRECATED, DO NOT USE
	///	</summary>
	var ids = "";

	for (i = 0; i < indexArray.length; i++)
	{
		if (ids != "")
		{
			ids += ",";
		}
		if (GuidArray[indexArray[i]])
		{
			ids += GuidArray[indexArray[i]];
		}
	}
	return ids;
};
function CreateCommaSeparatedStringFromArrayMembers(array)
{
	var s = "";

	if (array)
	{
		for (var i = 0; i < array.length; i++)
		{
			if (s != "")
			{
				s += ",";
			}
			var a = array[i];

			if (a != null)
			{
				s += a;
			}
		}
	}
	return s;
};

/**********************************************************
On Load Hookup
**********************************************************/
var OnLoad =
{
	///	<summary>
	///	Global Onload object, holding the functions to be invoked during single onload.
	///	</summary>
	/*
	aFunctions :
	[],
	*/
	AddFunction:

		function (oFunctionPointer)
		{
			var oldonload = window.onload;
			if (typeof window.onload == 'function')
			{
				window.onload = function ()
				{
					oldonload();
					oFunctionPointer();
				}
			}
			else
			{
				window.onload = oFunctionPointer;
			}

		}
};

//onload = function(){ OnLoad.CallFunctions(); };
/**********************************************************
On Scroll Hookup
**********************************************************/
var OnScrollFunctions =
{
	///	<summary>
	///	Global OnScrollFunctions object, holding the functions to be invoked during single onscroll.
	///	</summary>
	aFunctions:
		[],
	AddFunction:
		function (oFunctionPointer)
		{
			if (!this.Loaded)
			{
				this.aFunctions[this.aFunctions.length] = oFunctionPointer;
			}
			else
			{
				oFunctionPointer();
			}
		},
	CallFunctions:
		function ()
		{
			for (oFunctionPointer in this.aFunctions)
			{
				this.aFunctions[oFunctionPointer]();
			}
			this.Loaded = true;
		},
	Loaded:
		false
};

window.onscroll = function () { OnScrollFunctions.CallFunctions(); };
/**********************************************************
On Window Resize
***********************************************************/
var OnWindowResizeFunctions =
{
	///	<summary>
	///	Global OnScrollFunctions object, holding the functions to be invoked during single window resize call.
	///	</summary>
	aFunctions:
		[],
	AddFunction:
		function (oFunctionPointer)
		{
			if (!this.Loaded)
			{
				this.aFunctions[this.aFunctions.length] = oFunctionPointer;
			}
			else
			{
				oFunctionPointer();
			}
		},
	CallFunctions:
		function ()
		{
			for (oFunctionPointer in this.aFunctions)
			{
				this.aFunctions[oFunctionPointer]();
			}
			this.Loaded = true;
		},
	Loaded:
		false
};
function WindowResize()
{
	OnWindowResizeFunctions.CallFunctions();
};
window.onresize = function () { OnWindowResizeFunctions.CallFunctions(); };

/**********************************************************

***********************************************************/
var OnDocumentUnloadFunctions =
{
	///	<summary>
	///	Global OnDocumentUnloadFunctions object, holding the functions to be invoked during single document unload
	///	</summary>
	aFunctions:
		[],
	AddFunction:
		function (oFunctionPointer)
		{
			var dupe = false;
			for (var i = 0; i < this.aFunctions.length; i++)
			{
				if (this.aFunctions[i] == oFunctionPointer)
				{
					dupe = true;
				}
			}
			if (dupe == false)
			{
				this.aFunctions[this.aFunctions.length] = oFunctionPointer;
			}
		},
	CallFunctions:
		function ()
		{
			for (oFunctionPointer in this.aFunctions)
			{
				this.aFunctions[oFunctionPointer]();
			}
		}
};
function OnDocumentUnload()
{
	///	<summary>
	///	Global document unload method, calls OnDocumentUnloadFunctions.CallFunctions();
	///	</summary>
	OnDocumentUnloadFunctions.CallFunctions();
};
//set in body to enable
//document.body.onunload = function(){ OnDocumentUnload.CallFunctions(); };

/***********************************************************
Get Element By Id (Cross Browser)
************************************************************/
function GetElementById(elementId)
{
	///	<summary>
	///	Gets the DOM element from the supplied elementId.  The DOM element is located using various different methods to locate the element.  Use in place of document.getElementById(...) DOM element may be passed in, if the DOM element is interchangably used with the string ID or element name.   
	///	</summary>
	///	<param name="elementId" type="string"> id of the element to return.  If the actual DOM element is passed in, the DOM element is returned unchanged.</param>
	/// <returns type="element">DOM Element matching the element ID, or null if not</returns>


	//if the elementId passed in is a string, lookup the element object
	if (typeof elementId == 'string')
	{
		if (elementId == "")
		{
			return null;
		}
		else
		{
			var element = document.getElementById(elementId)

			if (!element)
			{
				element = document.forms[0][elementId];
			}
			return element;
		}
	}
	//elementId was not a string return the element object
	//this allows most methods to take either the element id or the element in a single parameter to functions
	else
	{
		return elementId;
	}
};


//Creates a simulated guid for use in JavaScript methods
function NewGuid()
{
	///	<summary>
	///	Creates a psuedo GUID.  Typically used for inline editing with the MetafuseTable object.   
	///	</summary>
	/// <returns type="string"> new GUID</returns>

	//dont use ActiveX any longer since it doesn't work on IE7 without a warning
	//try
	//{
	//	var x = new ActiveXObject("Scriptlet.TypeLib");

	//	return (x.guid);
	//}
	//catch (e)
	//{
	//create GUID here
	var g = "";
	for (var i = 0; i < 32; i++)
	{
		//random character for the guid
		var chr = Math.floor(Math.random() * 0xF).toString(0xF);

		//if we don't get a char for some reason just make it 0
		if (chr == null || chr == "" || chr.length > 1)
		{
			chr == "0";
		}

		//add the dash in to format the GUID correctly
		if (i == 7 || i == 11 || i == 15 || i == 19)
		{
			chr += "-";
		}

		//add the character to the GUID
		g += chr;

		//comment out old
		//g += Math.floor(Math.random() * 0xF).toString(0xF) + (i == 8 || i == 12 || i == 16 || i == 20 ? "-" : "");
	}
	return g;

	//}
};




/**********************************************************
Enter Postback Functions
**********************************************************/
//move to base tools...
function IsEnterKey(localEvent)
{
	///	<summary>
	/// Determines if the enter key was pressed.
	///	</summary>
	///	<param name="localEvent" type="event"> the local event (event)</param>
	/// <returns type="bool">flag indicating whether or not the key is the enter key</returns>
	if (navigator.appName == "Netscape" && parseInt(navigator.appVersion) >= 4)
	{
		if (localEvent.which)
		{
			return (localEvent.which == 13)
		}
		else
		{
			return false;
		}
	}
	else
	{
		if (!localEvent)
		{
			localEvent = window.event;
		}
		return (localEvent.keyCode == 13);
	}
};

function EKH(localEvent, element)
{
	///	<summary>
	///	Enter key hit, base function for directing an enter key pressed event on an input element or other form element.
	///	</summary>
	///	<param name="localEvent" type="event"> the local event (event)</param>
	///	<param name="hyperLink" type="string"> to append the additional element names to.</param>
	/// <param name="element" type="string"> to focus on when the enter key is hit.</param>
	/// <returns type="bool">Shortcut method to determine if the enter key has been pressed</returns>
	
	if (IsEnterKey(localEvent))
	{
		FormTools.FocusAndClickElementUsingSetTimeout(element);
		return false;
	}

	return true;
};






/**********************************************************
Context Help Functions
**********************************************************/
var metafuseBaseShowHelpFromDelayShowHelp = null;
function DSHlp(localEvent, helpText, helpWidth)
{
	///	<summary>
	/// Delayed version of showing context help for form labels dynmically in the default help layer.   Short method to help with output.
	///	</summary>
	///	<param name="localEvent" type="event"> the local event (event)</param>
	///	<param name="helpText" type="string"> help text to show in the layer.</param>
	///	<param name="helpWidth" type="int"> optional parameter defining the width of the layer.</param>
	/// <returns type="void" />

	if (!localEvent)
	{
		return false;
	}
	if (helpText != "")
	{
		//copied from show Div and IFrame At Event
		var x;
		var y;


		//get event coordinates
		if (navigator.appName == "Netscape" && parseInt(navigator.appVersion) >= 4)
		{
			x = localEvent.pageX;
			y = localEvent.pageY;
		}
		else
		{
			x = event.clientX + document.body.scrollLeft;
			y = event.clientY + document.body.scrollTop;
		}

		x = x + 20;

		y = y + 20;

		//MetafuseBase_ShowContextHelp

		var timestamp = new Date().valueOf();

		metafuseBaseShowHelpFromDelayShowHelp = timestamp;
		//UITools.ShowDivAndIFrameAtEvent(localEvent, contextHelp, UITools.GetElementShim("ContextHelp_MetafuseBase_Div"), offsetX, offsetY);

		//return this.ShowDivAndIFrameAtXY(x, y, divElement, iframe, offsetX, offsetY);

		//alert(helpText);
		setTimeout("MetafuseBase_ShowContextHelp(" + x + "," + y + ",'" + helpText.split("'").join("\\'") + "'," + helpWidth + ", '" + timestamp + "')", 750);
	}

};

//show context help
function SHlp(localEvent, helpText, helpWidth, offsetX, offsetY)
{
	///	<summary>
	/// Shows context help for form labels dynmically in the default help layer.   Short method to help with output.
	///	</summary>
	///	<param name="localEvent" type="event"> the local event (event)</param>
	///	<param name="helpText" type="string"> help text to show in the layer.</param>
	///	<param name="helpWidth" type="int"> optional parameter defining the width of the layer.</param>
	///	<param name="offsetX" type="int"> optional parameter defining the offset X from the event to show the layer.</param>
	///	<param name="offsetY" type="int"> optional parameter defining the offset Y from the event to show the layer.</param>
	/// <returns type="void" />

	if (helpText != "")
	{
	
		//copied from show Div and IFrame At Event
		var x;
		var y;


		//get event coordinates
		if (navigator.appName == "Netscape" && parseInt(navigator.appVersion) >= 4)
		{
			x = localEvent.pageX;
			y = localEvent.pageY;
		}
		else
		{
			x = event.clientX + UITools.GetScrollLeft(); //document.body.scrollLeft;
			y = event.clientY + UITools.GetScrollTop(); //document.body.scrollTop; //STW 2009-12-23 Fixes IE8 Bug with XHTML getting the wrong scroll top
		}

		x = x + 20;

		y = y + 20;

		
		//call the common base method for showing help
		MetafuseBase_ShowContextHelp(x, y, helpText, helpWidth);

		//UITools.ShowDivAndIFrameAtEvent(localEvent, contextHelp, UITools.GetElementShim("ContextHelp_MetafuseBase_Div"), offsetX, offsetY);
	}

};

function MetafuseBase_ShowContextHelp(x, y, helpText, helpWidth, timestamp)
{
	///	<summary>
	/// Internal method for showing the context help the "help" for form labels dynmically in the default help layer.  Use the short method SHlp.
	///	</summary>
	///	<param name="x" type="int"> The offset X from the event to show the layer.</param>
	///	<param name="y" type="int"> The offset Y from the event to show the layer.</param>
	///	<param name="helpText" type="string"> help text to show in the layer.</param>
	///	<param name="helpWidth" type="int"> optional parameter defining the width of the layer.</param>
	///	<param name="timestamp" type="Date"> parameter used for the "delay" to make sure to not show the same layer twice.</param>
	/// <returns type="bool">flag indicating whether or not the context was shown</returns>

	if (timestamp != null && metafuseBaseShowHelpFromDelayShowHelp != timestamp)
	{
		return false;
	}

	if (helpText != "")
	{
		var contextHelp = GetElementById("ContextHelp_MetafuseBase_Div");
		//contextHelp.style.width = null;
		

		if (contextHelp == null)
		{
			InsertHTML('<div id="ContextHelp_MetafuseBase_Div" class="ContextHelp" style="position: absolute; z-index: 20000;display:none;width:300px;"></div>');
			contextHelp = GetElementById("ContextHelp_MetafuseBase_Div");
		}
		var helpHtml;
		if (helpWidth)
		{
			helpHtml = "<table width=\"" + helpWidth + "\"><tr><td>" + helpText + "</td></tr></table>";
		}
		else
		{
			helpHtml = "<table><tr><td>" + helpText + "</td></tr></table>";
		}
		contextHelp.innerHTML = helpHtml;

		UITools.ShowDivAndIFrameAtXY(x, y, contextHelp);

		//make sure the context width isn't too wide
		if (helpWidth == null || helpWidth <= 0)
		{
			if (contextHelp.firstChild.offsetWidth >= 300)
			{

				contextHelp.style.width = 300 + 'px';

				var shim = UITools.GetElementShim("ContextHelp_MetafuseBase_Div");
				if (shim)
				{
					shim.style.width = 300 + 'px';
				}

			}
			else
			{

				//make sure the outer div is also equal to the inside and then the shim
				contextHelp.style.width = contextHelp.firstChild.offsetWidth + 'px';

				//contextHelp.style.width = null;
				var shim = UITools.GetElementShim("ContextHelp_MetafuseBase_Div");
				if (shim)
				{

					shim.style.width = contextHelp.firstChild.offsetWidth + 'px';
				}

			}
		}
		else
		{

			//make sure the outer div is also equal to the inside and then the shim
			contextHelp.style.width = contextHelp.firstChild.offsetWidth + 'px';

			//contextHelp.style.width = null;
			var shim = UITools.GetElementShim("ContextHelp_MetafuseBase_Div");
			if (shim)
			{

				shim.style.width = contextHelp.firstChild.offsetWidth + 'px';
			}
		}

	}
	return true;
};


//hide context help
function HHlp()
{
	///	<summary>
	/// Hides the context help.
	///	</summary>
	/// <returns type="void" />
	metafuseBaseShowHelpFromDelayShowHelp = null;
	var contextHelp = GetElementById("ContextHelp_MetafuseBase_Div");
	if (contextHelp)
	{
		UITools.HideDivAndIFrame(GetElementById("ContextHelp_MetafuseBase_Div"), UITools.GetElementShim("ContextHelp_MetafuseBase_Div"));
	}
};











/***********************************************************************
* 
*/
//parses the string testing for 1 or 0 to return, otherwise returns the supplied value
//USED IN MetafuseTableColumnSelector.
function ParseBoolValueFromShortString(s)
{
	///	<summary>
	///	 DEPRECATED
	///	</summary>
	if (s)
	{
		if (s.toString() == "1")
		{
			return true;
		}
		else if (s.toString() == "0")
		{
			return false;
		}
	}
	return s;
};


/***********************************************************************
* Numbers and Other Items
*************************************************************************/
//TO DEPRICATE -- Ensures whole number entered into the system replacing
function EnsureWholeNumber(element)
{
	///	<summary>
	///	 DEPRECATED
	///	</summary>

	element = GetElementById(element);
	if (element)
	{
		var elementId = element.id;


		var v = new Number();
		v = parseFloat(element.value);
		v = Round(v, 0);

		if (v.toString() == "NaN")
		{
			SetValueUsingSetTimeout(elementId, "");


		}
		else if (v < 0)
		{
			var absNumber = Math.abs(v);
			SetValueUsingSetTimeout(elementId, absNumber.toString());

		}
		else if (v.toString() != element.value.toString())
		{
			SetValueUsingSetTimeout(elementId, v.toString());
		}
	}
};
//TO DEPRICATE //ensures positive decimal to specified decimal places (default = 2)
function EnsurePositiveDecimal(element, decimalPlaces, setNanToZero)
{
	///	<summary>
	///	 DEPRECATED
	///	</summary>
	element = GetElementById(element);
	if (element)
	{
		var elementId = element.id;

		if (!decimalPlaces)
		{
			decimalPlaces = 2;
		}

		var v = new Number();
		v = parseFloat(element.value);

		if (v.toString() == "NaN")
		{
			if (setNanToZero)
			{
				SetValueUsingSetTimeout(elementId, "0");
			}
			else
			{
				SetValueUsingSetTimeout(elementId, "");
			}
			return;
		}

		v = Round(v, decimalPlaces, true);

		if (v < 0)
		{
			var roundedValue = Round(Math.abs(v), decimalPlaces, true);
			SetValueUsingSetTimeout(elementId, roundedValue.toString());
		}
		else if (v.toString() != element.value.toString())
		{
			SetValueUsingSetTimeout(elementId, v.toString());
		}
	}
};






//determines if a number is even or odd



/*************************************************************************
Basic Object Manipulation Functions
**************************************************************************/
function isAlien(a) { return isObject(a) && typeof a.constructor != 'function'; };
function isArray(a) { return isObject(a) && a.constructor == Array; };
function isBoolean(a) { return typeof a == 'boolean'; };
function isFunction(a) { return typeof a == 'function'; };
function isNull(a) { return typeof a == 'object' && !a; };
function isNumber(a) { return typeof a == 'number' && isFinite(a); };
function isObject(a) { return ((a != null) && typeof a == 'object') || isFunction(a); };
function isString(a) { return typeof a == 'string'; };
function isUndefined(a) { return typeof a == 'undefined'; };
function isEmpty(o)
{
	var i, v;
	if (isObject(o))
	{
		for (i in o)
		{
			v = o[i];
			if (isUndefined(v) && isFunction(v))
			{
				return false;
			}
		}
	}
	return true;
};
function isDefined(v)
{
	///	<summary>
	///	Determines if an object is defined by the window hashtable   
	///	</summary>
	///	<param name="v" type="string"> object name to determine if is defined or not</param>
	/// <returns type="bool">flag indicating whether or not the string is a defined javascript object.</returns>


	if (typeof (window[v.toString()]) != "undefined")
	{
		return true;
	}
	//else if(typeof (document[v.toString()]) != "undefined")
	//{
	//	return true;
	//}
	//alert(typeof (document[v.toString()]));
	return false;
};










//inserts html into the document body x-browser //move to UITools


//move to UITools...
function UpdateOuterHTML(elementId, outerHTML, insertElementIfNonExistent, outerElementId)
{
	///	<summary>
	///	 Updates the outer HTML of the supplied element
	///	</summary>
	///	<param name="elementId" type="string"> id or element to update the outer HTML.</param>
	///	<param name="outerHTML" type="string"> HTML to set as the outer HTML.</param>
	///	<param name="insertElementIfNonExistent" type="bool"> flag indicating whether or not the insert the element into the DOM if it does not exist (default false).</param>
	///	<param name="outerElementId" type="string"> optional id or element which is a potential outer id, or alternative for the ID.  If set the method looks for the presence of the outer element to replace it instead of the inner element id.</param>
	/// <returns type="void" />


	var element = GetElementById(elementId);
	var outerElement = null;
	if (outerElementId)
	{
		outerElement = GetElementById(outerElementId);

		if (outerElement)
		{
			element = outerElement;

		}
	}


	if (element != null)
	{
		if (element.nodeName != null && element.nodeName == "TR")
		{
			alert("You cannot replace the outerHTML of a table row");
		}
		else
		{

			if (document.all)
			{
				try
				{
					element.outerHTML = outerHTML;
				}
				catch (e)
				{
					alert("Unable to update the outer HTML for the element supplied " + elementId + ".  The error message will be dumped");
					__Dump(e);
				}
			}
			else
			{

				var $element = $(element);
				try
				{
					$element.replaceWith(outerHTML);
				}
				catch (e)
				{
					alert("Unable to update the outer HTML for the element supplied " + elementId + ".  The error message will be dumped");
					__Dump(e);
				}

				/*
				//element.outerHTML = outerHTML;
				//alert(element);

				try
				{


					
				var tmpElement = document.createElement("DIV");
				tmpElement.style.display = "none";
				element.parentNode.insertBefore(tmpElement, element);
				element.parentNode.removeChild(element);
				tmpElement.innerHTML = outerHTML;
					
				var firstChild = null;
				alert(tmpElement.childNodes.length);

				for(var i = 0; i < tmpElement.childNodes.length; i++)
				{
				firstChild = tmpElement.childNodes[i];
						
				if(firstChild.nodeType == 1)
				{
				break;
				}
				}

				if(firstChild.nodeType == 1)
				{
				tmpElement.parentNode.insertBefore(firstChild, tmpElement);
				tmpElement.parentNode.removeChild(tmpElement);
				}
					
					
					
				}
				catch(e)
				{
				alert("Unable to update the outer HTML for the element supplied " + elementId + ".  The error message will be dumped");
				__Dump(e);
				}
				*/


			}

		}
	}
	//insert the HTML if it is not there
	else if (insertElementIfNonExistent)
	{
		UITools.InsertHTML(outerHTML);
	}

};

//gets the HTML recursively for an element
//MOVE TO UI TOOLS
function GetInnerHTMLRecursive(element)
{
	///	<summary>
	///	MAY NOT BE SUPPORTED Gets all of the inner HTML as a string of all child nodes of the supplied element
	///	</summary>
	///	<param name="elementId" type="string"> id or element to get the innerHTML.</param>
	///	<param name="outerElementId" type="string"> optional id or element which is a potential outer id, or alternative for the ID.  If set the method looks for the presence of the outer element to replace it instead of the inner element id.</param>
	/// <returns type="string"> inner HTML of all inner child nodes</returns>

	var html = "";

	element = GetElementById(element);

	if (element != null)
	{
		if (element.outerHTML)
		{
			html = element.innerHTML + "\n\n\n";


			if (element.childNodes != null)
			{

				for (var i = 0; i < element.childNodes.length; i++)
				{
					var cn = element.childNodes[i];
					html += GetInnerHTMLRecursive(cn);
				}


			}
		}

	}
	return html;

};


//adds an event handler to an element (like mouse down/mouse up)
function AddEventHandlerToElement(element, eventName, eventMethod, useCapture)
{
	///	<summary>
	///	Adds an event handler to an element.  Cross browser supported.
	///	</summary>
	///	<param name="element" type="string"> id or element to apply the method to.</param>
	///	<param name="eventName" type="string"> name of the event to apply to (like click or mouseover).</param>
	///	<param name="eventMethod" type="function"> function to be invoked.</param>
	///	<param name="useCapture" type="bool"> flag indicating whether or ot to use the capture method when applying (default false)</param>
	/// <returns type="bool"> flag indicating success of applying the event handler</returns>

	element = GetElementById(element);

	//switch the order 2011-07-19 STW because it was failing on detach in IE9
	if (element.attachEvent)
	{
		return element.attachEvent(eventName, eventMethod);
	}
	else if (element.addEventListener)
	{
		if (useCapture == null)
		{
			useCapture = false;
		}
		element.addEventListener(eventName.replace("on", ""), eventMethod, useCapture);
		return true;
	}


	return false;
};
//adds an event handler to an element (like mouse down/mouse up)
function RemoveEventHandlerFromElement(element, eventName, eventMethod, useCapture)
{
	///	<summary>
	///	Removes an event handler to an element.  Cross browser supported.
	///	</summary>
	///	<param name="element" type="string"> id or element to remove the method from to.</param>
	///	<param name="eventName" type="string"> name of the event to apply to (like click or mouseover).</param>
	///	<param name="eventMethod" type="function"> function to be invoked which will be removed.</param>
	///	<param name="useCapture" type="bool"> flag indicating whether or ot to use the capture method when applying</param>
	/// <returns type="bool"> flag indicating success of removing the event handler</returns>

	element = GetElementById(element);

	//switch the order 2011-07-19 STW because it was failing on detach in IE9
	if (element.detachEvent)
	{
		return element.detachEvent(eventName, eventMethod);
	}
	else if (element.removeEventListener)
	{
		element.removeEventListener(eventName.replace("on", ""), eventMethod, useCapture);
		return true;
	}


	return false;
};




//delay javascript execution in milliseconds
//THIS MAY BE ABLE TO BE DEPRICATED
function Delay(milliseconds)
{
	///	<summary>
	///	TO BE DEPRECATED, or MOVED
	///	</summary>
	d = new Date() //today's date
	while (1)
	{
		mill = new Date() // Date Now
		diff = mill - d //difference in milliseconds
		if (diff > milliseconds)
		{
			break;
		}
	}
};

//CAN THIS BE DEPRICATED?? ADDED TO FORM TOOLS??
function MenuConfirmAndPostBack(confirmMessage, target, args)
{
	///	<summary>
	///	TO BE DEPRECATED, or MOVED
	///	</summary>
	if (confirm(confirmMessage))
	{
		__doPostBack(target, args);
	}

};

/***************************
*Row Highlighting for table row -- keep global
***************************/
function HOn(element, arrayOfAdditionalRows)
{
	///	<summary>
	///	Short cut row highlight method.  Preferred method for row hightlight outside of the MetafuseTable built in function.  On MetafuseTable use builtin function obj.H(this);
	///	</summary>
	///	<param name="element" type="string"> id or row element to highlight.</param>
	///	<param name="arrayOfAdditionalRows" type="Array"> of additional row ids to apply the highlight.</param>
	/// <returns type="void"></returns>

	if (element)
	{

		//var arrayOfAdditionalToReset = null;

		//if(arrayOfAdditionalRows)
		//{
		//arrayOfAdditionalToReset = new Array();

		//for(var i = 0; i < arrayOfAdditionalRows.length; i++)
		//{
		//var row = GetElementById(arrayOfAdditionalRows[i]);

		//if (row)
		//{

		//	var object = new Object();
		//	object.id = row.id;
		//	object.className = row.className;
		//	arrayOfAdditionalToReset[i] = object;

		//}
		//else
		//{
		//	arrayOfAdditionalToReset[i] = null;
		//}

		//}
		//}

		var element = GetElementById(element);
		if (element)
		{
			var className = element.className;

			if (element.onmouseout == null)
			{
				element.onmouseout = function ()
				{

					//element.className = className;
					element.onmouseout = null;

					//remove all of the row highlights
					element.className = element.className.replace(/ RowHighlight/gi, "");
					element.className = element.className.replace(/ RowHighlightT/gi, "");
					element.className = element.className.replace(/ RowHighlightM/gi, "");
					element.className = element.className.replace(/ RowHighlightB/gi, "");



					if (arrayOfAdditionalRows)
					{
						for (var i = 0; i < arrayOfAdditionalRows.length; i++)
						{

							var row = GetElementById(arrayOfAdditionalRows[i]);

							if (row)
							{
								row.onmouseout = null;
								row.className = row.className.replace(/ RowHighlight/gi, "");
								row.className = row.className.replace(/ RowHighlightT/gi, "");
								row.className = row.className.replace(/ RowHighlightM/gi, "");
								row.className = row.className.replace(/ RowHighlightB/gi, "");
							}

							//var object = arrayOfAdditionalToReset[i];

							//if (object)
							//{
							//	var row = GetElementById(object.id);
							//	if (row)
							//	{
							//		row.className = object.className;
							//	}
							//}
						}
					}
				};
			};

			if (element.className.indexOf(" RowHighlight") < 0)
			{
				element.className += " RowHighlight";
			}

			if (arrayOfAdditionalRows)
			{
				for (var i = 0; i < arrayOfAdditionalRows.length; i++)
				{
					var row = GetElementById(arrayOfAdditionalRows[i]);

					if (row)
					{

						row.className += " RowHighlight";
						if (row.onmouseout == null)
						{
							row.onmouseout = element.onmouseout;
						}
					}
				}
			}
		}

	}
};


//Preferred method is HOn this method performs a similar function using positions instead of offset
//Hover Highlight On with Multiple Rows
function HOnM(element, numberOfRowsBefore, numberOfRowsAfter)
{
	///	<summary>
	/// Alternative method for row hightlight using a count of rows before or after the supplied row.  Not the preferred method, use HOn if possible first.
	///	</summary>
	///	<param name="element" type="string"> id or row element to highlight.</param>
	///	<param name="numberOfRowsBefore" type="int"> number of rows before the supplied row to highlight.</param>
	///	<param name="numberOfRowsAfter" type="int"> number of rows after the supplied row to highlight.</param>
	/// <returns type="void"></returns>


	if ((numberOfRowsBefore == null && numberOfRowsAfter == null) || (numberOfRowsBefore == 0 && numberOfRowsAfter == 0))
	{
		HOn(element);
	}
	else
	{
		var className = element.className;

		var additionalRows = new Array();
		var additionalRowsClassName = new Array();
		var rowIndex = 0;

		var previousSibling = GetPreviousSibling(element);
		var t = previousSibling.tagName;

		for (var i = 1; i <= numberOfRowsBefore; i++)
		{
			additionalRows[rowIndex] = previousSibling;
			additionalRowsClassName[rowIndex] = previousSibling.className;
			rowIndex++;

			previousSibling.className += " RowHighlight";

			previousSibling = GetPreviousSibling(previousSibling);
		}

		var nextSibling = GetNextSibling(element);

		for (var k = 1; k <= numberOfRowsAfter; k++)
		{
			additionalRows[rowIndex] = nextSibling;
			additionalRowsClassName[rowIndex] = nextSibling.className;
			rowIndex++;

			nextSibling.className += " RowHighlight";
			nextSibling = GetNextSibling(nextSibling);
		}

		if (element.onmouseout == null)
		{
			element.onmouseout = function () { element.className = className; element.onmouseout = null; for (var j = 0; j < rowIndex; j++) { additionalRows[j].className = additionalRowsClassName[j]; } };
		}

		element.className += " RowHighlight";
	}

};

function GetPreviousSibling(element)
{
	///	<summary>
	/// Gets the previous sibling, which is NOT a text node (nodeType==1) for the supplied element.
	///	</summary>
	///	<param name="element" type="element"> element to obtain the previous sibling (cannot use ID)</param>
	/// <returns type="element"> which is the previous sibling</returns>


	if (element.previousSibling == null)
	{
		return null;
	}
	if (element.previousSibling.nodeType == 1)
	{
		return element.previousSibling;
	}
	return GetPreviousSibling(element.previousSibling);
};
function GetNextSibling(element)
{
	///	<summary>
	/// Gets the next sibling, which is NOT a text node (nodeType==1) for the supplied element.
	///	</summary>
	///	<param name="element" type="element"> element to obtain the next sibling (cannot use ID)</param>
	/// <returns type="element"> which is the next sibling</returns>

	if (element.nextSibling == null)
	{
		return null;
	}
	if (element.nextSibling.nodeType == 1)
	{
		return element.nextSibling;
	}
	return GetNextSibling(element.nextSibling);
};


//Update class
function UC(element, className)
{
	///	<summary>
	/// TO BE DEPRECATED??
	///	</summary>


	if (className == null)
	{
		className = "";
	}
	element.className = className;
};
//hover over element
function HOf(element, className)
{
	///	<summary>
	/// TO BE DEPRECATED??
	///	</summary>


	UC(element, className);
};



/***************************************
TO DEPRICATE -- DHTML Select List Methods -- MOVE TO AJAX TOOLS AND REPLACE
****************************************/
function DHTMLSelectListDisplayLoading(selectElement, keepSelected)
{
	///	<summary>
	/// DEPRECATED!
	///	</summary>
	selectElement = GetElementById(selectElement);
	if (selectElement)
	{
		SelectOptionsClear(selectElement, keepSelected);

		if (selectElement.options.length == 1)
		{
			selectElement.options[0].text = "Loading...";
		}
		else
		{
			selectElement.options[0] = new Option("Loading...", "");
		}
	}
};
function DHTMLSelectListDisplayNoneSelected(selectElement, noneSelectedString)
{
	///	<summary>
	/// DEPRECATED!
	///	</summary>
	selectElement = GetElementById(selectElement);
	if (selectElement)
	{
		if (!noneSelectedString)
		{
			noneSelectedString = "None Selected";
		}

		SelectOptionsClear(selectElement);
		selectElement.options[selectElement.options.length] = new Option(noneSelectedString, "");
	}
};
//to be depricated use UpdateSelectOptions
function DHTMLSelectListPopulateSelect(selectElement, selectListArray)
{
	///	<summary>
	/// DEPRECATED!
	///	</summary>
	selectElement = GetElementById(selectElement);
	if (selectElement)
	{
		SelectOptionsClear(selectElement);

		if (selectListArray)
		{
			for (var i = 0; i < selectListArray.length; i++)
			{
				var e = selectListArray[i];
				var o = new Option(e.Text, e.Value);

				if (e.Selected == "true")
				{
					o.selected = true;
				}
				selectElement.options[selectElement.options.length] = o;
			}
		}
	}
};






/****************************************************************************************
Namespace objects to hold various functions for javascript
*****************************************************************************************/
//constructor for the math tools used for doing math related functions
function MathTools()
{

	///	<summary>
	/// Global math tools object contains the basic functions for handling math
	///	</summary>
	///	<field name="CurrencySymbol" type="string"> symbol for the currency (default "$")</field>
	///	<field name="CurrencySymbolAtEnd" type="bool"> flag indicating whether or not the currency symbol is at the end of the string (default false)</field>
	///	<field name="CurrencyCommaDecimalReversed" type="bool"> flag indicating whether or not the comma and decimals are reversed for the currency format (default false)</field>

	///	<field name="CurrencyScale" type="int"> scale of the currency (default 2)</field>
	///	<field name="CurrencyExcludeCommas" type="bool"> flag indicating whether or not to exclude the commas from currency $1,243.23 (default false)</field>
	///	<field name="CurrencyExcludeLeadingZero" type="bool"> flag indicating whether or not to include leading zeros in front of decimal place (default false)</field>
	///	<field name="CurrencyExcludeTrailingZeros" type="bool"> flag indicating whether or not the include trailing zeros after the decimal place (default false)</field>

	///	<field name="DecimalScale" type="int"> scale of the decimal (default 2)</field>
	///	<field name="DecimalExcludeCommas" type="bool"> flag indicating whether or not to exclude the commas from decimals 1,243.23 (default false)</field>
	///	<field name="DecimalExcludeLeadingZero" type="bool"> flag indicating whether or not to include leading zeros in front of decimal place (default false)</field>
	///	<field name="DecimalExcludeTrailingZeros" type="bool"> flag indicating whether or not the include trailing zeros after the decimal place (default false)</field>

	///	<field name="DecimalCommaAndDecimalReversed" type="bool"> flag indicating whether or not the comma and decimals are reversed for the decimal format (default false)</field>

	///	<field name="PercentScale" type="int"> scale of the percent (default 2)</field>
	///	<field name="PercentExcludeLeadingZero" type="bool"> flag indicating whether or not to include leading zeros in front of decimal place (default false)</field>
	///	<field name="PercentExcludeTrailingZeros" type="bool"> flag indicating whether or not the include trailing zeros after the decimal place (default false)</field>


	//default currency formatting settings (can be overridden by function calls)
	this.CurrencySymbol = "$" // British Pound = String.fromCharCode(163); 
	this.CurrencySymbolAtEnd = false;
	this.CurrencyCommaDecimalReversed = false;

	this.CurrencyScale = 2;
	this.CurrencyExcludeCommas = false;
	this.CurrencyExcludeLeadingZero = false;
	this.CurrencyExcludeTrailingZeros = false;

	//default decimal settings (can be overridden by function calls)
	this.DecimalScale = 2;
	this.DecimalExcludeCommas = false;
	this.DecimalExcludeLeadingZero = false;
	this.DecimalExcludeTrailingZeros = false;

	this.DecimalCommaAndDecimalReversed = false;

	//default percent settings (can be overridden by function calls)
	this.PercentScale = 2;
	this.PercentExcludeLeadingZero = false;
	this.PercentExcludeTrailingZeros = false;



	//determines whether or not a string is numeric so it can be converted to a number successfully
	this.IsNumeric = function (inputString)
	{
		///	<summary>
		/// Determines if the input string is numeric
		///	</summary>
		///	<param name="inputString" type="string"> input string to determine if is numeric.</param>
		/// <returns type="bool"> flag indicating whether or not the supplied string is numeric</returns>

		var sNumber;
		var fNumber;
		if (inputString != null)
		{
			sNumber = inputString.toString();
			fNumber = parseFloat(inputString);
			if (sNumber == fNumber && fNumber != Number.POSITIVE_INFINITY && fNumber != Number.NEGATIVE_INFINITY)
			{
				return true;
			}
		}
		return false;
	};


	//this formats the string into a decimal string with the following options
	this.FormatDecimalString = function (stringValue, returnEmptyStringWhenNaN, excludeCommas, excludeLeadingZero, excludeTrailingZeros, scale, positiveOnly, commaAndDecimalReversed)
	{
		///	<summary>
		/// Formats the supplied string into the decimal string.
		///	</summary>
		///	<param name="stringValue" type="string"> string to format as a decimal.</param>
		///	<param name="returnEmptyStringWhenNaN" type="bool"> flag indicating whether or not to return an empty string rather than 0, when the input is not a number.</param>
		///	<param name="returnEmptyStringWhenNaN" type="bool"> flag indicating whether or not to exclude commas, if null, then takes the default set on the object</param>
		///	<param name="excludeLeadingZero" type="bool"> flag indicating whether or not to exclude leading zeros, if null, then takes the default set on the object.</param>
		///	<param name="excludeTrailingZeros" type="bool"> flag indicating whether or not to exclude trailing zeros, if null, then takes the default set on the object.</param>
		///	<param name="scale" type="int"> scale of the number (number of decimal places), if null, then takes the default set on the object.</param>
		///	<param name="positiveOnly" type="bool"> whether or not the number should be positive only (absolute value).</param>
		///	<param name="commaAndDecimalReversed" type="bool"> flag indicating whether or not the comma and decimal is reversed, if null, then takes the default set on the object.</param>
		/// <returns type="string"> formatted as a decimal</returns>


		if (excludeCommas == null)
		{
			excludeCommas = this.DecimalExcludeCommas;
		}
		if (excludeLeadingZero == null)
		{
			excludeLeadingZero = this.DecimalExcludeLeadingZero;
		}
		if (excludeTrailingZeros == null)
		{
			excludeTrailingZeros = this.DecimalExcludeTrailingZeros;
		}
		if (scale == null)
		{
			scale = this.DecimalScale;
		}

		//determine if the commaAndDecimal are reversed for decimals
		if (commaAndDecimalReversed == null)
		{
			commaAndDecimalReversed = this.DecimalCommaAndDecimalReversed;
		}


		//parse the float to make sure it's a number
		var decimalValue = this.ParseFloat(stringValue, true, commaAndDecimalReversed);

		if (decimalValue == null)
		{
			if (returnEmptyStringWhenNaN)
			{
				return "";
			}
			else
			{
				decimalValue = 0;
			}
		}


		//round the number to the appropriate scale
		//Already converted to a decimal value, so don't reconvert it.
		decimalValue = this.Round(decimalValue, scale, commaAndDecimalReversed);


		//put the decimal value into a string for formatting
		var decimalString = new String(decimalValue.toString());


		//if there isn't a decimal place in the string then put one on the end

		if (decimalString.indexOf(".") < 0)
		{
			decimalString += ".";
		}


		//split the string into 2 parts
		var decimalStringArray = decimalString.split(".");

		//set the left side of the string
		var decimalLeftSide = new String(decimalStringArray[0]);
		//set the right side of the string
		var decimalRightSide = new String(decimalStringArray[1]);
		//setup the decimal sign
		var decimalSign = new String("");

		//if a negative number strip the negative sign off temporarily
		if (decimalValue < 0)
		{
			if (!positiveOnly)
			{
				decimalSign = "-";
			}
			decimalLeftSide = decimalLeftSide.replace("-", "");
		}



		if (scale > 0 && decimalValue < 1 && decimalValue > -1)
		{
			if (excludeLeadingZero)
			{
				if (decimalValue > 0)
				{
					decimalLeftSide = "";
				}
				else
				{
					decimalLeftSide = "-";
				}
			}
			else if (decimalLeftSide.length == 0)
			{
				decimalLeftSide = "0";
			}
		}



		//if we aren't excluding the commas then we need to include them back in
		if (!excludeCommas && (decimalValue >= 1000 || decimalValue <= -1000))
		{

			var start = decimalLeftSide.length;
			start -= 3;

			while (start >= 1)
			{
				decimalLeftSide = decimalLeftSide.substring(0, start) + "," + decimalLeftSide.substring(start, decimalLeftSide.length)
				start -= 3;
			}
		}

		//if the scale is greater than zero then we need to include the trailing zeros
		if (!excludeTrailingZeros && scale > 0 && decimalRightSide.length < scale)
		{
			//add the trailing zeros
			for (var i = decimalRightSide.length; i < scale; i++)
			{
				decimalRightSide += "0";
			}
		}



		var returnDecimalString = new String(decimalLeftSide);

		if (decimalRightSide.length > 0)
		{
			returnDecimalString = decimalLeftSide + "." + decimalRightSide;
		}


		//if the comma and decimal are reversed, then we need to swap the values
		if (commaAndDecimalReversed)
		{
			//swap out periods and commas

			if (!excludeCommas)
			{
				//replace the period with a pipe
				returnDecimalString = returnDecimalString.replace(".", "|");
				//replace the commas with a period
				returnDecimalString = returnDecimalString.replace(",", ".");
				//replaec the piple with a comma
				returnDecimalString = returnDecimalString.replace("|", ",");
			}
			else
			{
				//replace the period with a comma
				returnDecimalString = returnDecimalString.replace(".", ",");
			}
		}



		return decimalSign + returnDecimalString;


	};


	//formats the string into currency
	this.FormatCurrencyString = function (numberString, returnEmptyStringWhenNaN, excludeCommas, excludeLeadingZero, excludeTrailingZeros, scale, positiveOnly, currencySymbol, currencySymbolAtEnd, currencyCommaDecimalReversed)
	{
		///	<summary>
		/// Formats the supplied string into the currency string.
		///	</summary>
		///	<param name="stringValue" type="string"> string to format as a currency.</param>
		///	<param name="returnEmptyStringWhenNaN" type="bool"> flag indicating whether or not to return an empty string rather than 0, when the input is not a number.</param>
		///	<param name="returnEmptyStringWhenNaN" type="bool"> flag indicating whether or not to exclude commas, if null, then takes the default set on the object</param>
		///	<param name="excludeLeadingZero" type="bool"> flag indicating whether or not to exclude leading zeros, if null, then takes the default set on the object.</param>
		///	<param name="excludeTrailingZeros" type="bool"> flag indicating whether or not to exclude trailing zeros, if null, then takes the default set on the object.</param>
		///	<param name="scale" type="int"> scale of the number (number of decimal places), if null, then takes the default set on the object.</param>
		///	<param name="positiveOnly" type="bool"> whether or not the number should be positive only (absolute value).</param>
		///	<param name="currencySymbol" type="string">the currency symbol, if null, then takes the default set on the object.</param>
		///	<param name="currencySymbolAtEnd" type="bool"> flag indicating whether or not the currency symbol is at the end of the string, if null, then takes the default set on the object.</param>
		///	<param name="currencyCommaDecimalReversed" type="bool"> flag indicating whether or not the comma and decimal is reversed, if null, then takes the default set on the object.</param>
		/// <returns type="string"> formatted as a currency</returns>


		if (excludeCommas == null)
		{
			excludeCommas = this.CurrencyExcludeCommas;
		}
		if (excludeCommas == null)
		{
			excludeCommas = this.CurrencyExcludeCommas;
		}
		if (excludeLeadingZero == null)
		{
			excludeLeadingZero = this.CurrencyExcludeLeadingZero;
		}
		if (excludeTrailingZeros == null)
		{
			excludeTrailingZeros = this.CurrencyExcludeTrailingZeros;
		}
		if (scale == null)
		{
			scale = this.CurrencyScale;

		}

		if (currencyCommaDecimalReversed == null)
		{
			currencyCommaDecimalReversed = this.CurrencyCommaDecimalReversed;
		}

		//get currency formatted as a decimal first
		var decimalString = this.FormatDecimalString(numberString, returnEmptyStringWhenNaN, excludeCommas, excludeLeadingZero, excludeTrailingZeros, scale, positiveOnly, currencyCommaDecimalReversed);

		if (decimalString == "")
		{
			return decimalString;
		}


		//now format the decimal as currency with the preferences
		if (currencySymbol == null)
		{
			currencySymbol = this.CurrencySymbol;
		}
		if (currencySymbolAtEnd == null)
		{
			currencySymbolAtEnd = this.CurrencySymbolAtEnd;
		}



		var symbolStart = currencySymbol;
		var symbolEnd = "";

		if (currencySymbolAtEnd)
		{
			symbolStart = "";
			symbolEnd = currencySymbol;
		}

		var negativeSign = "";
		if (decimalString.indexOf("-") >= 0)
		{
			negativeSign = "-";
			decimalString = decimalString.replace("-", "");
		}


		/* moved to FormatDecimalString 
		if(currencyCommaDecimalReversed)
		{
		//swap out periods and commas
			
		if(!excludeCommas)
		{
		//replace the period with a pipe
		decimalString = decimalString.replace(".","|");
		//replace the commas with a period
		decimalString = decimalString.replace(",",".");
		//replaec the piple with a comma
		decimalString = decimalString.replace("|",",");
		}
		else
		{
		//replace the period with a comma
		decimalString = decimalString.replace(".",",");
		}
		}
		*/

		return negativeSign + symbolStart + decimalString + symbolEnd;

	};

	//formats the string
	this.FormatPercentString = function (stringValue, returnEmptyStringWhenNaN, excludeLeadingZero, excludeTrailingZeros, scale)
	{

		///	<summary>
		/// Formats the supplied string into the percent string.
		///	</summary>
		///	<param name="stringValue" type="string"> string to format as a percent.</param>
		///	<param name="returnEmptyStringWhenNaN" type="bool"> flag indicating whether or not to return an empty string rather than 0, when the input is not a number.</param>
		///	<param name="returnEmptyStringWhenNaN" type="bool"> flag indicating whether or not to exclude commas, if null, then takes the default set on the object</param>
		///	<param name="excludeLeadingZero" type="bool"> flag indicating whether or not to exclude leading zeros, if null, then takes the default set on the object.</param>
		///	<param name="excludeTrailingZeros" type="bool"> flag indicating whether or not to exclude trailing zeros, if null, then takes the default set on the object.</param>
		///	<param name="scale" type="int"> scale of the number (number of decimal places), if null, then takes the default set on the object.</param>
		/// <returns type="string"> formatted as a percent</returns>


		if (excludeLeadingZero == null)
		{
			excludeLeadingZero = this.PercentExcludeLeadingZero;
		}
		if (excludeTrailingZeros == null)
		{
			excludeTrailingZeros = this.PercentExcludeTrailingZeros;
		}
		if (scale == null)
		{
			scale = this.PercentScale;
		}

		//parse the float to make sure it's a number
		var decimalValue = this.ParseFloat(stringValue, true);

		if (decimalValue < 0)
		{
			decimalValue = 0;
		}
		else if (decimalValue > 100)
		{
			decimalValue = 100;
		}

		decimalValue = this.FormatDecimalString(decimalValue, returnEmptyStringWhenNaN, true, excludeLeadingZero, excludeTrailingZeros, scale);

		return decimalValue.toString() + "%";

	};





	//parse the string into a valid float (if possible), returns 0 or null if NaN depending on returnNullWhenNaN
	this.ParseFloat = function (string, returnNullWhenNaN, commaAndDecimalReversed)
	{
		///	<summary>
		/// Parses the string into a float.  If the number is a number then the number is returned, otherwise it is converted into a number
		///	</summary>
		///	<param name="string" type="string"> string to parse into a float.</param>
		/// <param name="returnNullWhenNaN" type="bool"> flag indicating whether or not the return null when the number si not a number</param>
		/// <param name="commaAndDecimalReversed" type="bool"> flag indicating whether or not the comma and decimal is reversed, if null, then takes the default set on the object.</param>
		/// <returns type="float"> number</returns>

		if (string == null)
		{
			if (returnNullWhenNaN)
			{
				return null;
			}
			else
			{
				return 0;
			}
		}
		else if (isNumber(string))
		{
			return string;
		}
		else
		{

			var stringInput = string.toString();




			//determine if the commaAndDecimal are reversed for decimals
			if (commaAndDecimalReversed == null)
			{
				commaAndDecimalReversed = this.DecimalCommaAndDecimalReversed;
			}


			//if the comma and decimal is reversed we need to normalize it to US format before processing under US format
			if (commaAndDecimalReversed == true && stringInput && stringInput != "")
			{

				//if there is a period in front of the comma then we need to remove the periods
				if (stringInput.indexOf(".") < stringInput.indexOf(","))
				{
					//strip periods
					stringInput = stringInput.replace(".", "");
					//swap comma with periods (decimals)
					stringInput = stringInput.replace(",", ".");

				}
				//if there are no periods, but commas then we need to replace them (would normally only happen in
				else if (stringInput.indexOf(".") < 0 && stringInput.indexOf(",") >= 0)
				{
					//swap comma with periods (decimals)
					stringInput = stringInput.replace(",", ".");
				}



			}

			//Now strip the number down to just digits and decimal point.
			var stripNotNumbers = /[^0-9.-]/g;

			stringInput = stringInput.replace(stripNotNumbers, "");

			var number = new Number();
			number = parseFloat(stringInput);

			if (number.toString() == "NaN")
			{
				if (returnNullWhenNaN)
				{
					return null;
				}
				else
				{
					return 0;
				}
			}
			else
			{
				return number;
			}
		}

	};



	//rounds the number supplied, returns a number with the appropriate scale
	this.Round = function (number, scale, commaAndDecimalReversed)
	{
		///	<summary>
		/// Rounds the supplied number
		///	</summary>
		///	<param name="number" type="float"> number to round.</param>
		///	<param name="scale" type="int"> scale of the number (number of decimal places), if null, then takes the default set on the object.</param>
		///	<param name="commaAndDecimalReversed" type="bool"> flag indicating whether or not the comma and decimal is reversed, if null, then takes the default set on the object.</param>
		/// <returns type="float"> rounded</returns>

		var inNum = number;
		var sign = 1;

		if (inNum < 0)
		{
			sign = -1;
		}

		if (scale == null)
		{
			scale = this.DecimalScale;
		}

		//make sure the number is a float..
		inNum = this.ParseFloat(inNum, false, commaAndDecimalReversed);
		inNum = Math.abs(inNum);
		scale = parseInt(scale);

		var n = new Number(sign * Math.round(inNum * Math.pow(10, scale)) / Math.pow(10, scale));

		return n;
	};

	//determines whether or not the number is even
	this.IsEven = function (integer)
	{
		///	<summary>
		/// Determines if the number is even
		///	</summary>
		///	<param name="integer" type="int"> to determine if the number is odd or even.</param>
		/// <returns type="bool"> flag indicating whether or not the number is even</returns>

		return (1 - (integer % 2));
	};



};
var MathTools = new MathTools();

//constructor for the layout tools page position moving items around etc.
function UITools()
{
	///	<summary>
	///	Master user interface tools library for 
	///	</summary>
	///	<param name="hiddenInput" type="string">name or id of the hidden input element</param>
	///	<param name="hiddenValue" type="string">value of the input to set</param>
	/// <returns type="void" />
	/// <field name="GlobalIsControlKeyDown" type="bool"> Flag indicates whether or not the CNTRL key is currently pressed.</field>	
	/// <field name="GlobalIsShiftKeyDown" type="bool"> Flag indicates whether or not the shift key is currently pressed.</field>	


	//Key Down Variables
	//
	//Control Key
	this.GlobalIsControlKeyDown = false;
	//Shift Key
	this.GlobalIsShiftKeyDown = false;



	//gets the page x coordinate of the element
	this.GetPageXCoordinate = function (element)
	{
		///	<summary>
		///		Gets the X coordinate, relative to the page, for the supplied element or element id
		///	</summary>
		///	<param name="element" type="string">id of the element (or the element itself)</param>
		/// <returns type="int">X coordinage of the element, relative to the page location.</returns>

		var elementId = element;
		element = GetElementById(element);

		if (element)
		{
			//var offsetParent = element.offsetParent;

			var offsetParent = element;


			if (!offsetParent)
			{
				//if (element.parentNode)
				//{
				//	offsetParent = element.parentNode;
				//}
				//else
				//{
				alert("Able to find element, but unable to find the offsetParent for the element supplied to UITools.GetPageXCoordinate.  The next alert will dump the object");
				__Dump(element);
				//}
			}

			//var echo = false;
			//if (element.id == "ganttChartContainer")
			//{
			//	echo = true;
			//alert(element.id);
			//}

			var offsetLeft = 0;
			// element.offsetLeft - element.scrollLeft;

			//2010 STW - added offsetParent.tagName != "HTML" to handle XHTML when inserting HTML apparently with XHTML doc type, inserted HTML is not in the Form though should be?
			while (offsetParent != null && offsetParent.tagName != "BODY" && offsetParent.tagName != "HTML")
			{
				//if (echo)
				//{
				//alert("offsetParent id: " + offsetParent.id + " scroll " + offsetParent.scrollLeft + " offsetLeft " + offsetParent.offsetLeft + " tag: " + offsetParent.tagName);

				//alert("while: " + offsetParent.id);
				//}



				offsetLeft += offsetParent.offsetLeft - offsetParent.scrollLeft;


				//if (offsetParent.id == "ss_rightPaneDiv")
				//{
				//	alert(offsetParent.id + " " + offsetParent.scrollLeft);
				//}

				//if (offsetParent.offsetParent)
				//{
				//	offsetParent = offsetParent.offsetParent;
				//}
				//else 
				//if (offsetParent.parentNode && offsetParent.parentNode != offsetParent.offsetParent)
				//{
				//	alert(offsetParent.parentNode.id);
				//}


				if (offsetParent.parentNode && offsetParent.parentNode != offsetParent.offsetParent && offsetParent.parentNode.scrollLeft && offsetParent.parentNode.scrollLeft > 0)
				{
					offsetLeft -= offsetParent.parentNode.scrollLeft;
				}

				//move to the next one up
				offsetParent = offsetParent.offsetParent;


			}

			return parseInt(offsetLeft);
		}
		else
		{
			alert("Unable to locate the element supplied to the UITools.GetPageXCoordinate");
			__Dump(elementId);
		}
	};



	//gets the page y coordinate of the element
	this.GetPageYCoordinate = function (element)
	{
		///	<summary>
		///		Gets the Y coordinate, relative to the page, for the supplied element or element id
		///	</summary>
		///	<param name="element" type="string">id of the element (or the element itself)</param>
		/// <returns type="int">Y coordinage of the element, relative to the page location.</returns>


		var elementId = element;
		element = GetElementById(element);



		if (element)
		{

			var offsetTop = 0;

			//var offsetParent = element.offsetParent; // - element.scrollTop;
			var offsetParent = element;

			//var offsetTop = element.offsetTop - element.scrollTop;

			//alert("element id: " + element.id + " scroll " + element.scrollTop + " offsetTop " + element.offsetTop + " tag: " + element.tagName);


			// offsetParent.offsetTop - offsetParent;

			//if this is or safari and the item is TR with 0 offsetTop we need to get the offset top from the first child (TD)
			//if (offsetTop == 0 && element.tagName == "TR" && BrowserTools.IsSafari() && element.firstChild != null)
			//{
			//	if (element.firstChild.offsetTop)
			//	{
			//		offsetTop = element.firstChild.offsetTop;
			//	}
			//}

			if (offsetParent.offsetTop == 0 && offsetParent.tagName == "TR" && BrowserTools.IsSafari() && offsetParent.firstChild != null)
			{
				offsetParent = offsetParent.firstChild;
			}



			if (!offsetParent)
			{
				//if (element.parentNode)
				//{
				//	offsetParent = element.parentNode;
				//}
				//else
				//{
				alert("Able to find element, but unable to find the offsetParent for the element supplied to UITools.GetPageYCoordinate.  The next alert will dump the object");
				__Dump(element);
				//}
			}

			//2010 STW - added offsetParent.tagName != "HTML" to handle XHTML when inserting HTML apparently with XHTML doc type, inserted HTML is not in the Form though should be?
			while (offsetParent != null && offsetParent.tagName != "BODY" && offsetParent.tagName != "HTML")
			{
				//if(offsetParent.scrollTop != 0)
				//{
				//	__Dump(offsetParent);
				//}
				//THIS MAY NOT WORK PROPERLY IN XHTML...

				//in FF the tag name TR repeats the offset of the cell that it was contained in, so don't add that in the calc

				offsetTop += offsetParent.offsetTop - offsetParent.scrollTop;


				if (offsetParent.parentNode && offsetParent.parentNode != offsetParent.offsetParent && offsetParent.parentNode.scrollTop && offsetParent.parentNode.scrollTop > 0)
				{
					offsetTop -= offsetParent.parentNode.scrollTop;
				}



				//alert("TOTAL: " + offsetTop + " element.id: " + element.id + " offsetParent id: " + offsetParent.id + " scroll " + offsetParent.scrollTop + " offsetTop " + offsetParent.offsetTop + " tag: " + offsetParent.tagName);

				//else
				//{
				//	alert("offsetParent id: " + offsetParent.id + " scroll " + offsetParent.scrollTop + " offsetTop " + offsetParent.offsetTop + " tag: " + offsetParent.tagName);
				//}
				offsetParent = offsetParent.offsetParent;
				//offsetParent = offsetParent.parentNode;
			}


			return parseInt(offsetTop);
		}
		else
		{
			alert("Unable to locate the element supplied to the UITools.GetPageYCoordinate");
			__Dump(elementId);
		}
	};


	//gets the event page x coordiante
	this.GetEventPageXCoordinate = function (localEvent)
	{
		///	<summary>
		///		Gets the X coordinate on the Page of an event.
		///	</summary>
		///	<param name="event" type="event">event to get the coordinate</param>
		/// <returns type="int"> the X coordinate of the event on the page.</returns>
		var x;
		//all netscape based browsers
		if (navigator.appName == "Netscape")
		{
			x = parseInt(localEvent.pageX);
		}
		//ie (target browser)
		else
		{
			x = parseInt(localEvent.clientX + UITools.GetScrollLeft());
		}

		return x;

	};
	//gets the event page y coordinate
	this.GetEventPageYCoordinate = function (localEvent)
	{
		///	<summary>
		///		Gets the Y coordinate on the Window of an event.
		///	</summary>
		///	<param name="event" type="event">event to get the coordinate</param>
		/// <returns type="int"> the Y coordinate of the event on the page.</returns>
		var y;

		//all netscape based browsers
		if (navigator.appName == "Netscape")
		{
			y = parseInt(localEvent.pageY);
		}
		//ie (target browser)
		else
		{
			y = parseInt(localEvent.clientY + UITools.GetScrollTop());
		}

		return y;

	};
	//gets the window height
	this.GetWindowHeight = function ()
	{
		///	<summary>
		///		Gets the height of the window
		///	</summary>
		/// <returns type="int"> height of the window.</returns>

		if (IsSafari())
		{
			return parseInt(window.innerHeight);
		}
		else
		{
			var h = parseInt(document.documentElement.clientHeight);
			if (h == null || h <= 0)
			{
				h = document.body.clientHeight;
			}
			return h;
			//return parseInt(document.body.clientHeight);
			//return parseInt(document.documentElement.clientHeight);
		}
	};
	//gets the window width
	this.GetWindowWidth = function ()
	{
		///	<summary>
		///		Gets the width of the window
		///	</summary>
		/// <returns type="int"> width of the window.</returns>

		if (IsSafari())
		{
			return parseInt(window.innerWidth);
		}
		else
		{
			var w = parseInt(document.documentElement.clientWidth);
			if (w == null || w <= 0)
			{
				w = parseInt(document.body.clientWidth);
			}
			return w;
			//return parseInt(document.body.clientWidth);
			//return parseInt(document.documentElement.clientWidth);
		}
	};

	//gets the window scroll left pixels
	this.GetScrollLeft = function ()
	{
		///	<summary>
		///		Gets the amount of left scroll for the window.
		///	</summary>
		/// <returns type="int"> left scroll of the window.</returns>


		if (navigator.appName == "Netscape")
		{
			return parseInt(window.pageXOffset);
		}
		else
		{
			var scrollLeft = document.body.scrollLeft;
			var scrollLeftDocElement = 0;
			if (document.documentElement != null)
			{
				scrollLeftDocElement = document.documentElement.scrollLeft;
			}
			return parseInt(Math.max(scrollLeft, scrollLeftDocElement));
		}
	};
	//gets the window scroll top pixels
	this.GetScrollTop = function ()
	{
		///	<summary>
		///		Gets the amount of top scroll for the window.
		///	</summary>
		/// <returns type="int"> top scroll of the window.</returns>

		if (navigator.appName == "Netscape")
		{
			return parseInt(window.pageYOffset);
		}
		else
		{
			var scrollTop = document.body.scrollTop;
			var scrollTopDocElement = 0;
			if (document.documentElement != null)
			{
				scrollTopDocElement = document.documentElement.scrollTop;
			}
			return parseInt(Math.max(scrollTop, scrollTopDocElement));
		}
	};

	//gets the width of the element
	this.GetElementWidth = function (element)
	{
		///	<summary>
		///		Gets the width of the supplied element or element id
		///	</summary>
		///	<param name="element" type="string">id or element to locate the width</param>
		/// <returns type="int"> width of the element.</returns>


		element = GetElementById(element);

		if (element)
		{
			return parseInt(element.offsetWidth);
		}
		else
		{
			alert("Unable to locate the element supplied to the UITools.GetElementWidth - 0 returned");
		}

		return 0;
	};
	//gets the height of the element
	this.GetElementHeight = function (element)
	{
		///	<summary>
		///		Gets the height of the supplied element or element id
		///	</summary>
		///	<param name="element" type="string">id or element to locate the height</param>
		/// <returns type="int"> height of the element.</returns>

		element = GetElementById(element);

		if (element)
		{
			return parseInt(element.offsetHeight);
		}
		else
		{
			alert("Unable to locate the element supplied to the UITools.GetElementHeight - 0 returned");

		}
		return 0;

	};



	/***************************************************************************************
	Div and I Frame Display
	****************************************************************************************/

	//shows the div and iframe at the specified local event
	this.ShowDivAndIFrameAtEvent = function (localEvent, divElement, iframe, offsetX, offsetY)
	{
		///	<summary>
		///	Shows the div (and iframe) at the supplied event. Obtains the coordinates the event occurred at.
		///	</summary>
		/// <param name="localEvent" type="event"> event to get the coordinates</param>
		///	<param name="divElement" type="string"> id or element to show</param>
		///	<param name="iframe" type="string"> [LEGACY] id or iframe element to show under the div if null, then the iframe is automatically applied)</param>
		/// <param name="offsetX" type="int"> x coordinate offset from the event location to show the div</param>
		/// <param name="offsetY" type="int"> y coordinate offset from the event location to show the div</param>
		/// <returns type="bool"> flag normally false, used to cancel an onclick action associated with invoking the method.</returns>

		if (!localEvent)
		{
			return false;
		}

		var x;
		var y;


		//get event coordinates
		if (navigator.appName == "Netscape" && parseInt(navigator.appVersion) >= 4)
		{
			x = localEvent.pageX;
			y = localEvent.pageY;
		}
		else
		{
			x = event.clientX + document.body.scrollLeft;
			y = event.clientY + document.body.scrollTop;
		}


		return this.ShowDivAndIFrameAtXY(x, y, divElement, iframe, offsetX, offsetY);
	};


	//shows the div and i frame (if ie) at the element location specified
	this.ShowDivAndIFrameAtCenterScreen = function (divElement, iframe, offsetX, offsetY, showVeil)
	{
		///	<summary>
		///	Shows the div (and iframe) at the center of the screen.
		///	</summary>
		/// <param name="localEvent" type="event"> event to get the coordinates</param>
		///	<param name="divElement" type="string"> id or element to show</param>
		///	<param name="iframe" type="string"> [LEGACY] id or iframe element to show under the div if null, then the iframe is automatically applied)</param>
		/// <param name="offsetX" type="int"> x coordinate offset from the center screen location to show the div</param>
		/// <param name="offsetY" type="int"> y coordinate offset from the center screen location to show the div</param>
		/// <param name="showVeil" type="bool"> flag indicating whether or not to show the veil under the div (default false).</param>
		/// <returns type="bool"> flag normally false, used to cancel an onclick action associated with invoking the method.</returns>

		var divElement = GetElementById(divElement);


		var x = 0;
		var y = 0;

		divElement.style.display = "block";
		divElement.style.visibility = "visible";
		var width = divElement.offsetWidth;
		var height = divElement.offsetHeight;
		divElement.style.display = "none";
		divElement.style.visibility = "";

		var windowWidth = UITools.GetWindowWidth();
		var windowHeight = UITools.GetWindowHeight();

		if (windowWidth > width)
		{
			x = (windowWidth - width) / 2;
		}
		x = x + UITools.GetScrollLeft();

		if (windowHeight > height)
		{
			y = (windowHeight - height) / 2;
		}
		y = y + UITools.GetScrollTop();


		if (offsetX)
		{
			x += offsetX;
		}
		if (offsetY)
		{
			y += offsetY;
		}


		//show the tip
		return UITools.ShowDivAndIFrameAtXY(x, y, divElement, iframe, offsetX, offsetY, showVeil);

	};

	//shows the div and i frame (if ie) at the element location specified
	this.ShowDivAndIFrameAtElement = function (elementNear, divElement, iframe, offsetX, offsetY, showVeil, outofWindowAllowed, scrollToKeepInWindow)
	{
		///	<summary>
		///	Shows the div (and iframe) at the center of the screen.
		///	</summary>
		/// <param name="elementNear" type="event"> id or element to show the supplied divElement near to</param>
		///	<param name="divElement" type="string"> id or element to show</param>
		///	<param name="iframe" type="string"> [LEGACY] id or iframe element to show under the div if null, then the iframe is automatically applied)</param>
		/// <param name="offsetX" type="int"> x coordinate offset from the elementNear location to show the div</param>
		/// <param name="offsetY" type="int"> y coordinate offset from the elementNear location to show the div</param>
		/// <param name="showVeil" type="bool"> flag indicating whether or not to show the veil under the div (default false).</param>
		/// <param name="outofWindowAllowed" type="bool"> flag indicating whether or not to show the divelement can be out of the immediate window, if false, and the div element will be out of the window, the coordinates of the show are adjusted (default false).</param>
		/// <param name="scrollToKeepInWindow" type="bool"> flag indicating whether or not to scroll the window to keep the layer in view, if true, and the outOfwindowAllowed is false, then the page will be scrolled instead of the layer being moved.</param>
		/// <returns type="bool"> flag normally false, used to cancel an onclick action associated with invoking the method.</returns>


		return this.ShowDivAndIFrameAtXY(this.GetPageXCoordinate(elementNear), this.GetPageYCoordinate(elementNear), divElement, iframe, offsetX, offsetY, showVeil, outofWindowAllowed, scrollToKeepInWindow);
	};

	//shows the div and i frame (if ie) at the x-y location specified
	this.ShowDivAndIFrameAtXY = function (x, y, divElement, iframe, offsetX, offsetY, showVeil, outofWindowAllowed, scrollToKeepInWindow)
	{
		///	<summary>
		///	Shows the div (and iframe) at the center of the screen.
		///	</summary>
		/// <param name="x" type="int"> x coordinate location to show the div</param>
		/// <param name="y" type="int"> y coordinate location to show the div</param>
		///	<param name="divElement" type="string"> id or element to show</param>
		///	<param name="iframe" type="string"> [LEGACY] id or iframe element to show under the div if null, then the iframe is automatically applied)</param>
		/// <param name="offsetX" type="int"> x coordinate offset from the supplied x location to show the div</param>
		/// <param name="offsetY" type="int"> y coordinate offset from the supplied y location to show the div</param>
		/// <param name="showVeil" type="bool"> flag indicating whether or not to show the veil under the div (default false).</param>
		/// <param name="outofWindowAllowed" type="bool"> flag indicating whether or not to show the divelement can be out of the immediate window, if false, and the div element will be out of the window, the coordinates of the where to show the layer are adjusted (default false).</param>
		/// <param name="scrollToKeepInWindow" type="bool"> flag indicating whether or not to scroll the window to keep the layer in view, if true, and the outOfwindowAllowed is false, then the page will be scrolled instead of the layer being moved.</param>
		/// <returns type="bool"> flag normally false, used to cancel an onclick action associated with invoking the method.</returns>


		divElement = GetElementById(divElement);

		if (divElement)
		{

			if (divElement.parentNode.tagName != "BODY" && divElement.parentNode.tagName != "FORM")
			{
				divElement.parentNode.removeChild(divElement);
				document.forms[0].appendChild(divElement);
			}

			divElement.style.display = "block";
			divElement.style.visibility = "visible";

			if (!offsetX)
			{
				offsetX = 0;
			}
			if (!offsetY)
			{
				offsetY = 0;
			}

			x = x + offsetX;
			y = y + offsetY;


			if (!outofWindowAllowed)
			{


				if (scrollToKeepInWindow)
				{
					var sX = this.GetPageXScrollByForAdjustedElementWithinWindow(x, divElement);
					var sY = this.GetPageYScrollByForAdjustedElementWithinWindow(y, divElement);

					if (sX != 0 || sY != 0)
					{
						window.scrollBy(sX, sY);
					}
				}
				else
				{
					var x = this.GetPageXCoordinateAdjustedElementWithinWindow(x, divElement);
					var y = this.GetPageYCoordinateAdjustedElementWithinWindow(y, divElement);
				}


				//ensure we are always under the window (this will hook it up)
				if (divElement.onresize == null)
				{
					//IE is the only browser that supports the onresize, so use IE method to attach event handler
					//AddEventHandlerToElement(divElement, "onresize", function() { UITools.EnsureElementAndIFrameDisplayedWithinWindow(divElement) });
					//AddEventHandlerToElement(divElement, "onresize", function() { alert('in resize') }, true);

					divElement.onresize = function () { UITools.EnsureElementAndIFrameDisplayedWithinWindow(divElement, scrollToKeepInWindow) };
				}
			}


			/* if element is child of relative position
			var offsetParentX = 0;
			var offsetParentY = 0;
			if(divElement.offsetParent != null)
			{
			offsetParentX = UITools.GetPageXCoordinate(divElement.offsetParent);
			offsetParentY = UITools.GetPageYCoordinate(divElement.offsetParent);
			}
			x = x - offsetParentX;
			y = y - offsetParentY;
			*/

			divElement.style.left = x + "px";
			divElement.style.top = y + "px";



			//if an iframe was supplied then 
			if (iframe)
			{
				iframe = GetElementById(iframe);
			}

			if (iframe == null)
			{
				iframe = UITools.GetElementShim(divElement);
			}


			//i frame underneath so
			if (iframe != null)
			{
				//show the i frame under the div
				this.ShowIFrameUnderDiv(divElement, iframe, x, y);
			}


			//if the veil element was supplied then send it in.
			if (showVeil)
			{
				metafuseVeil.ShowVeilUnderElement(divElement, iframe);
			}

		}
		else
		{
			alert("Unable to locate the div specified in the UITools.ShowDivAndIFrameAtXY function");
		}

		return false;
	};
	//shows the i frame directly under the div
	this.ShowIFrameUnderDiv = function (divElement, iframe, x, y)
	{
		///	<summary>
		///	Method shows the div under the iframe
		///	</summary>
		///	<param name="divElement" type="string"> id or element to show</param>
		///	<param name="iframe" type="string"> [LEGACY] id or iframe element to show under the div if null, then the iframe is automatically applied)</param>
		/// <param name="x" type="int"> x coordinate location to show the div</param>
		/// <param name="y" type="int"> y coordinate location to show the div</param>
		/// <returns type="void" />


		divElement = GetElementById(divElement);
		iframe = GetElementById(iframe);

		if (divElement && iframe)
		{
			iframe.display = "";

		

			iframe.style.width = divElement.offsetWidth + 'px';
			iframe.style.height = divElement.offsetHeight + 'px';


			//make sure the iframe gets sized with the div it is hiding under
			if (divElement.onresize == null)
			{
				divElement.onresize = function () { iframe.style.width = divElement.offsetWidth; iframe.style.height = divElement.offsetHeight; };
			}


			//var y = divElement.style.top;
			//if(!y)
			//{
			if (y == null)
			{
				y = this.GetPageYCoordinate(divElement);
			}
			//}
			//var x = divElement.style.left;
			//if(!x)
			//{
			if (x == null)
			{
				x = this.GetPageXCoordinate(divElement);
			}
			//}
			//x = this.GetPageXCoordinateAdjustedElementWithinWindow(x, divElement);
			//y = this.GetPageYCoordinateAdjustedElementWithinWindow(y, divElement);

			iframe.style.top = y + "px";
			iframe.style.left = x + "px";
			if (divElement.style.zIndex)
			{
				iframe.style.zIndex = divElement.style.zIndex - 1;
			}
			iframe.style.display = "";



		}
		else
		{
			alert("Unable to locate either the element or the div at specified in the UITools.ShowIFrameUnderDiv function");
		}
	};

	//ensures the element and i frame are displayed in the window
	this.EnsureElementAndIFrameDisplayedWithinWindow = function (element, scrollToKeepInWindow)
	{

		///	<summary>
		///	Ensures the element and iframe are displayed within the window.
		///	</summary>
		///	<param name="divElement" type="element"> element to show</param>
		/// <param name="scrollToKeepInWindow" type="bool"> flag indicating whether or not to scroll the window to keep the layer in view, if true, and the outOfwindowAllowed is false, then the page will be scrolled instead of the layer being moved.</param>
		/// <returns type="void" />


		//window.status = new Date().valueOf();
		element = GetElementById(element);

		if (element)
		{

			var x = this.GetPageXCoordinate(element);
			var y = this.GetPageYCoordinate(element);

			if (scrollToKeepInWindow)
			{
				var sX = this.GetPageXScrollByForAdjustedElementWithinWindow(x, element);
				var sY = this.GetPageYScrollByForAdjustedElementWithinWindow(y, element);
				if (sX != 0 || sY != 0)
				{
					window.scrollBy(sX, sY);
				}
			}
			else
			{

				var xC = this.GetPageXCoordinateAdjustedElementWithinWindow(x, element);
				var yC = this.GetPageYCoordinateAdjustedElementWithinWindow(y, element);

				if (x != xC)
				{
					element.style.left = xC;
				}
				if (y != yC)
				{
					element.style.top = yC;
				}

				var iframe = GetElementById(iframe);
				if (iframe)
				{
					//make sure the sizes are correct
					iframe.style.width = element.offsetWidth;
					iframe.style.height = element.offsetHeight;
					if (x != xC)
					{
						iframe.style.left = xC;
					}
					if (y != yC)
					{
						iframe.style.top = yC;
					}

				}
			}
		}
	};

	//gets the x coordinate adjusted element within the window
	this.GetPageXCoordinateAdjustedElementWithinWindow = function (x, element)
	{
		///	<summary>
		///	Gets the page x coordinate adjusted to be within the window for the supplied element. 
		///	</summary>
		/// <param name="x" type="int"> x coordinate</param>
		/// <param name="element" type="element">  element to determine the adjusted in screen x coordinate</param>
		/// <returns type="int"> adjusted x coordinate within the window</returns>


		var scrollLeft = UITools.GetScrollLeft();
		var windowWidth = UITools.GetWindowWidth();

		//alert(x);
		//if we go too far right then move it back

		var xOver = (x + element.offsetWidth) - (windowWidth + scrollLeft);

		if (xOver > 0)
		{
			x = x - xOver;
		}
		//alert(xOver);
		//keep it from too far left second
		if (x < scrollLeft)
		{
			x = scrollLeft;
		}
		return x;
	};



	//gets the y coordinate adjusted element within the window
	this.GetPageYCoordinateAdjustedElementWithinWindow = function (y, element)
	{
		///	<summary>
		///	Gets the page y coordinate adjusted to be within the window for the supplied element. 
		///	</summary>
		/// <param name="y" type="int"> y coordinate</param>
		/// <param name="element" type="element">  element to determine the adjusted in screen y coordinate</param>
		/// <returns type="int"> adjusted y coordinate within the window</returns>

		var scrollTop = UITools.GetScrollTop();
		var windowHeight = UITools.GetWindowHeight();

		//alert(y);
		//if we go too far down move it up
		var yOver = (y + element.offsetHeight) - (windowHeight + scrollTop);
		if (yOver > 0)
		{
			y = y - yOver;
		}
		//alert(yOver);
		//if we go to far up move it back down
		if (y < scrollTop)
		{
			y = scrollTop;
		}
		return y;
	};

	//gets the x coordinate adjusted element within the window
	this.GetPageXScrollByForAdjustedElementWithinWindow = function (x, element)
	{
		///	<summary>
		///	Gets the page scroll by x so the window can be adjusted so the element will be within the window for the supplied element. 
		///	</summary>
		/// <param name="x" type="int"> x coordinate</param>
		/// <param name="element" type="element">  element to determine the adjusted in screen x coordinate</param>
		/// <returns type="int"> x amount to scroll by to keep the element in the window</returns>

		var scrollLeft = UITools.GetScrollLeft();
		var windowWidth = UITools.GetWindowWidth();
		var xOver = (x + element.offsetWidth) - (windowWidth + scrollLeft);


		if (xOver > 0)
		{
			return xOver;
		}
		//alert(xOver);
		//keep it from too far left second
		if (x < scrollLeft)
		{
			return xOver;
		}

		return 0;
	};


	this.GetPageYScrollByForAdjustedElementWithinWindow = function (y, element)
	{
		///	<summary>
		///	Gets the page scroll by y so the window can be adjusted so the element will be within the window for the supplied element. 
		///	</summary>
		/// <param name="y" type="int"> y coordinate</param>
		/// <param name="element" type="element">  element to determine the adjusted in screen y coordinate</param>
		/// <returns type="int"> y amount to scroll by to keep the element in the window</returns>

		var scrollTop = UITools.GetScrollTop();
		var windowHeight = UITools.GetWindowHeight();

		var yOver = (y + element.offsetHeight) - (windowHeight + scrollTop);

		if (yOver > 0)
		{
			return yOver;
		}
		//alert(yOver);
		//if we go to far up move it back down
		if (y < scrollTop)
		{
			return yOver;
		}
		return 0;
	};

	//hides the div and iframe (if ie)
	this.HideDivAndIFrame = function (divElement, iframe)
	{
		///	<summary>
		///	Hides the supplied div and iframe 
		///	</summary>
		/// <param name="divElement" type="string"> id or  element to determine the adjusted in screen y coordinate</param>
		/// <param name="iframe" type="string"> [LEGACY] id or iframe element to show under the div if null, then the iframe is automatically applied)</param> 
		/// <returns type="int"> adjusted y coordinate within the window</returns>



		divElement = GetElementById(divElement);
		if (divElement)
		{
			divElement.style.display = "none";
		}
		if (BrowserTools.IsInternetExplorer() || this.AlwaysCreateShim)
		{
			iframe = GetElementById(iframe);

			//if no iframe supplied, get the shim
			if (iframe == null)
			{
				iframe = this.GetElementShim(divElement);
			}
			else
			{
				//temporary use this to help if one was supplied make sure that the shim is also done
				//in case the open method doesn't send the shim, but the close call does
				var iframeShim = this.GetElementShim(divElement);
				if (iframeShim)
				{
					iframeShim.style.width = 0;
					iframeShim.style.height = 0;
					iframeShim.style.display = "none";
				}
			}

			if (iframe)
			{
				iframe.style.width = 0;
				iframe.style.height = 0;
				iframe.style.display = "none";
			}
		}
		metafuseVeil.HideVeilUnderElement(divElement);

	};

	//gets the iframe that goes with a particular element takes the id the iframe should be
	//THIS is an older function the preferred method is to use GetElementShim(element) it takes the
	//element and creates a shim for that element
	this.GetIFrameForShim = function (iframeId)
	{
		///	<summary>
		///	Gets the iframe for the supplied id.   If the iframe doesn't exist, one is created with the supplied id. 
		///	</summary>
		/// <param name="iframeId" type="string"> [LEGACY] id or iframe element, if non existent, then an iframe is created</param> 
		/// <returns type="element"> iframe element.</returns>


		var iframe = GetElementById(iframeId);

		if (iframe == null)
		{
			this.InsertHTML("<iframe id=\"" + iframeId + "\" scrolling=\"no\" frameborder=\"0\" style=\"position:absolute;top:0px; left:0px; display:none;color:#ffffff;font-size:1px;\"></iframe>");
			iframe = GetElementById(iframeId);
		}
		return iframe;
	};

	this.AlwaysCreateShim = false;

	//preferred method to get a shim when necessary, handles naming for the element and
	//whether the browser even needs the shim.
	this.GetElementShim = function (element)
	{
		///	<summary>
		///	Gets an iframe shim for the supplied element.   If the iframe doesn't exist, one is created for the supplied element. 
		///	</summary>
		/// <param name="element" type="element"> element to get the iframe shim for.</param> 
		/// <returns type="element"> iframe element.</returns>

		if ((BrowserTools.IsInternetExplorer() && BrowserTools.GetMajorVersion() < 9) || this.AlwaysCreateShim)
		{
			element = GetElementById(element);

			if (element != null)
			{
				return UITools.GetIFrameForShim(element.id + "_Shim_erspw");
			}

		}
		return null;

	};

	/*
	//the method gets the element parent div that with the document body as the parent so that this
	//element can be dragged or positioned.  This essentially moves an element that starts as a child of a table or
	//other div that is not absolute positioned and moves it out into a div that has the body as the parent
	this.GetElementParentDivWithBodyAsParent = function(element)
	{
	//make sure we have the element handle
	element = GetElementById(element);

	//creates an outer div
	var outerDivId = element.id + "_OuterDiv_esqjizw";

	//see if we can get the element from the body, if not there then it's not there
	var outerDiv = GetElementById(outerDivId);

	if(outerDiv == null)
	{
	var outerDivHTML = "<div id=\"" + outerDivId + "\" style=\"position:absolute;z-index:801;display:none;\"></div>";
	UITools.InsertHTML(outerDivHTML);

	//get the object that was just inserted
	outerDiv = GetElementById(outerDivId);

	element.style.display = "block";
	element.style.visibility = "visible";

	//get the width and height of the edit form
	var height = element.offsetHeight;
	var width = element.offsetWidth;

	//STW I don't think this is necessary
	//element.parentNode.removeChild(element);// = null;

	//add the div to the outer div
	outerDiv.appendChild(element);
	outerDiv.style.height = height;
	outerDiv.style.width = width;
	//alert('here');
	}
	return outerDiv;
	};
	*/

	/*******************************************************************************
	Focus On Element, Toggle Display Etc
	********************************************************************************/
	this.FocusOnElement = function (elementToFocus)
	{
		///	<summary>
		///	Sets the focus on the supplied element
		///	</summary>
		/// <param name="elementToFocus" type="string"> id or element to set focus on.</param> 
		/// <returns type="void" />
		var focusElement = GetElementById(elementToFocus);
		if (focusElement)
		{
			if (focusElement.style)
			{
				if (focusElement.style.display != "none")
				{
					try
					{
						focusElement.focus();
					}
					catch (e)
					{
					}
				}
			}

		}
	};


	//clicks an element (does not work in safari)
	this.ClickElement = function (element)
	{

		///	<summary>
		///	Invokes the click event on the supplied element.
		///	</summary>
		/// <param name="element" type="string"> id or element to click on.</param> 
		/// <returns type="void" />


		element = GetElementById(element);

		if (element)
		{
			//if the browser is IE we can do this
			if (!BrowserTools.IsChrome() && (BrowserTools.IsInternetExplorer() || BrowserTools.IsSafari()))
			{
				element.click();
			}
			else
			{
				var evt = document.createEvent('MouseEvents');

				try
				{
					evt.initMouseEvent('click', true, true, document.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
					element.dispatchEvent(evt);
				}
				catch (ex)
				{
					try
					{
						element.click();
					}
					catch (ex2)
					{
						
					};
				};



			}
		}
	};

	//disables an element (tested on link button on TaskAddEdit)
	this.DisableElement = function (elementNameToDisable)
	{
		///	<summary>
		///	Disables the supplied element
		///	</summary>
		/// <param name="elementNameToDisable" type="string"> id or element to disable.</param> 
		/// <returns type="void" />

		this.ToggleElementDisable(elementNameToDisable, false);
	};
	//enables an element (tested on link button on TaskAddEdit)
	this.EnableElement = function (elementNameToEnable)
	{
		///	<summary>
		///	Enables the supplied element
		///	</summary>
		/// <param name="elementNameToDisable" type="string"> id or element to enable.</param> 
		/// <returns type="void" />

		ToggleElementDisable(elementNameToEnable, true);
	};
	this.ToggleElementDisable = function (elementName, enable)
	{
		///	<summary>
		///	Disables or enables the supplied element
		///	</summary>
		/// <param name="elementName" type="string"> id or element to enable or disable.</param> 
		/// <param name="enable" type="bool"> flag indicating whether or not to enable or disable the supplied element.</param> 
		/// <returns type="void" />

		var element = GetElementById(elementName);
		if (element)
		{
			if (enable)
			{

				if (element.tagName == "A" && (BrowserTools.IsInternetExplorer() == false || isUndefined(element.disabled) == true))
				{

					var href_previous = element.getAttribute("href_previous");
					if (href_previous && href_previous != null && href_previous != "")
					{
						element.setAttribute("href", href_previous);
					}

					var onclick_previous = element.getAttribute("onclick_previous");
					if (onclick_previous && onclick_previous != null && onclick_previous != "")
					{
						element.setAttribute("onclick", onclick_previous);
					}
					var onmousedown_previous = element.getAttribute("onmousedown_previous");
					if (onmousedown_previous && onmousedown_previous != null && onmousedown_previous != "")
					{
						element.setAttribute("onmousedown", onmousedown_previous);
					}
					var onmouseover_previous = element.getAttribute("onmouseover_previous");
					if (onmouseover_previous && onmouseover_previous != null && onmouseover_previous != "")
					{
						element.setAttribute("onmouseover", onmouseover_previous);
					}
					var color_previous = element.getAttribute("color_previous");
					if (color_previous && color_previous != null && color_previous != "")
					{
						element.style.color = color_previous;
					}
					else
					{
						element.style.color = "";
					}
				}
				else
				{
					if (isUndefined(element.disabled) == false)
					{
						element.disabled = false;
						$(element).removeAttr('disabled');

						if (element.tagName == "TABLE" && element.className == "MetafuseComboBox")
						{
							var textBox = GetElementById(element.id + '_tb');
							if (textBox)
							{
								$(textBox).removeAttr('disabled');
								textBox.disabled = false;
							}
						}
					}
				}

				//possibly add drill up you can drill up inside out and it works (checkbox control needs it).
			}
			else
			{

				if (element.tagName == "A" && (BrowserTools.IsInternetExplorer() == false || isUndefined(element.disabled) == true))
				{

					var href = element.getAttribute("href");
					if (href && href != null && href != "")
					{
						element.setAttribute("href_previous", href);
						element.setAttribute("href", "javascript:;");
					}

					var onclick = element.getAttribute("onclick");
					if (onclick && onclick != null && onclick != "")
					{
						element.setAttribute("onclick_previous", onclick);
						element.setAttribute("onclick", "void(0);");
					}
					var onmousedown = element.getAttribute("onmousedown");
					if (onmousedown && onmousedown != null && onmousedown != "")
					{
						element.setAttribute("onmousedown_previous", onmousedown);
						element.setAttribute("onmousedown", "return false;");
					}

					var onmouseover = element.getAttribute("onmouseover");
					if (onmouseover && onmouseover != null && onmouseover != "")
					{
						element.setAttribute("onmouseover_previous", onmouseover);
						element.setAttribute("onmouseover", "return false;");
					}

					if (element.style.color)
					{
						element.setAttribute("color_previous", element.style.color);
					}
					element.style.color = "gray";


				}
				else
				{
					if (isUndefined(element.disabled) == false)
					{
						$(element).attr('disabled', 'disabled');
						element.disabled = true;

						if (element.tagName == "TABLE" && element.className == "MetafuseComboBox")
						{
							var textBox = GetElementById(element.id + '_tb');
							if (textBox)
							{
								$(textBox).attr('disabled', 'disabled');
								textBox.disabled = true;
							}
						}

					}
				}

			}
		}
	};
	//toggle display of a layer
	this.ToggleDisplay = function (element, hide)
	{
		///	<summary>
		///	Shows or hides the supplied element setting style display.none for hide.
		///	</summary>
		/// <param name="element" type="string"> id or element to show or hide.</param> 
		/// <param name="hide" type="bool"> flag indicating whether or not to hide or show the supplied element.</param> 
		/// <returns type="void" />


		//make so we can use element or element id.
		element = GetElementById(element);

		if (element)
		{
			if (hide)
			{
				if (element.style.display == "" || element.style.display == "block")
				{
					element.style.display = "none";
				}
			}
			else
			{
				if (element.style.display == "none")
				{
					element.style.display = "";
				}
			}

			//if this is a checkbox, then toggle the label for the checkbox too
			var type = FormTools.GetFormElementType(element);
			if (type == "checkbox" && element.nextSibling && element.nextSibling.tagName == "LABEL")
			{
				UITools.ToggleDisplay(element.nextSibling, hide);
			}

		}
		return false;
	};


	//gets the key down event 
	this.GetKeyDown = function (localEvent)
	{
		///	<summary>
		///	Gets the key code for the key down event
		///	</summary>
		/// <param name="localEvent" type="event"> to get the key down event for.</param> 
		/// <returns type="int"> key code</returns>


		var keyCode =
			document.layers ? localEvent.which :
			document.all ? event.keyCode :
			document.getElementById ? localEvent.keyCode : 0;

		return keyCode;
	};
	//gets the key up event
	this.GetKeyUp = function (localEvent)
	{
		///	<summary>
		///	Gets the key code for the key up event
		///	</summary>
		/// <param name="localEvent" type="event"> to get the key up event for.</param> 
		/// <returns type="int"> key code</returns>

		var keyCode =
			document.layers ? localEvent.which :
			document.all ? event.keyCode :
			document.getElementById ? localEvent.keyCode : 0;

		return keyCode;
	};


	//inserts html into the page
	this.InsertHTML = function (html)
	{
		///	<summary>
		///	Inserts the supplied HTML into the page
		///	</summary>
		/// <param name="html" type="string"> HTML code to insert into the page.</param> 
		/// <returns type="void" />


		if (html != null && html != "")
		{
			if (document.body && document.body.insertAdjacentHTML)
			{
				//document.body.insertAdjacentHTML('AfterBegin', html);
				//document.body.insertAdjacentHTML('BeforeBegin', html);
				//document.body.insertAdjacentHTML('AfterEnd', html);

				//2010 STW, Richard discovered that the resulting HTML is has a parentTag name of HTML when inserting with XHTML doc type

				document.forms[0].insertAdjacentHTML('BeforeEnd', html);
			}
			else if (document.createRange)
			{
				var range = document.createRange();
				if (range.createContextualFragment)
				{
					range.selectNodeContents(document.body);
					var docFrag = range.createContextualFragment(html);
					document.forms[0].appendChild(docFrag);
				}
			}
			else if (document.layers)
			{
				var layer = new Layer(window.innerWidth);
				layer.document.open();
				layer.document.write(html);
				layer.document.close();
				layer.top = document.height;
				document.height += layer.document.height;
				layer.visibility = 'show';
			}
		}
	};

	//updates the inner html of the element.
	this.UpdateInnerHTML = function (element, html)
	{
		///	<summary>
		///	Updates the inner HTML of the supplied element
		///	</summary>
		/// <param name="element" type="string"> id or element to update the innerHTML.</param> 
		/// <param name="html" type="string"> HTML to update the innerHTML into the page.</param> 
		/// <returns type="void" />



		element = GetElementById(element);

		if (element)
		{
			element.innerHTML = html;
		}
	};
	this.UpdateOuterHTML = function (elementId, html, insertElementIfNonExistent, outerElementId)
	{
		///	<summary>
		///	 Updates the outer HTML of the supplied element
		///	</summary>
		///	<param name="elementId" type="string"> id or element to update the outer HTML.</param>
		///	<param name="outerHTML" type="string"> HTML to set as the outer HTML.</param>
		///	<param name="insertElementIfNonExistent" type="bool"> flag indicating whether or not the insert the element into the DOM if it does not exist (default false).</param>
		///	<param name="outerElementId" type="string"> optional id or element which is a potential outer id, or alternative for the ID.  If set the method looks for the presence of the outer element to replace it instead of the inner element id.</param>
		/// <returns type="void" />

		UpdateOuterHTML(elementId, html, insertElementIfNonExistent, outerElementId);
	};

	//removes the element from the DOM
	this.RemoveElementFromDOM = function (element)
	{
		///	<summary>
		///	 Removes the supplied element from the DOM
		///	</summary>
		///	<param name="element" type="string"> id or element to remove from the DOM.</param>
		///<returns type="void" />

		element = GetElementById(element);

		if (element)
		{
			$(element).remove();
		}

	};


	this.CancelBubble = function (localEvent)
	{

		///	<summary>
		///	 Cancels bubbling the event up the DOM to outer elements.
		///	</summary>
		///	<param name="localEvent" type="event"> local event to apply the cancel bubble to.</param>
		/// <returns type="bool">returns false</returns>

		if (localEvent == null && window.event)
		{
			localEvent = window.event;
		}
		if (localEvent)
		{
			localEvent.cancelBubble = true;
			localEvent.returnValue = false;

			if (localEvent.stopPropagation)
			{
				localEvent.stopPropagation();
				localEvent.preventDefault();
			}
		}

		return false;
	};

	//Drags an element (requires drag and drop libary present)
	//The MetafuseLayer control uses this method
	this.DragElement = function (localEvent, elementId)
	{
		///	<summary>
		/// Simple method allows the dragging of the supplied element.  Use MetafuseDragDrop.js for more complex dragging operations
		///	</summary>
		///	<param name="localEvent" type="event"> local event of the mouse down.</param>
		/// <param name="elementId" type="string"> id or element to allow dragging on.</param>	
		/// <returns type="bool">returns false if dragging otherwise void</returns>

		var element = GetElementById(elementId);

		//Only allow the left button to move layer.
		//The middle button in IE creates an error that hangs the IE iFrame shim.
		//
		if (localEvent.button)
		{
			if (localEvent.button != "1")
			{
				return;
			}
		}
		else if (localEvent.which)
		{
			if (localEvent.which != "1")
			{
				return;
			}
		}

		if (element.parentNode != "BODY" && element.parentNode != "FORM")
		{
			//make sure the element is shown where it is shown
			//if(element.style.top == null || element.style.left == null)
			//{
			this.ShowDivAndIFrameAtElement(element, element);
			//}
			element.parentNode.removeChild(element);
			document.forms[0].appendChild(element);
		}

		//__Dump(element, true);
		//__Dump(element.parentNode, true);
		//__Dump(element.parentNode.parentNode, true);

		var dragObject = new MetafuseGenericDragObject();
		dragObject.StartDrag(localEvent, GetElementById(elementId));
		return false;
	};

	//finds the first instance of the particular type of parent node for the element
	this.GetParentNodeByTagName = function (elementId, tagName)
	{
		///	<summary>
		/// Gets the parent node by the supplied tag name
		///	</summary>
		/// <param name="elementId" type="string"> id or element to look at parent nodes to obtain the parent for.</param>	
		/// <param name="tagName" type="string"> tag name to look for, (for example DIV or TR).</param>	
		/// <returns type="element"> returns the parent node matching the tag, null if the parent is not found.</returns>


		var element = GetElementById(elementId);
		var parentNode = element;
		while (parentNode != null)
		{
			//if the node matches the tag name we're looking for (like a row)
			if (parentNode.nodeName == tagName)
			{
				return parentNode;
			}

			parentNode = parentNode.parentNode;
		}
		//if it can't be found then null
		return null;
	};

	//finds the first instance of the particular type of child node for the element
	this.GetChildNodeByTagName = function (elementId, tagName)
	{
		///	<summary>
		/// Gets the first child node by the supplied tag name
		///	</summary>
		/// <param name="elementId" type="string"> id or element to look at parent nodes to obtain the parent for.</param>	
		/// <param name="tagName" type="string"> tag name to look for, (for example DIV or TR).</param>	
		/// <returns type="element"> returns the parent node matching the tag, null if the parent is not found.</returns>

		var element = GetElementById(elementId);

		if (element.nodeName == tagName)
		{
			return element;
		}

		//now look at each of the child nodes of the current node to see if the child node exists
		for (var i = 0; i < element.childNodes.length; i++)
		{
			var childNode = element.childNodes[i];

			if (childNode.nodeName == tagName)
			{
				return childNode;
			}
		}

		//we didn't find one matching, now check each child node of the children
		for (var i = 0; i < element.childNodes.length; i++)
		{
			var childNode = element.childNodes[i];

			var matchingNode = UITools.GetChildNodeByTagName(childNode, tagName);

			if (matchingNode != null)
			{
				return matchingNode;
			}
		}

		//if it can't be found then null
		return null;
	};

	//move the date picker
	this.MoveElement = function (element, newParentNode)
	{
		///	<summary>
		/// Moves the element to a new parent. 
		///	</summary>
		/// <param name="element" type="string"> id or element to move.</param>	
		/// <param name="newParentNode" type="string"> id or element to move the element to.</param>	
		/// <returns type="void" />
		element = GetElementById(element);
		newParentNode = GetElementById(newParentNode);




		if (element && newParentNode)
		{
			if (element.parentNode != newParentNode)
			{
				element.parentNode.removeChild(element);
				newParentNode.appendChild(element);
			}
		}
	};







};

//construct the namespace and object
var UITools = new UITools();


function GlobalF1KeyInvokeContextHelp() { };
function GlobalKeyDown(event)
{
	///	<summary>
	///	 Method invoked by the document global key down event.  Keeps track of shift key and control key used by multiple javascript libraries. Provides a universal way of determine if the shift and control key is currently pressed.
	///	</summary>
	///	<param name="event" type="event"> event passed in fron the event handler</param>
	/// <returns type="void" />

	var keyCode = UITools.GetKeyDown(event);

	if (keyCode == 112)
	{
		GlobalF1KeyInvokeContextHelp();
		return UITools.CancelBubble(event);
	}
	if (keyCode == 16)//Shift
	{
		UITools.GlobalIsShiftKeyDown = true;
	}
	if (keyCode == 17)//Control
	{
		UITools.GlobalIsControlKeyDown = true;
	}

	//if (keyCode == 17)
	//{
	//	metafuseGlobalLinkOpenInNewWindow = true;
	//}
};
function GlobalKeyUp(event)
{
	///	<summary>
	///	 Method invoked by the document global key up event.  Keeps track of shift key and control key used by multiple javascript libraries. Provides a universal way of determine if the shift and control key is currently pressed.
	///	</summary>
	///	<param name="event" type="event"> event passed in fron the event handler</param>
	/// <returns type="void" />
	var keyCode = UITools.GetKeyUp(event);
	if (keyCode == 16)//Shift
	{
		UITools.GlobalIsShiftKeyDown = false;
	}
	if (keyCode == 17)//Control
	{
		metafuseGlobalLinkOpenInNewWindow = false;
		UITools.GlobalIsControlKeyDown = false;
	}
};
function GlobalAddKeyDownAndKeyUpEventsToDocument()
{
	///	<summary>
	/// Method which hooks up the GlobalKeyDown and GlobalKeyUp functions to the document, watching the shift and control keys.
	///	</summary>
	/// <returns type="void" />
	AddEventHandlerToElement(document, "onkeydown", GlobalKeyDown, false);
	AddEventHandlerToElement(document, "onkeyup", GlobalKeyUp, false);

	window.onhelp = function (event) { return UITools.CancelBubble(event); };

};
//add to the onload for the page to hookup the key down and key up events
OnLoad.AddFunction(GlobalAddKeyDownAndKeyUpEventsToDocument);


//constructor for form tools
function FormTools()
{
	///<summary>
	/// Global object which contains form tool elements, used to work with form input controls
	///</summary>
	///<returns type="void"/>

	//updates the select options for a select input
	this.UpdateSelectOptions = function (selectClientID, selectListArray)
	{
		///<summary>
		/// Updates the select options for a standard drop down control
		///</summary>
		///<param name="selectClientID" type="string"> id or drop down element to set the options to</param>
		///<param name="selectListArray" type="Array"> of select options (object.Value and object.Text) to set to the control.</param>
		///<returns type="void"/>
		var selectElement = GetElementById(selectClientID);

		if (selectElement)
		{
			this.SelectOptionsClear(selectElement);

			if (selectListArray)
			{
				for (var i = 0; i < selectListArray.length; i++)
				{
					var e = selectListArray[i];
					var o = new Option(e.Text, e.Value);

					if (e.Selected == "true")
					{
						o.selected = true;
					}
					selectElement.options[selectElement.options.length] = o;
				}
			}
		}
	};

	this.AddAdditionalHiddenElementNamesToAppendToReturnUrl = function (elementName)
	{
		///	<summary>
		///		Adds an element name to the list of elements to monitor and append to the return URL when a link through L is invoked.
		///	</summary>
		///	<param name="elementName" type="string">
		///		Adds the name to the list.
		///	</param>
		/// <returns type="void" />
		if (AdditionalHiddenElementNamesToAppendToReturnUrl == null)
		{
			AdditionalHiddenElementNamesToAppendToReturnUrl = new Array();
		}

		var found = false;
		for (var i = 0; i < AdditionalHiddenElementNamesToAppendToReturnUrl.length; i++)
		{
			if (AdditionalHiddenElementNamesToAppendToReturnUrl[i] == elementName)
			{
				found = true;
				break;
			}
		}

		if (!found)
		{
			AdditionalHiddenElementNamesToAppendToReturnUrl[AdditionalHiddenElementNamesToAppendToReturnUrl.length] = elementName;
		}

	};

	this.SelectMultipleCheckNoneSelected = function (element)
	{
		///<summary>
		/// Selects multiple checkbox to uncheck all checkboxes in the list
		///</summary>
		///<param name="element" type="string"> id or element to uncheck the boxes.</param>
		///<returns type="void"/>

		element = GetElementById(element);
		if (element)
		{
			if (element.length)
			{
				if (element[0].selected == true)
				{
					for (var i = 1; i < element.length; i++)
					{
						element[i].selected = false;
					}
				}
			}
		}
	};

	//clears the select options
	this.SelectOptionsClear = function (selectElement, keepSelected)
	{
		///<summary>
		/// Clears the select options for the drop down list.
		///</summary>
		///<param name="selectElement" type="string"> id or element remove all of the options from.</param>
		///<param name="keepSelected" type="bool"> flag indicating whether or not the leave the selected option in the list.</param>
		///<returns type="void"/>

		selectElement = GetElementById(selectElement);

		if (selectElement)
		{
			var selectedExists = false;
			var i = 0;

			while (selectElement.options && selectElement.options.length > i)
			{

				if (keepSelected == true && selectElement.options[i].selected == true)
				{
					i += 1;
					continue;
				}
				else
				{
					selectElement.options[i] = null;
				}
			}
		}
	};
	//removes a single option from the select options returns if succesful or not
	this.SelectOptionsRemoveOption = function (selectElement, optionValue)
	{
		///<summary>
		/// Removes a specific option from the supplied drop down.
		///</summary>
		///<param name="selectElement" type="string"> id or element remove the specific options from.</param>
		///<param name="optionValue" type="string"> value of the option to remove.</param>
		///<returns type="bool">flag indicating whether or not the option was removed, true if the option was removed</returns>


		selectElement = GetElementById(selectElement);

		if (selectElement)
		{
			for (var i = 0; i < selectElement.options.length; i++)
			{
				var option = selectElement.options[i];

				if (option.value == optionValue)
				{
					selectElement.options[i] = null;
					return true;
					break;
				}
			}
		}
		return false;
	};

	this.GetFormElementType = function (element)
	{
		///<summary>
		/// Gets the form element type.  Used by the "FormTools.GetFormElementValue" etc.
		///</summary>
		///<param name="element" type="string"> id or element to determine the type.</param>
		///<returns type="variant">type of the supplied element</returns>


		var type = null;

		if (element)
		{
			//get the type of element so we now how to get the form element value
			type = element.type;


			if (type == null)
			{
				if (element.length)
				{
					type = element[0].type;
				}
				else
				{

					if (element.className && element.className == "MetafuseComboBox")
					{
						type = element.className;
					}

				}
			}
		}

		return type;
	};

	this.GetFormElementValue = function (element, multipleSelectionValueSeparator)
	{

		///<summary>
		/// Gets the form element value for the supplied element
		///</summary>
		///<param name="element" type="string"> id or element to get the value for</param>
		///<param name="multipleSelectionValueSeparator" type="string"> separator to use when the element can contain multiple selected values (like a list box).</param>
		///<returns type="string">value of the element</returns>


		var element = GetElementById(element);

		if (element)
		{
			//get the type of element so we now how to get the form element value
			var type = this.GetFormElementType(element);

			if (type == null)
			{
				elementForm = document.forms[0][element.id];

				type = this.GetFormElementType(elementForm);

				if (type == null)
				{

					alert("Unable to detect the type of form element for element id: " + element.id + " in GetFormElementValue");

				}
			}


			if (type == "select-multiple" || type == "select-one")
			{
				var values = "";



				//make this work with empty values
				if (element.options)
				{
					var useValue = true;

					if (element.options.length > 1)
					{
						var option1 = element.options[0];
						var option2 = element.options[1];

						if ((option1.value == null || option1.value == "") && (option2.value == null || option2.value == ""))
						{
							useValue = false;
						}
					}

					if (multipleSelectionValueSeparator == null || multipleSelectionValueSeparator == "")
					{
						multipleSelectionValueSeparator = ",";
					}


					for (var i = 0; i < element.options.length; i++)
					{
						if (element.options[i].selected == true)
						{
							if (values.length > 0)
							{
								values += multipleSelectionValueSeparator;
							}
							if (useValue)
							{
								values += element.options[i].value;
							}
							else
							{
								values += element.options[i].text;
							}
							//break out if select one and selected
							if (type == "select-one")
							{
								break;
							}
						}
					}
				}
				return values;
			}
			else if (type == "checkbox")
			{



				if (element.checked)
				{
					//2007-04-13 STW (this may not be the right thing to do but it is needed for multiple checkbox so the element would return the
					//value if one is specified.  
					if (element.value != null && element.value != "")
					{
						return element.value;
					}
					else
					{
						return "on";
					}
				}
			}
			else if (type == "radio")
			{
				//get the element by name so we can loop through it
				var radio = null;

				//newer firefox and safari use the same method as IE
				//if(BrowserTools.IsInternetExplorer())
				//{

				if (element.name)
				{
					var name = new String(element.name);
					radio = document.forms[0][name];
				}

				//try to get the radio by id
				if (radio == null)
				{
					radio = document.forms[0][element.id];
				}

				//if no radio
				if (radio == null)
				{
					//if we don't have an element either then return "" else try the element passed in
					if (element == null)
					{
						return "";
					}
					else
					{
						radio = element;
					}
					//element = document.forms[0][element.id];
				}

				if (radio)
				{
					if (radio.length == null)
					{
						if (radio.checked)
						{
							return radio.value;
						}
					}
					else
					{
						for (var i = 0; i < radio.length; i++)
						{
							var r = radio[i];

							if (r.checked)
							{
								return r.value;
							}
						}
					}
				}
			}
			else if (type == "MetafuseComboBox")
			{
				return FormTools.GetFormElementValue(element.id + "_sv", multipleSelectionValueSeparator);
			}
			else
			{
				return element.value;
			}
		}
		return "";
	};

	this.GetFormElementText = function (clientId)
	{
		///<summary>
		/// Gets the form element text for the supplied element
		///</summary>
		///<param name="element" type="string"> id or element to get the text for</param>
		///<returns type="string">text for the element</returns>


		element = GetElementById(clientId);

		if (element)
		{
			//get the type of element so we now how to get the form element value
			var type = this.GetFormElementType(element);


			if (type == null)
			{

				elementForm = document.forms[0][element.id];

				type = this.GetFormElementType(elementForm);

				if (type == null)
				{
					alert("Unable to detect the type of form element for element id: " + element.id + " in GetFormElementText");
				}
			}


			if (type == "select-multiple" || type == "select-one")
			{
				var values = "";

				if (element.options)
				{
					for (var i = 0; i < element.options.length; i++)
					{
						if (element.options[i].selected == true)
						{
							if (values.length > 0)
							{
								values += ", ";
							}
							values += element.options[i].text;
						}
					}
				}
				return values;
			}
			else if (type == "checkbox")
			{
				if (element.checked)
				{

					//2010-01-26 STW - Should we move this to use the value of the nextSibling if it exists and the sibling is a Label

					//2008-05-17 STW -- I copied this from GetFormElementValue -- may not be right for this as well
					//2007-04-13 STW (this may not be the right thing to do but it is needed for multiple checkbox so the element would return the
					//value if one is specified.  
					//if(element.value != null && element.value != "")
					//{
					//	return element.value;
					//}
					//else
					//{
					return "Yes";
					//}
				}
				else
				{
					return "No";
				}
			}
			else if (type == "radio")
			{
				//get the element by name so we can loop through it
				var radio = null;

				//newer firefox and safari use the same method as IE
				//if(BrowserTools.IsInternetExplorer())
				//{

				if (element.name)
				{
					var name = new String(element.name);
					radio = document.forms[0][name];
				}

				//try to get the radio by id
				if (radio == null)
				{
					radio = document.forms[0][element.id];
				}

				//if no radio
				if (radio == null)
				{
					//if we don't have an element either then return "" else try the element passed in
					if (element == null)
					{
						return "";
					}
					else
					{
						radio = element;
					}
					//element = document.forms[0][element.id];
				}

				if (radio)
				{
					var selectedRadio = null;

					if (radio.length == null)
					{
						if (radio.checked)
						{
							selectedRadio = radio;
						}
					}
					else
					{
						for (var i = 0; i < radio.length; i++)
						{
							var r = radio[i];

							if (r.checked)
							{
								selectedRadio = r;
							}
						}
					}

					if (selectedRadio != null && selectedRadio.parentNode != null)
					{
						var parentNode = selectedRadio.parentNode;

						var labels = parentNode.getElementsByTagName('label');

						if (labels != null && labels.length > 0)
						{
							return labels[0].innerHTML;
						}
						else
						{
							//couldn't find return value
							return this.GetFormElementValue(element);
						}

					}
					else
					{
						//couldn't find, so return value
						return this.GetFormElementValue(element);
					}

				}
			}
			else if (type == "MetafuseComboBox")
			{
				var metafuseComboBoxElement = window[element.id + "_obj"];

				//NOTE the separator for the values is stored with the control for MetafuseComboBox

				//return the results of the GetFormElementText from the control
				if (metafuseComboBoxElement)
				{
					return metafuseComboBoxElement.GetFormElementText();
				}
			}
			else
			{
				//get the form element value unless we can figure out the text
				return this.GetFormElementValue(element);
			}
		}
		return "";
	};

	this.GetFormElementOptionText = function (element, value)
	{
		element = GetElementById(element);
		if (element)
		{
			//get the type of element so we now how to get the form element value
			var type = this.GetFormElementType(element);


			if (type == null)
			{

				elementForm = document.forms[0][element.id];

				type = this.GetFormElementType(elementForm);

				if (type == null)
				{
					alert("Unable to detect the type of form element for element id: " + element.id + " in GetFormElementOptionText");
				}
			}

			if (type == "select-multiple" || "select-one")
			{


				if (element.options)
				{
					for (var i = 0; i < element.options.length; i++)
					{
						if (element.options[i].value.toString() == value.toString())
						{
							return element.options[i].text;
						}
					}
				}

			}
			else
			{
				alert("Unable to get the form element option text for the element supplied " + element.id + " type not supported in GetFormElementOptionText");
			}
		}
		return "";
	};

	//sets the form element value of any form element
	this.SetFormElementValue = function (clientId, value, text, valueSeparator, textSeparator, missionOptionArray, insertOptionsMissing, dropDownSelectWithMatchingValueOrTextOnOptions)
	{
		///<summary>
		/// Sets the form element value for the supplied element.
		///</summary>
		///<param name="clientId" type="string"> id or element to set the value for</param>
		///<param name="value" type="string"> value to set</param>
		///<param name="text" type="string"> text which goes with the supplied value</param>
		///<param name="valueSeparator" type="string"> separator used in the value input to indicate different values when the element allows multiple values (like a list box).</param>
		///<param name="textSeparator" type="string"> separator used in the text input to indicate different values when the element allows multiple values (like list box).</param>
		///<param name="missionOptionArray" type="Array"> of missing options to set.</param>
		///<param name="insertOptionsMissing" type="bool"> flag indicating whether or not to insert the mission options into the element (like a drop down).</param>
		///<param name="dropDownSelectWithMatchingValueOrTextOnOptions" type="bool"> flag indicating whether or not to select a drop down with EITHER the value or text input (default false).</param>
		///<returns type="bool">flag indicating whether or not the element value was successfully set</returns>


		if (value == null)
		{
			return false;
		}

		if (valueSeparator == null)
		{
			valueSeparator = ",";
		}

		var element = GetElementById(clientId);

		var success = false;



		if (element)
		{
			//get the type of element so we now how to get the form element value
			var type = this.GetFormElementType(element);



			if (type == null)
			{
				elementForm = document.forms[0][element.id];

				type = this.GetFormElementType(elementForm);

				if (type == null)
				{
					alert("Unable to detect the type of form element for element id: " + element.id + " in GetFormElementValue");
					//__Dump(elementForm);
				}
			}



			if (type == "select-multiple")
			{

				var valueArray = null;
				var textArray = null;

				//take away a leading space off the separator if there is one
				value = value.replace(valueSeparator + ' ', valueSeparator);
				var valueArray = value.split(valueSeparator);

				if (text)
				{
					//take away a leading space off the separator if there is one
					text = text.replace(textSeparator + ' ', textSeparator);
					textArray = text.split(textSeparator);
				}

				//select multiple...
				if (element.options.length)
				{

					//select the drop own with the value
					var useValue = true;

					//if there is more than one element then this is important, if only one element, that element is selected by default
					if (element.options.length > 1)
					{
						var option1 = element.options[0];
						var option2 = element.options[1];

						//if neither the first nor second element has a value
						if ((option1.value == null || option1.value == "") && (option2.value == null || option2.value == ""))
						{
							useValue = false;
						}
					}


					//loop through the elements 
					for (var i = 0; i < element.options.length; i++)
					{

						var o = element.options[i];
						o.selected = false;

						//loop through the values to see if we can apply them
						for (var ii = 0; ii < valueArray.length; ii++)
						{
							var v = valueArray[ii];

							var foundMatch = false;

							if (useValue)
							{
								if (o.value == v)
								{
									o.selected = true;
									foundMatch = true;
								}
								else if (o.value == "" && v == "")
								{
									o.selected = true;
									foundMatch = true;
								}
								//if we're using the text or the value then see if the text matches the value, if so select
								//this is used by the MetafuseTable with CustomFields that have GUIDs in them, the metafuse table
								//outputs the text into the table, but the drop down for users, companies, groups etc have guids
								//used for the value property... which is what we want for selected, but to select it we want to match the text here
								else if (dropDownSelectWithMatchingValueOrTextOnOptions && o.text == v)
								{
									o.selected = true;
									foundMatch = true;
								}
							}
							else
							{

								if (o.text.toString() == v.toString())
								{
									o.selected = true;
									foundMatch = true;
								}
								else if (o.text == "" && v == "")
								{
									o.selected = true;
									foundMatch = true;
								}
							}

							//if the match was found, then remove the value from the list
							if (foundMatch)
							{

								valueArray.splice(ii, 1);

								if (textArray)
								{
									textArray.splice(ii, 1);
								}
								break;
							}

						}




					}

				}



				//if we're going to insert options, then get into this method
				if (valueArray.length > 0)
				{
					if (missionOptionArray != null || insertOptionsMissing)
					{
						if (missionOptionArray == null)
						{
							missionOptionArray = new Array();

						}
						for (var i = 0; i < valueArray.length; i++)
						{
							var v = valueArray[i];
							var t = v;
							if (textArray && textArray.length > i)
							{
								t = textArray[i];
							}

							var opt = { text: t, value: v };
							missionOptionArray[missionOptionArray.length] = opt;
						}
					}

					if (insertOptionsMissing && missionOptionArray.length > 0)
					{

						for (var i = missionOptionArray.length - 1; i >= 0; i--)
						{
							var missingOption = missionOptionArray[i];
							FormTools.InsertFormElementValueAndText(element, missingOption.value, missingOption.text, true, 0);
						}
						success = true;

					}

				}
				else
				{
					//we were able to add all of the items
					success = true;
				}

			}

			else if (type == "select-one")
			{

				if (element.options.length)
				{


					//select the drop down with the value
					var useValue = true;

					//if there is more than one element then this is important, if only one element, that element is selected by default
					if (element.options.length > 1)
					{
						var option1 = element.options[0];
						var option2 = element.options[1];

						//if neither the first nor second element has a value
						if ((option1.value == null || option1.value == "") && (option2.value == null || option2.value == ""))
						{
							useValue = false;
						}
					}


					//loop through the values to find selected ones
					for (var i = 0; i < element.options.length; i++)
					{
						var o = element.options[i];


						//using the value
						if (useValue)
						{

							if (o.value.toString() == value.toString())
							{
								o.selected = true;
								success = true;
							}
							else if (o.value == "" && value == "")
							{
								o.selected = true;
								success = true;
							}
							//if we're using the text or the value then see if the text matches the value, if so select
							//this is used by the MetafuseTable with CustomFields that have GUIDs in them, the metafuse table
							//outputs the text into the table, but the drop down for users, companies, groups etc have guids
							//used for the value property... which is what we want for selected, but to select it we want to match the text here
							else if (dropDownSelectWithMatchingValueOrTextOnOptions && o.text == value)
							{
								o.selected = true;
								success = true;
							}

						}
						else
						{

							if (o.text.toString() == value.toString())
							{
								o.selected = true;
								success = true;
							}
							else if (o.text == "" && value == "")
							{
								o.selected = true;
								success = true;
							}

						}


						if (success)
						{
							break;
						}
					}
				}


				//if we didn't successfully find the 
				if (!success)
				{
					if (missionOptionArray)
					{
						var opt = { text: text, value: value };
						missionOptionArray[missionOptionArray.length] = opt;
					}

					if (insertOptionsMissing)
					{
						FormTools.InsertFormElementValueAndText(element, value, text, true, 0);
						success = true;
					}

				}

			}

			else if (type == "checkbox")
			{
				value = value.toLowerCase();

				if (value == "on" || value == "true" || value == "1" || value == "checked" || value == "yes" || value == "active")
				{
					element.checked = true
					success = true;

				}
				else
				{
					element.checked = false;
					success = true;
				}
			}

			else if (type == "radio")
			{

				var radio = null;

				//STW 2006-12-28 
				//changed to reflect the GetFormElementValue method, safari and firefox now follow IE rules here
				if (element.name)
				{
					var name = new String(element.name);
					radio = document.forms[0][name];
				}

				if (radio == null)
				{
					//try to get the radio by id
					radio = document.forms[0][element.id];

					if (radio == null && element != null)
					{
						radio = element;
					}
				}

				if (radio)
				{
					if (radio.length == null)
					{
						if (radio.value == value)
						{
							radio.checked = true;
							success = true;

						}
					}
					else
					{
						for (var i = 0; i < radio.length; i++)
						{
							var r = radio[i];

							if (r.value == value)
							{
								r.checked = true;
								success = true;
							}
						}
					}
				}
			}

			else if (type == "MetafuseComboBox")
			{
				var metafuseComboBoxElement = window[element.id + "_obj"];

				//NOTE the separator for the values is stored with the control for MetafuseComboBox

				//return the results of the SetFormElementValue from the control
				if (metafuseComboBoxElement)
				{
					//the separators for the values and text is set with the control.
					return metafuseComboBoxElement.SetFormElementValue(value, text, missionOptionArray, insertOptionsMissing);
				}
			}
			else
			{
				element.value = value;
				success = true;
			}

		}

		return success;
	};


	//inserts the value and text from a control
	this.InsertFormElementValueAndText = function (elementId, value, text, defaultSelected, index)
	{

		///<summary>
		/// Inserts a new option with the supplied value and text into the supplied element.
		///</summary>
		///<param name="elementId" type="string"> id or element to insert the new option into</param>
		///<param name="value" type="string"> value to set insert</param>
		///<param name="text" type="string"> text which goes with the supplied value</param>
		///<param name="defaultSelected" type="bool"> flag indicating whether or not the new inserted value should be selected.</param>
		///<param name="index" type="int"> index position to insert the new value and text to.</param>
		///<returns type="void"> returns null</returns>



		var element = GetElementById(elementId);


		if (element)
		{
			//get the type of element so we now how to get the form element value
			var type = this.GetFormElementType(element);

			if (type == null)
			{
				elementForm = document.forms[0][element.id];

				type = this.GetFormElementType(elementForm);

				if (type == null)
				{
					alert("Unable to detect the type of form element for element id: " + element.id + " in GetFormElementValue");
					//__Dump(elementForm);
				}
			}
			else if (type == "select-one" || type == "select-multiple")
			{

				var newOption = new Option(text, value);


				if (defaultSelected)
				{
					newOption.selected = true;
				}

				if (element.length > 0)
				{
					if (index == null || index < 0)
					{
						index = 0;
					}
					else if (index > element.length)
					{
						index = element.options.length;
					}

					var existingOption = element.options[index];

					try
					{
						element.add(newOption, existingOption);
					}
					catch (ex)
					{
						element.add(newOption, index);
					}

				}
				else
				{
					//add one to the end
					element.options[0] = newOption;
				}

			}
			else if (type == "MetafuseComboBox")
			{
				var metafuseComboBoxElement = window[element.id + "_obj"];
				if (metafuseComboBoxElement)
				{
					metafuseComboBoxElement.AddAvailableRow(value, text, defaultSelected);
				}
			}
			else
			{
				alert("insert form field and text not implemented for element type: " + type + " id: " + element.id + " value: " + value + " text: " + text);
			}
		}

		return null;
	};

	//removes the value and text from a control (select)
	this.RemoveFormElementValueAndText = function (elementId, value, text)
	{

		///<summary>
		/// Removes an option with the supplied value and text from the supplied element.
		///</summary>
		///<param name="elementId" type="string"> id or element to insert the new option into</param>
		///<param name="value" type="string"> value to remove</param>
		///<param name="text" type="string"> text which goes with the supplied value</param>
		///<returns type="void"> returns null</returns>


		var element = GetElementById(elementId);

		if (element)
		{
			//get the type of element so we now how to get the form element value
			var type = this.GetFormElementType(element);

			if (type == null)
			{
				elementForm = document.forms[0][element.id];

				type = this.GetFormElementType(elementForm);

				if (type == null)
				{
					alert("Unable to detect the type of form element for element id: " + element.id + " in GetFormElementValue");
					//__Dump(elementForm);
				}
			}
			else if (type == "select-one" || type == "select-multiple")
			{
				var start = element.options.length - 1;
				for (var i = start; i >= 0; i--)
				{
					var o = element.options[i];

					if (o)
					{
						//if we have a value check the value
						if (value != null)
						{
							if (o.value != null && o.value == value)
							{
								element.options[i] = null;
							}
						}
						//if we have text but no value check the text 
						else if (text != null)
						{
							if (o.text != null && o.text == text)
							{
								element.options[i] = null;
							}
						}
					}
				}
			}
			else if (type == "MetafuseComboBox")
			{
				var metafuseComboBoxElement = window[element.id + "_obj"];
				if (metafuseComboBoxElement)
				{
					metafuseComboBoxElement.RemoveAvailableRow(value, text);
				}
			}
			else
			{
				alert("remove form field and text not implemented for element type: " + type);
			}
		}
	};

	//sets the value using set timeout so that the onchange will still be recongized (like user input)
	this.SetValueUsingSetTimeout = function (elementId, value)
	{

		///<summary>
		/// Sets the form element value using set timeout.
		///</summary>
		///<param name="elementId" type="string"> id or element to set the value for</param>
		///<param name="value" type="string"> value to remove</param>
		///<returns type="void"/ >


		var element = GetElementById(elementId);

		if (element)
		{
			var s = new String("");
			if (value)
			{
				s = value.toString();
			}
			//setTimeout("GetElementById('" + element.id + "').value=\"" + s.replace(/\"/g, "\\\"") + "\"", 0);
			setTimeout("FormTools.SetFormElementValue('" + element.id + "',\"" + s.replace(/\"/g, "\\\"") + "\")", 0);

		}
	};


	//focuses and clicks an element using set timeout (does not work with Safari when created)
	this.FocusAndClickElementUsingSetTimeout = function (element)
	{
		///<summary>
		/// OLDER METHOD Sets focus and clicks on the element using set timeout
		///</summary>
		///<param name="elementId" type="string"> id or element to focus and click</param>
		///<returns type="void"/ >


		var element = GetElementById(element);
		if (element)
		{
			setTimeout("GetElementById('" + element.id + "').focus()", 0);
			//delay here so that javascript functions can get completed before submitting 
			//STW 2008-11-21 Changed timeout time to 300, from 500.
			setTimeout("UITools.ClickElement('" + element.id + "')", 300);
		}
	};



	/********************************************************************
	* Form Element Formatting (Ensure in Format called after onChange);
	*********************************************************************/

	//ensures that the element has a valid currency (normally text boxes)
	this.EnsureCurrency = function (element, blankNotAllowed, excludeCommas, excludeLeadingZero, excludeTrailingZeros, scale)
	{
		///	<summary>
		/// Ensures the element has a valid currency string.  Generally used for text controls onchange event.
		///	</summary>
		///	<param name="element" type="string"> id or element the ensure method is connected to.</param>
		///	<param name="blankNotAllowed" type="bool"> flag indicating whether or not blank is allowed.</param>
		///	<param name="excludeCommas" type="bool"> flag indicating whether or not to exclude commas, if null, then takes the default set on the object</param>
		///	<param name="excludeLeadingZero" type="bool"> flag indicating whether or not to exclude leading zeros, if null, then takes the default set on the object.</param>
		///	<param name="excludeTrailingZeros" type="bool"> flag indicating whether or not to exclude trailing zeros, if null, then takes the default set on the object.</param>
		///	<param name="scale" type="int"> scale of the number (number of decimal places), if null, then takes the default set on the object.</param>
		/// <returns type="void" /> 




		var value = FormTools.GetFormElementValue(element);

		//get the decimal string
		var currencyString = MathTools.FormatCurrencyString(value, !blankNotAllowed, excludeCommas, excludeLeadingZero, excludeTrailingZeros, scale);

		if (value != currencyString)
		{
			FormTools.SetValueUsingSetTimeout(element, currencyString);
		}
	};

	//ensures that the element has a valid currency (normally text boxes)
	this.EnsurePositiveCurrency = function (element, blankNotAllowed, excludeCommas, excludeLeadingZero, excludeTrailingZeros, scale)
	{

		///	<summary>
		/// Ensures the element has a POSITIVE valid currency string.  Generally used for text controls onchange event.
		///	</summary>
		///	<param name="element" type="string"> id or element the ensure method is connected to.</param>
		///	<param name="blankNotAllowed" type="bool"> flag indicating whether or not blank is allowed.</param>
		///	<param name="excludeCommas" type="bool"> flag indicating whether or not to exclude commas, if null, then takes the default set on the object</param>
		///	<param name="excludeLeadingZero" type="bool"> flag indicating whether or not to exclude leading zeros, if null, then takes the default set on the object.</param>
		///	<param name="excludeTrailingZeros" type="bool"> flag indicating whether or not to exclude trailing zeros, if null, then takes the default set on the object.</param>
		///	<param name="scale" type="int"> scale of the number (number of decimal places), if null, then takes the default set on the object.</param>
		/// <returns type="void" /> 

		var value = FormTools.GetFormElementValue(element);

		//get the decimal string
		var currencyString = MathTools.FormatCurrencyString(value, !blankNotAllowed, excludeCommas, excludeLeadingZero, excludeTrailingZeros, scale, true);

		if (value != currencyString)
		{
			FormTools.SetValueUsingSetTimeout(element, currencyString);
		}
	};

	//ensures the element input is a decimal (normally text boxes)
	this.EnsureDecimal = function (element, blankNotAllowed, excludeCommas, excludeLeadingZero, excludeTrailingZeros, scale)
	{
		///	<summary>
		/// Ensures the element has a valid decimal string.  Generally used for text controls onchange event.
		///	</summary>
		///	<param name="element" type="string"> id or element the ensure method is connected to.</param>
		///	<param name="blankNotAllowed" type="bool"> flag indicating whether or not blank is allowed.</param>
		///	<param name="excludeCommas" type="bool"> flag indicating whether or not to exclude commas, if null, then takes the default set on the object</param>
		///	<param name="excludeLeadingZero" type="bool"> flag indicating whether or not to exclude leading zeros, if null, then takes the default set on the object.</param>
		///	<param name="excludeTrailingZeros" type="bool"> flag indicating whether or not to exclude trailing zeros, if null, then takes the default set on the object.</param>
		///	<param name="scale" type="int"> scale of the number (number of decimal places), if null, then takes the default set on the object.</param>
		/// <returns type="void" /> 

		//get the form element value
		var value = FormTools.GetFormElementValue(element);

		//get the decimal string
		var decimalString = MathTools.FormatDecimalString(value, !blankNotAllowed, excludeCommas, excludeLeadingZero, excludeTrailingZeros, scale);

		//if it's different then update it
		if (value != decimalString)
		{
			FormTools.SetValueUsingSetTimeout(element, decimalString);
		}

	};

	//ensures the element input is a positive decimal (normally text boxes)
	this.EnsurePositiveDecimal = function (element, blankNotAllowed, excludeCommas, excludeLeadingZero, excludeTrailingZeros, scale)
	{
		///	<summary>
		/// Ensures the element has a POSITIVE valid decimal string.  Generally used for text controls onchange event.
		///	</summary>
		///	<param name="element" type="string"> id or element the ensure method is connected to.</param>
		///	<param name="blankNotAllowed" type="bool"> flag indicating whether or not blank is allowed.</param>
		///	<param name="excludeCommas" type="bool"> flag indicating whether or not to exclude commas, if null, then takes the default set on the object</param>
		///	<param name="excludeLeadingZero" type="bool"> flag indicating whether or not to exclude leading zeros, if null, then takes the default set on the object.</param>
		///	<param name="excludeTrailingZeros" type="bool"> flag indicating whether or not to exclude trailing zeros, if null, then takes the default set on the object.</param>
		///	<param name="scale" type="int"> scale of the number (number of decimal places), if null, then takes the default set on the object.</param>
		/// <returns type="void" /> 


		var value = FormTools.GetFormElementValue(element);

		//get the form element value
		var value = FormTools.GetFormElementValue(element);

		//get the decimal string
		var decimalString = MathTools.FormatDecimalString(value, !blankNotAllowed, excludeCommas, excludeLeadingZero, excludeTrailingZeros, scale, true);

		//if it's different then update it
		if (value != decimalString)
		{
			FormTools.SetValueUsingSetTimeout(element, decimalString);
		}
	};

	//ensures the element input is an integer (normally text boxes)
	this.EnsureInteger = function (element, blankNotAllowed, excludeCommas)
	{
		///	<summary>
		/// Ensures the element has a valid integer string.  Generally used for text controls onchange event.
		///	</summary>
		///	<param name="element" type="string"> id or element the ensure method is connected to.</param>
		///	<param name="blankNotAllowed" type="bool"> flag indicating whether or not blank is allowed.</param>
		///	<param name="excludeCommas" type="bool"> flag indicating whether or not to exclude commas, if null, then takes the default set on the object</param>
		/// <returns type="void" /> 


		//get the form element value
		var value = FormTools.GetFormElementValue(element);

		//get the decimal string
		var integerString = MathTools.FormatDecimalString(value, !blankNotAllowed, excludeCommas, false, false, 0);

		//if it's different then update it
		if (value != integerString)
		{
			FormTools.SetValueUsingSetTimeout(element, integerString);
		}
	};

	//ensures the element input is a positive integer (normally text boxes)
	this.EnsurePositiveInteger = function (element, blankNotAllowed, excludeCommas)
	{
		///	<summary>
		/// Ensures the element has a valid POSITIVE integer string.  Generally used for text controls onchange event.
		///	</summary>
		///	<param name="element" type="string"> id or element the ensure method is connected to.</param>
		///	<param name="blankNotAllowed" type="bool"> flag indicating whether or not blank is allowed.</param>
		///	<param name="excludeCommas" type="bool"> flag indicating whether or not to exclude commas, if null, then takes the default set on the object</param>
		/// <returns type="void" /> 


		//get the form element value
		var value = FormTools.GetFormElementValue(element);

		//get the decimal string
		var integerString = MathTools.FormatDecimalString(value, !blankNotAllowed, excludeCommas, false, false, 0, true);

		//if it's different then update it
		if (value != integerString)
		{
			FormTools.SetValueUsingSetTimeout(element, integerString);
		}
	};


	//ensures the element input is a percent (normally text boxes)
	this.EnsurePercent = function (element, blankNotAllowed, excludeLeadingZero, excludeTrailingZeros, scale)
	{
		///	<summary>
		/// Ensures the element has a valid percent string.  Generally used for text controls onchange event.
		///	</summary>
		///	<param name="element" type="string"> id or element the ensure method is connected to.</param>
		///	<param name="blankNotAllowed" type="bool"> flag indicating whether or not blank is allowed.</param>
		///	<param name="excludeLeadingZero" type="bool"> flag indicating whether or not to exclude leading zeros, if null, then takes the default set on the object.</param>
		///	<param name="excludeTrailingZeros" type="bool"> flag indicating whether or not to exclude trailing zeros, if null, then takes the default set on the object.</param>
		///	<param name="scale" type="int"> scale of the number (number of decimal places), if null, then takes the default set on the object.</param>
		/// <returns type="void" /> 


		var value = FormTools.GetFormElementValue(element);

		var percentString = MathTools.FormatPercentString(value, !blankNotAllowed, excludeLeadingZero, excludeTrailingZeros, scale);

		if (value != percentString)
		{
			FormTools.SetValueUsingSetTimeout(element, percentString);
		}
	};


	//moves the items in the list up
	this.SelectBoxMoveSelectedItemsUp = function (selectElement)
	{
		///	<summary>
		/// Moves the selected items in a list box up
		///	</summary>
		///	<param name="selectElement" type="string"> id or element to move the selected items up in.</param>
		/// <returns type="void" /> 

		//get the select element
		selectElement = GetElementById(selectElement);
		var optionsToMove = new Array();
		var firstMoveOptionIndex = -1;
		var optionOrder = new Array();
		var optionMoved = false;

		for (var i = selectElement.options.length - 1; i >= 0; i--)
		{

			var currentOption = selectElement.options[i];

			if (currentOption.selected == true && (i > 0))
			{
				if (optionsToMove.length == 0)
				{
					firstMoveOptionIndex = i;
				}
				optionsToMove[optionsToMove.length] = currentOption;

			}
			else if (optionsToMove.length > 0)
			{
				optionMoved = true;
				optionOrder[optionOrder.length] = currentOption;

				for (var ii = 0; ii < optionsToMove.length; ii++)
				{
					optionOrder[optionOrder.length] = optionsToMove[ii];
				}

				//clear the options to move
				optionsToMove = new Array();
			}
			else
			{
				optionOrder[optionOrder.length] = currentOption;
			}
		}

		//if any were moved, rebind the list
		if (optionMoved == true)
		{
			while (selectElement.options.length > 0)
			{
				selectElement.options[0] = null;
			}
			for (var i = optionOrder.length - 1; i >= 0; i--)
			{
				selectElement.options[selectElement.options.length] = optionOrder[i];
			}
		}
	};


	this.SelectBoxMoveSelectedItemsDown = function (selectElement)
	{
		///	<summary>
		/// Moves the selected items in a list box down
		///	</summary>
		///	<param name="selectElement" type="string"> id or element to move the selected items down in.</param>
		/// <returns type="void" /> 



		selectElement = GetElementById(selectElement);
		var optionsToMove = new Array();
		var firstMoveOptionIndex = -1;
		var optionOrder = new Array();
		var optionMoved = false;

		for (var i = 0; i < selectElement.options.length; i++)
		{

			var currentOption = selectElement.options[i];

			if (currentOption.selected == true && (i + 1 < selectElement.options.length))
			{
				if (optionsToMove.length == 0)
				{
					firstMoveOptionIndex = i;
				}
				optionsToMove[optionsToMove.length] = currentOption;

			}
			else if (optionsToMove.length > 0)
			{
				optionMoved = true;

				optionOrder[optionOrder.length] = currentOption;

				for (var ii = 0; ii < optionsToMove.length; ii++)
				{
					optionOrder[optionOrder.length] = optionsToMove[ii];
				}

				//clear the options to move
				optionsToMove = new Array();
			}
			else
			{
				optionOrder[optionOrder.length] = currentOption
			}
		}

		//if any were moved, rebind the list
		if (optionMoved == true)
		{
			while (selectElement.options.length > 0)
			{
				selectElement.options[0] = null;
			}
			for (var i = 0; i < optionOrder.length; i++)
			{
				selectElement.options[selectElement.options.length] = optionOrder[i];
			}
		}
	};

	//sorts a select box by the text as string
	this.SortSelectByTextAsString = function (selectElement)
	{
		///	<summary>
		/// Sorts the select list by string text
		///	</summary>
		///	<param name="selectElement" type="string"> id or element to sort the selected items.</param>
		/// <returns type="void" /> 

		selectElement = GetElementById(selectElement);
		if (selectElement.options.length > 1)
		{
			//load the array
			var a = new Array();
			for (var i = 0; i < selectElement.options.length; i++)
			{
				a[a.length] = selectElement.options[i];
			}

			//sort the array by text
			a.sort(FormTools.CompareSelectTextAsString);

			//clear the select box elements
			while (selectElement.options.length > 0)
			{
				selectElement.options[0] = null;
			}
			//add the sorted array back to the select	
			for (var i = 0; i < a.length; i++)
			{

				selectElement.options[selectElement.options.length] = a[i];
			}
		}
	};

	this.CompareSelectTextAsString = function (optionA, optionB)
	{
		///	<summary>
		/// Compares the select box options text values (like a compare to for option a and option b)
		///	</summary>
		///	<param name="optionA" type="Option"> a option to compare.</param>
		///	<param name="optionA" type="Option"> b option to compare.</param>
		/// <returns type="int"> returns 0 if equal, -1 if a is less than b, or 1 if b is greater than a</returns>

		// text comparison
		if (optionA.text == optionB.text)
		{
			return 0;
		}
		else
		{
			if (optionA.text < optionB.text)
			{
				return -1;
			}
			else
			{
				return 1;
			}
		}
	};




	//sets the checkbox label text dynamically.
	this.SetCheckboxLabelText = function (checkbox, text)
	{


		///	<summary>
		///	 Sets the ASP.NET label for a text box.
		///	</summary>
		///	<param name="stringToStrip" type="string">string to strip HTML from</param>
		/// <returns type="string"> which is stripped of HTML characters</return>
		checkbox = GetElementById(checkbox);

		if (checkbox && FormTools.GetFormElementType(checkbox) == "checkbox" && checkbox.nextSibling && checkbox.nextSibling.tagName == "LABEL")
		{
			checkbox.nextSibling.innerHTML = text;
		}
	};





	//opens a new location with form post (optionally opening a new window)
	this.WindowOpenWithPost = function (url, params, name, windowoption)
	{
		///	<summary>
		/// Performs an open browser window with a form post
		///	</summary>
		///	<param name="url" type="string"> URL to invoke.</param>
		///	<param name="params" type="Array"> of parameters to add to the form (STW NOTE: unsure of structure of input).</param>
		///	<param name="name" type="string"> name of the window.</param>
		///	<param name="windowoption" type="object"> features</param>
		/// <returns type="void"/>


		var form = document.createElement("form");
		form.setAttribute("method", "post");
		form.setAttribute("action", url);
		if (name != null)
		{
			form.setAttribute("target", name);
		}

		if (params != null)
		{
			for (var i in params)
			{
				if (params.hasOwnProperty(i))
				{
					var input = document.createElement('input');
					input.type = 'hidden';
					input.name = i;
					input.value = params[i];
					form.appendChild(input);
				}
			}
		}

		document.body.appendChild(form);

		//only if we are opening a new window
		if (name != null)
		{
			//note I am using a post.htm page since I did not want to make double request to the page 
			//it might have some Page_Load call which might screw things up.
			window.open(Root + "/post.htm", name, windowoption);
		}

		form.submit();
		document.body.removeChild(form);
	};

	this.Trim = function (stringToTrim)
	{
		///	<summary>
		///	 Trims white space from the left and right side of a string, using a regular expression
		///	</summary>
		///	<param name="stringToTrim" type="string">string to trim</param>
		/// <returns type="string"> which is trimmed</return>
		return Utils.Trim(stringToTrim);
	};
	this.LTrim = function (stringToTrim)
	{
		///	<summary>
		///	 Trims white space from the left side of a string, using a regular expression
		///	</summary>
		///	<param name="stringToTrim" type="string">string to trim</param>
		/// <returns type="string"> which is trimmed</return>
		return Utils.LTrim(stringToTrim);
	};
	this.RTrim = function (stringToTrim)
	{
		///	<summary>
		///	 Trims white space from the right side of a string, using a regular expression
		///	</summary>
		///	<param name="stringToTrim" type="string">string to trim</param>
		/// <returns type="string"> which is trimmed</return>
		return Utils.RTrim(stringToTrim);
	};


};

//create the form tools namespace
var FormTools = new FormTools();

/******************************************************
Utilities
*******************************************************/
function Utils()
{
	///	<summary>
	///	Global utility object holds basic utility functions.
	///	</summary>
	/// <returns type="void"/>
	/// <field name="DateTime" type="UTils.DaetTime"> date time object.</field>

	this.DateTime = new Utils.DateTime();

	//URL: blog.stevenlevithan.com/archives/faster-trim-javascript
	//1.return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); (fastest according to the link above)
	//2.return str.replace(/^\s+/, '').replace(/\s+$/, ''); (alternative, second fastest, but most common)


	this.Trim = function (stringToTrim)
	{
		///	<summary>
		///	 Trims white space from the left and right side of a string, using a regular expression
		///	</summary>
		///	<param name="stringToTrim" type="string">string to trim</param>
		/// <returns type="string"> which is trimmed</return>
		if (stringToTrim)
		{
			return stringToTrim.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
		}
		return stringToTrim;

	};
	this.LTrim = function (stringToTrim)
	{
		///	<summary>
		///	 Trims white space from the left side of a string, using a regular expression
		///	</summary>
		///	<param name="stringToTrim" type="string">string to trim</param>
		/// <returns type="string"> which is trimmed</return>
		if (stringToTrim)
		{
			return stringToTrim.replace(/^\s\s*/, '');
		}
		return stringToTrim;
	};
	this.RTrim = function (stringToTrim)
	{
		///	<summary>
		///	 Trims white space from the right side of a string, using a regular expression
		///	</summary>
		///	<param name="stringToTrim" type="string">string to trim</param>
		/// <returns type="string"> which is trimmed</return>
		if (stringToTrim)
		{
			return stringToTrim.replace(/\s\s*$/, '');
		}
		return stringToTrim;
	};

	this.GetNextTableRow = function (row)
	{
		///<summary>Gets the next table row from the supplied row</summary>
		///<param name="row" type="string"> the row object or id of the row to find the next table row</param>
		/// <returns type="object"> next table row</returns>

		//make sure the row supplied is a row
		row = GetElementById(row);

		if (row != null)
		{
			var nextRow = row.nextSibling;

			//STW 2006-06-19 perhaps we could use the rowIndex property for this too like the code below
			while (nextRow != null && nextRow.nodeName != "TR")
			{
				nextRow = nextRow.nextSibling;
			}

			if (nextRow != null && nextRow.nodeName == "TR")
			{
				return nextRow;
			}
		}
		return null;
	};

	/*
	//THIS MAY NOT WORK
	this.StripHTML = function(stringToStrip)
	{
	///	<summary>
	///	 THIS MAY NOT WORK, NEEDS TESTING: Strips HTML tags from the supplied text
	///	</summary>
	///	<param name="stringToStrip" type="string">string to strip HTML from</param>
	/// <returns type="string"> which is stripped of HTML characters</return>
	return stringToStrip.replace(/<[^<|>]+?>/gi, '').replace(/&gt;/gi, ">").replace(/&lt;/gi, "<").replace(/&amp;/gi, "&").replace(/&nbsp;/gi, " ");
	};
	*/
}
Utils.DateTime = function ()
{

	///	<summary>
	///	Global DateTime object, holds date and time functions.
	///	</summary>
	/// <returns type="void"/>

	//not really used other than attempting to determine the date data.
	//this.ShortDateFormat = "M/d/yyyy";

	this.GetDayOfWeekDescription = function (date)
	{
		///	<summary>
		///	Gets the day of week description for the supplied date
		///	</summary>
		///	<param name="date" type="Date"> date to get the day of week description</param>
		/// <returns type="string"> of the day of the week.</returns>
		date = new Date(date);
		var day = date.getDay();

		if (day == 0) { return "Sunday"; }
		else if (day == 1) { return "Monday"; }
		else if (day == 2) { return "Tuesday"; }
		else if (day == 3) { return "Wednesday"; }
		else if (day == 4) { return "Thursday"; }
		else if (day == 5) { return "Friday"; }
		else { return "Saturday"; }
	};
	this.AddDays = function (date, daysToAdd)
	{
		///	<summary>
		///	Creates a new date and then adds the supplied number of days to the date.
		///	</summary>
		///	<param name="date" type="Date"> date to get the day of week description</param>
		///	<param name="daysToAdd" type="int"> number of days to add to the supplied date.</param>
		/// <returns type="Date"> new Date with the supplied number of days added</returns>
		date = new Date(date);
		date.setDate(date.getDate() + 1);
		return date;
	};
};

var Utils = new Utils();


function BrowserTools()
{

	//detects if the browser is IE
	this.IsInternetExplorer = function ()
	{
		///	<summary>
		///	Determines if the current browser is IE
		///	</summary>
		/// <returns type="bool"> flag indicating whether or not the browser is IE</returns>
		if (navigator.userAgent.indexOf("MSIE") >= 0)
		{
			return true;
		}
		else
		{
			return false;
		}
	};
	//detects if the browser is netscape
	this.IsNetscape = function ()
	{
		///	<summary>
		///	Determines if the current browser is Netscape
		///	</summary>
		/// <returns type="bool"> flag indicating whether or not the browser is Netscape</returns>

		if (this.IsSafari())
		{
			return false;
		}
		else if (this.IsFirefox())
		{
			return false;
		}
		else
		{
			if (navigator.appName.toLowerCase().indexOf("netscape") > -1)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
	};
	//detects if the browser is safari
	this.IsSafari = function ()
	{
		///	<summary>
		///	Determines if the current browser is Safari
		///	</summary>
		/// <returns type="bool"> flag indicating whether or not the browser is Safari</returns>

		if (navigator.userAgent.toLowerCase().indexOf("safari") > -1)
		{
			return true;
		}
		else
		{
			return false;
		}
	};
	this.IsFirefox = function ()
	{
		///	<summary>
		///	Determines if the current browser is Firefox
		///	</summary>
		/// <returns type="bool"> flag indicating whether or not the browser is Firefox</returns>

		if (navigator.userAgent.indexOf("Firefox") > -1)
		{
			return true;
		}
		else
		{
			return false;
		}
	};
	//detects if the browser is chrome
	this.IsChrome = function ()
	{
		///	<summary>
		///	Determines if the current browser is Chrome
		///	</summary>
		/// <returns type="bool"> flag indicating whether or not the browser is Chrome</returns>

		if (navigator.userAgent.toLowerCase().indexOf("chrome") > -1)
		{
			return true;
		}
		else
		{
			return false;
		}
	};
	this.GetMajorVersion = function ()
	{
		///	<summary>
		///	Gets the major 
		///	</summary>
		/// <returns type="float"> major version</returns>

		var userAgt = navigator.userAgent
		if (this.IsInternetExplorer())
		{

			var verOffset = userAgt.indexOf("MSIE");

			return parseFloat(userAgt.substring(verOffset + 5, userAgt.length));

		}
		else
		{
			alert("Unsupported for the browser");
		}
		return parseFloat(navigator.appVersion);
	};

	this.IsIEBrowserZoomed = function ()
	{
		///	<summary>
		/// Determines whether or not the IE browser is zoomed in
		///	</summary>
		/// <returns type="bool"> flag indicating whether or not the browser is zoomed</returns>
		var isZoomed = false;

		if (navigator.appVersion.indexOf("MSIE") > 0)
		{
			if (IsIE8Browser())
			{
				isZoomed = (window.screen.deviceYDPI != 96);
			}
			else if (navigator.appVersion.indexOf("MSIE 7") > 0)
			{
				var rect = document.body.getBoundingClientRect();
				var zoomLevel = Math.round((rect.right - rect.left) / document.body.clientWidth * 100);
				isZoomed = (zoomLevel < 95 || zoomLevel > 105);
			}
		}

		return isZoomed;
	};

};
var BrowserTools = new BrowserTools();



/***************************
//dump properties for dev
*****************************/
function __Dump(object, insertIntoPage)
{
	///	<summary>
	///	Dumps the object properties to an alert (or in the page)
	///	</summary>
	///	<param name="insertIntoPage" type="bool"> flag indicating whether or not the object properties should be dumped and inserted into the bottom of the page inside a text area control.</param>
	/// <returns type="void"></returns>
	if (insertIntoPage)
	{
		InsertHTML("<p><textarea style=\"width:100%\" rows=\"10\">" + __GetObjectProperties(object) + "</textarea></p>");
	}
	else
	{
		alert(__GetObjectProperties(object));
	}
}

function __GetObjectProperties(obj)
{
	///	<summary>
	///	Loops through the object gettin the properties of the object
	///	</summary>
	///	<param name="obj" type="obj"> object to get the properties and dump.</param>
	/// <returns type="void"></returns>

	var properties = new String();

	if (isString(obj))
	{
		return obj;
	}

	for (var i in obj)
	{
		var msg = i + ": " + obj[i] + "\t";
		var msgString = new String();
		msgString = msg.toString()
		msgString = msgString.substring(0, 100);

		properties += msgString;
	}

	return properties;
}


/********************************************************
Veil Object
*********************************************************/

function MetafuseModalVeil()
{
	///	<summary>
	///	The Modal veil object used to show a veil under div
	///	</summary>
	/// <returns type="void"></returns>

	///	<field name="ElementQueue" type="Array"> array of elements in the queue of veil objects.</field>
	///	<field name="VeilElement" type="element"> the current element the veil is for or under</field>
	///	<field name="VeilElementShim" type="element"> the iframe (shim) for the current element.</field>
	///	<field name="VeilZIndex" type="int"> current zindex for the veil.</field>

	this.ElementQueue = null;
	this.VeilElement = null;
	this.VeilElementShim = null;
	this.VeilZIndex = 0;



	this.ShowVeilUnderElement = function (element, elementShim)
	{
		///	<summary>
		///	Shows the veil under the supplied elemnet
		///	</summary>
		///	<param name="element" type="element"> id or element to show the veil under</param>
		///	<param name="elementShim" type="element"> id or elemen of the shim for the supplied element</param>
		/// <returns type="void"></returns>

		element = GetElementById(element)

		if (element)
		{
			//if the element is not queued then go ahead and set it
			if (this.ElementQueue == null)
			{
				this.ElementQueue = new Array();
				UITools.InsertHTML("<div id=\"metafuseVeilObjectDiv\" class=\"Veil\"></div>");
				this.VeilElement = GetElementById("metafuseVeilObjectDiv");

				/*
				if(BrowserTools.IsInternetExplorer())
				{
				this.InsertHTML("<iframe id=\"metafuseVeilObjectShim\" class=\"Veil\" allowtransparency=\"false\" scrolling=\"no\" frameborder=\"0\" style=\"position:absolute; top:0px; left:0px; display:none;\"></iframe>");
				this.VeilElementShim = GetElementById("metafuseVeilObjectShim");
				}
				*/

				//set resize 
				var self = this;
				OnWindowResizeFunctions.AddFunction(function () { self.SetDimensions(); });
				OnScrollFunctions.AddFunction(function () { self.SetDimensions(); });

				//set the veil size
				this.SetDimensions();



			}

			//see if the veil is already shown and if so, we need to make sure that the veil div element is above the veil.
			if (this.VeilElement != null && this.VeilElement.style.zIndex > element.style.zIndex)
			{
				var veilElementzIndex = this.VeilElement.style.zIndex + 5;

				element.style.zIndex = veilElementzIndex;

				if (elementShim)
				{
					elementShim.style.zIndex = veilElementzIndex - 1;
				}
			}


			//now set the veil z index and show it
			this.VeilElement.style.zIndex = element.style.zIndex - 2;
			this.VeilElement.style.display = "";

			if (this.VeilElementShim)
			{
				this.VeilElementShim.style.zIndex = this.VeilElement.style.zIndex - 1;
				this.VeilElementShim.style.display = "";
			}

			//add this element to the queue of elements that are 
			this.ElementQueue[this.ElementQueue.length] = element;


		}

	};

	this.HideVeilUnderElement = function (element)
	{
		///	<summary>
		///	Hides the veil with the element (and dequeus the veil)
		///	</summary>
		///	<param name="element" type="element"> id or element to hide the veil under</param>
		/// <returns type="void"></returns>


		if (this.ElementQueue != null)
		{

			var elementHadVeil = false;

			element = GetElementById(element);

			if (element)
			{
				for (var i = 0; i < this.ElementQueue.length; i++)
				{
					var elementQueue = this.ElementQueue[i];
					if (elementQueue)
					{
						if (elementQueue.id == element.id)
						{
							this.ElementQueue.splice(i, 1);
							elementHadVeil = true;
							break;
						}
					}
				}
				//if the element had a veil then move the veil down
				if (elementHadVeil)
				{
					//if there are elements that have shown the veil then keep the veil up
					if (this.ElementQueue.length > 0)
					{
						var lastElement = this.ElementQueue[this.ElementQueue.length - 1];
						this.VeilElement.style.zIndex = lastElement.style.zIndex - 1;
						if (this.VeilElementShim)
						{
							this.VeilElementShim.style.zIndex = this.VeilElement.style.zIndex - 1;
						}

					}
					else
					{
						//hide the veil, no elements using it
						this.VeilElement.style.display = "none";
						this.VeilElement.style.zIndex = 0;
						if (this.VeilElementShim)
						{
							this.VeilElementShim.style.display = "none";
							this.VeilElementShim.style.zIndex = 0;
						}
					}
				}
			}

		}


	};

	this.SetDimensions = function ()
	{
		///	<summary>
		///	Sets the dimension of the veil
		///	</summary>
		/// <returns type="void"></returns>

		if (this.VeilElement != null)
		{
			if (this.VeilElement.style.display == "")
			{
				var w = UITools.GetWindowWidth() + UITools.GetScrollLeft();
				var h = UITools.GetWindowHeight() + UITools.GetScrollTop();



				//if(this.VeilElement.offsetWidth < w)
				//{
				this.VeilElement.style.width = w;
				//}
				//if(this.VeilElement.offsetHeight < h)
				//{
				this.VeilElement.style.height = h;
				//}

				//window.status = "w: " + w + " h: " + h;

				//window.status = "scrollLeft: " + window.scrollLeft;
				if (this.VeilElementShim)
				{
					this.VeilElementShim.style.width = w;
					this.VeilElementShim.style.height = h;
				}

			}
		}
	};
};
//create the basic veil
var metafuseVeil = new MetafuseModalVeil();



///////////////////////////////////////////////////////////////////////////
///Shell Functions
///////////////////////////////////////////////////////////////////////////
/*
function OnContentResize()
{
///	<summary>
///	Shell method called by controls that may adjust the content so that elements in the interface which rely on being anchored in certain locations can be inserted specific to the site.   For example, if the buttons are anchored in the upper right hand window, then this function should be completed to allow for that behavior.   The split screen control may invoke this method.
///	</summary>
/// <returns type="void" />
	
};
*/
///////////////////////////////////////////////////////////////////////////
///Depricated/Replaced Functions
///////////////////////////////////////////////////////////////////////////

function SetValueUsingSetTimeout(elementId, value)
{
	///	<summary>
	///	DEPRECATED, use FormTools.SetValueUsingSetTimeout()
	///	</summary>
	FormTools.SetValueUsingSetTimeout(elementId, value);
};
function SelectOptionsClear(selectElement, keepSelected)
{
	///	<summary>
	///	DEPRECATED, use FormTools.SelectOptionsClear()
	///	</summary>
	FormTools.SelectOptionsClear(selectElement, keepSelected);
};
function ListBoxCheckNoneSelected(element)
{
	///	<summary>
	///	DEPRECATED, use FormTools.SelectMultipleCheckNoneSelected()
	///	</summary>
	FormTools.SelectMultipleCheckNoneSelected(element);
};
function SubmitUsingSetTimeout(element)
{
	///	<summary>
	///	DEPRECATED, use FormTools.FocusAndClickElementUsingSetTimeout()
	///	</summary>
	FormTools.FocusAndClickElementUsingSetTimeout(element);
};
function GetPageXCoordinate(element)
{
	///	<summary>
	///	DEPRECATED, use UITools.GetPageXCoordinate()
	///	</summary>
	return UITools.GetPageXCoordinate(element);
};
function GetPageYCoordinate(element)
{
	///	<summary>
	///	DEPRECATED, use UITools.GetPageYCoordinate()
	///	</summary>
	return UITools.GetPageYCoordinate(element);
};
function GetEventPageXCoordinate(localEvent)
{
	///	<summary>
	///	DEPRECATED, use UITools.GetEventPageXCoordinate()
	///	</summary>
	return UITools.GetEventPageXCoordinate(localEvent);
};
function GetEventPageYCoordinate(localEvent)
{
	///	<summary>
	///	DEPRECATED, use UITools.GetEventPageYCoordinate()
	///	</summary>
	return UITools.GetEventPageYCoordinate(localEvent);
};
function GetWindowHeight()
{
	///	<summary>
	///	DEPRECATED, use UITools.GetWindowHeight()
	///	</summary>
	return UITools.GetWindowHeight();
};
function GetWindowWidth()
{
	///	<summary>
	///	DEPRECATED, use UITools.GetWindowWidth()
	///	</summary>
	return UITools.GetWindowWidth();
};
function GetScrollLeft()
{
	///	<summary>
	///	DEPRECATED, use UITools.GetScrollLeft()
	///	</summary>
	return UITools.GetScrollLeft();
};
function GetScrollTop()
{
	///	<summary>
	///	DEPRECATED, use UITools.GetScrollTop()
	///	</summary>
	return UITools.GetScrollTop();
};
function ShowDivAndIFrameAtEvent(localEvent, divElement, iframe, offsetX, offsetY)
{
	///	<summary>
	///	DEPRECATED, use UITools.ShowDivAndIFrameAtEvent()
	///	</summary>
	UITools.ShowDivAndIFrameAtEvent(localEvent, divElement, iframe, offsetX, offsetY);
};
function ShowDivAndIFrameAtXY(x, y, divElement, iframe, offsetX, offsetY)
{
	///	<summary>
	///	DEPRECATED, use UITools.ShowDivAndIFrameAtXY()
	///	</summary>
	UITools.ShowDivAndIFrameAtXY(x, y, divElement, iframe, offsetX, offsetY);
};
function HideDivAndIFrame(divElement, iframe)
{
	///	<summary>
	///	DEPRECATED, use UITools.HideDivAndIFrame()
	///	</summary>
	UITools.HideDivAndIFrame(divElement, iframe);
};
function FocusOnElement(elementToFocus)
{
	///	<summary>
	///	DEPRECATED, use UITools.FocusOnElement()
	///	</summary>
	UITools.FocusOnElement(elementToFocus);
};
function DisableElement(elementNameToDisable)
{
	///	<summary>
	///	DEPRECATED, use UITools.DisableElement()
	///	</summary>
	UITools.DisableElement(elementNameToDisable);
};
function EnableElement(elementNameToEnable)
{
	///	<summary>
	///	DEPRECATED, use UITools.EnableElement()
	///	</summary>
	UITools.EnableElement(elementNameToEnable);
};
function ToggleElementDisable(elementName, enable)
{
	//	<summary>
	///	DEPRECATED, use UITools.ToggleElementDisable()
	///	</summary>
	UITools.ToggleElementDisable(elementName, enable);
};
function ToggleDisplay(element, hide)
{
	///	<summary>
	///	DEPRECATED, use UITools.ToggleDisplay()
	///	</summary>
	return UITools.ToggleDisplay(element, hide);
};
function InsertHTML(html)
{
	///	<summary>
	///	DEPRECATED, use UITools.InsertHTML()
	///	</summary>
	UITools.InsertHTML(html);
};


//REPLACED IN MathTools
function IsNumeric(inputString)
{
	///	<summary>
	///	DEPRECATED, use MathTools.IsNumeric()
	///	</summary>
	return MathTools.IsNumeric(inputString);
};
function FormatCurrency(num)
{
	///	<summary>
	///	DEPRECATED, use MathTools.FormatCurrencyString()
	///	</summary>
	return MathTools.FormatCurrencyString(num);
};
function Round(dNumber, iDecimalPlaces, includeTrailingZeros)
{
	///	<summary>
	///	DEPRECATED, use MathTools.Round()
	///	</summary>
	if (iDecimalPlaces > 0 && !includeTrailingZeros)
	{
		alert("depricated functionality, check the function");
	}
	return MathTools.Round(dNumber, iDecimalPlaces);
};
function IsEven(integer)
{
	///	<summary>
	///	DEPRECATED, use MathTools.IsEven()
	///	</summary>
	return MathTools.IsEven(integer);
};
function ConvertToFloat(value)
{
	///	<summary>
	///	DEPRECATED, use MathTools.ParseFloat()
	///	</summary>
	return MathTools.ParseFloat(value);
};
function ParseFloatReturnsZeroIfNaN(inValue)
{
	///	<summary>
	///	DEPRECATED, use MathTools.ParseFloat()
	///	</summary>
	return MathTools.ParseFloat(inValue);
};
function IsNetscape()
{
	///	<summary>
	///	DEPRECATED, use BrowserTools.IsNetscape()
	///	</summary>
	return IsBrowserNetscape();
};
function IsBrowserNetscape()
{
	///	<summary>
	///	DEPRECATED, use BrowserTools.IsNetscape()
	///	</summary>
	return BrowserTools.IsNetscape();
};
function IsSafari()
{
	///	<summary>
	///	DEPRECATED, use BrowserTools.IsSafari()
	///	</summary>
	return IsBrowserSafari();
};
function IsBrowserSafari()
{
	///	<summary>
	///	DEPRECATED, use BrowserTools.IsSafari()
	///	</summary>
	return BrowserTools.IsSafari();
};
function IsBrowserInternetExplorer()
{
	///	<summary>
	///	DEPRECATED, use BrowserTools.IsInternetExplorer()
	///	</summary>
	return BrowserTools.IsInternetExplorer();
};

/////////////////////////////////////////////////////////////////////
/// DEPRECATED PERMANENTLY
/////////////////////////////////////////////////////////////////////

//DEPRICATED USE FormTools.EnsurePercent
function EnsurePercent(element, decimalPlaces)
{
	///	<summary>
	///	DEPRECATED, use FormTools.EnsurePercent(...)
	///	</summary>
	element = GetElementById(element);
	if (element)
	{
		var elementId = element.id;

		if (!decimalPlaces)
		{
			decimalPlaces = 2;
		}

		var v = new Number();
		v = parseFloat(element.value);

		if (v.toString() == "NaN")
		{
			SetValueUsingSetTimeout(elementId, "");
			return;
		}

		v = Round(v, decimalPlaces, true);

		if (v < 0)
		{
			SetValueUsingSetTimeout(elementId, "0");
		}
		else if (v > 100)
		{
			SetValueUsingSetTimeout(elementId, "100");
		}
		else if (v.toString() != element.value.toString())
		{
			SetValueUsingSetTimeout(elementId, v.toString());
		}
	}
};


/**********************************************************
Change element class name (USED IN HEADER)
***********************************************************/
function ChangeElementClassName(element, className)
{
	///	<summary>
	///	DEPRECATED, DO NOT USE
	///	</summary>
	element = GetElementById(element);
	if (element)
	{
		element.className = className;
	}
};
/**********************************************************
Image Changing Functions (Depricate?)
**********************************************************/

//STW 2003-04-27 override the previous one, which does not work on Tree's for whatever reason.  
function ChangeImage(sImageId, sImageName)
{
	///	<summary>
	///	DEPRECATED, DO NOT USE
	///	</summary>
	if (document.images && document[sImageId] && eval("window." + sImageName))
	{
		document[sImageId].src = eval(sImageName + ".src");
	}
};
function ChangeInputImage(inputImage, imgObjName)
{
	///	<summary>
	///	DEPRECATED, DO NOT USE
	///	</summary>
	//If the browser supports rollovers then change the image.
	if (document.getElementById)
	{
		inputImage.src = eval(imgObjName + ".src");
	}
};
//swaps an image inside a hyperlink
function HyperLinkSwapImage(element, imageUrl)
{
	///	<summary>
	///	DEPRECATED, DO NOT USE
	///	</summary>
	element = GetElementById(element);
	if (element)
	{
		element.src = imageUrl;
	}
};
function LO(scriptPath, guidArrayIndex, optionalNameString)
{
	///	<summary>
	///	DEPRECATED, DO NOT USE
	///	</summary>
	if (scriptPath.indexOf("?") >= 0)
	{
		scriptPath += "&";
	}
	else
	{
		scriptPath += "?";
	}

	if (!optionalNameString)
	{
		optionalNameString = "Id";
	}

	return L(scriptPath + optionalNameString + "=" + GuidArray[guidArrayIndex]);

};
//DEPRICATED
function SID(hiddenInput, guidArrayIndex)
{
	///	<summary>
	/// DEPRICATED, DO NOT USE
	///	</summary>
	SHV(hiddenInput, GuidArray[guidArrayIndex]);
};

/*********************************************************************
Anchor elements to window sides
**********************************************************************/
function AnchorElementOnRight(elementName)
{
	///	<summary>
	/// DEPRICATED, DO NOT USE
	///	</summary>
	var element = GetElementById(elementName);
	if (element)
	{
		var scrollLeft;
		var elementWidth;
		if (navigator.appName == "Netscape")
		{
			element.style.position = "fixed";
		}
		else
		{
			scrollLeft = document.body.scrollLeft;
			var windowWidth = GetWindowWidth();
			//var left = (document.body.clientWidth - element.offsetWidth) + scrollLeft;
			var left = (windowWidth - element.offsetWidth) + scrollLeft;

			//window.status = left;
			element.style.position = "absolute";
			element.style.left = left;
		}

	}
};

//TO BE DEPRECATED
function IsIEBrowserZoomed()
{
	///	<summary>
	/// DEPRICATED, BrowserTools.IsIEBrowserZoomed();
	///	</summary>
	return BrowserTools.IsIEBrowserZoomed();
};


