
// Begin sbalookandfeel.js (in case cfincluded, which normally shouldn't be done)
// Created by Steve Seaquist, 11/16/2006
//
// NOTE:				The next usage of jQuery should probably be replacing all /library references to window.onload 
//						with a $(document).ready function that binds $(window).load (for automatic queuing). This would 
//						allow us to ease body.onload and window.onload restrictions. That'll have to be done cautiously, 
//						so it's not part of the 12/09/2008 release. When the $(window).load logic is in place, move this 
//						explanation into the Revision History. 
//
// Revision History:	12/01/2010, SRS:	Reverse the effects of ShowUntilAllFullyLoaded and HideUntilAllFullyLoaded 
//											when the page is fully loaded. (Not too many using those classes, because this 
//											is actually a MAJOR bug that managed to go unnoticed for quite some time.) 
//											New function SlafCenterInAppData. See also sba.css (style #CenterThisInAppData). 
//						09/21/2010, SRS:	New look-and-feel is now stable, so moved JS from cf_sbalookandfeel to here. 
//						07/20/2010, SRS:	"New Look-and-Feel": AppInfo is now width:100%, so we no longer resize it. 
//											Also made AppTimeoutDangerZone a className in sba.ccs, so used it here. 
//						01/27/2010, SRS:	Added support for "AppTimeout" (setInterval-based display of approximate time 
//											till session timeout). Made it reset on frame reloads. 
//						01/22/2010, SRS:	We're sometimes throwing an error at document unload time if cf_sbalookandfeel 
//											was called with ReadyLight="No", because neither top.SetReadyLightToLoading nor 
//											top.MainNav.SetReadyLightToLoading is defined. Added test to prevent that. 
//											
//						07/10/2009, SRS:	Now that the cf_sbalookandfeel custom tag is queuing DoThisOnLoad using 
//											$(document).ready(), added a new function DoThisIfAllFullyLoaded. In addition 
//											to setting the ReadyLight, it also clears "UntilAllFullyLoaded" classes. 
//						05/29/2009, SRS:	Since cf_sbalookandfeel now uses $(window).resize(SlafDoThisOnResize), and 
//											since jQuery passes the event object to event handlers, had to set debugging 
//											flag using top.SlafDebug. Added SlafSetFrameLoaded (part of automatic support 
//											for ReadyLight that was added to cf_sbalookandfeel). 
//						03/19/2009, SRS:	Added gDivHighlightCursor and SlafHighlightCursor(pTurnHighlightingOn). 
//						12/09/2008, SRS:	Better feedback to users about margins via SlafMarginHi and SlafMarginLo. 
//											Animated SlafToggleAppData using jQuery's animate function. (Wow factor.) 
//											This is the first jQuery usage actually inside sbalookandfeel.js. As a 
//											result, we are now intrinsically committed to jQuery, and can henceforth 
//											use it more freely. (Fortunately, jQuery is awesome.) See NOTE, above. 
//						10/02/2007, SRS:	Forced the creation of a new window whenever the user requests a pop up 
//											such as Print or Help. (See references to sWindIntName, below.) 
//						02/23/2007, SRS:	Added SlafMenu code, which is currently just a prototype to try it out as 
//											an interface option. Per Ron Whalen, modified SlafPopUpRegion to accept 
//											AppInfoAndAppData (or logical synonym Print), for use in DoPrint scripts. 
//											Also per Ron, made BotMost participate in SlafToggleAppData. 
//						11/16/2006, SRS:	Original implementation, as part of CSS-P version of SBA look-and-feel. 
//
// This JavaScript should be called ONLY by cf_sbalookandfeel. If any other frame or inline region needs these 
// variables or functions, they can always reference them as top.whatever. Therefore, it's okay to force the 
// caller to the topmost window frame: 

if	(self != top.self)						// Prevents accidentally nested frames. 
	top.location.href						= self.location.href;

// Configuration Parameters:

var	kBrowserIsMSIE							= ((navigator.appName == "Microsoft Internet Explorer") 
										//	&& (navigator.userAgent.indexOf("Opera") < 0)	// Opera emulates IE. 
										//	&& (navigator.platform == "Win32")				// Mac has same broken box model. 
											) ? true : false;
var	kEnvelopeBorder							= 1;
var	kEnvelopeCellSpacing					= 2;
var	kEnvelopeMargin							= 10;
var	kFudgeFactorMSIE						= kBrowserIsMSIE ? 2 : 0;	// Required in backward-compatibility mode (broken box). 
var	kHeightAppDataMin						= 100;
var	kHeightAppName							= 24;
var	kHeightAzureGrowthGraph					= 101;
var	kHeightBotMost							= 24;
var	kHeightSBALogo							= 77;
var	kHeightTop4Regions						= kHeightSBALogo		+ kEnvelopeCellSpacing + kHeightAppName;
var	kHeightTopOfAppData						= kHeightTop4Regions	+ kEnvelopeCellSpacing;
var	kHeightWindowMin						= kHeightTopOfAppData
											+ kHeightAppDataMin
											+ kHeightBotMost
											+ (2 * kEnvelopeBorder)
											+ (2 * kEnvelopeMargin);
var	kHeightWindowDefault					= 607;	// based on MSIE for Windows and 1024x768 resolution
var	kServerSessionTimeoutInSeconds			= 3600;	// One hour. 
var	kWidthAzureGrowthGraph					= 434;
var	kWidthSBALogo							= 196;
var	kWidthLeftOfAppData						= kWidthSBALogo			+ kEnvelopeCellSpacing;
var	kWidthWindowMin							= kWidthSBALogo
											+ kEnvelopeCellSpacing
											+ kWidthAzureGrowthGraph
											+ (2 * kEnvelopeBorder)
											+ (2 * kEnvelopeMargin);
var	kWidthWindowDefault						= 984;	// based on MSIE for Windows and 1024x768 resolution

// Globals to save on calls to document.getElementById:

var	gAllGlobalsInitialized					= false;	// ... until SlafInitGlobals() is called. 
var	gDivAppData								= null;
var	gDivAppInfo								= null;
var	gDivAppName								= null;
var	gDivAppNameText							= null;
var	gDivAppNav								= null;
var	gDivBotMost								= null;
var	gDivCenterThisInAppData					= null;
var	gDivEnvelope							= null;
var	gDivHighlightCursor						= null;
var	gDivMainNav								= null;
var	gDivMarginT								= null;	// Standard CSS order = top, right, bottom, left. 
var	gDivMarginR								= null;	// Standard CSS order = top, right, bottom, left. 
var	gDivMarginB								= null;	// Standard CSS order = top, right, bottom, left. 
var	gDivMarginL								= null;	// Standard CSS order = top, right, bottom, left. 
var	gDivSBALogo								= null;
var	gDivSlafMenu							= null;
var	gDivWindow								= null;
var	gDspAppInfo								= "";	// Optional region. This will be "" or "none". 
var	gDspAppNav								= "";	// Optional region. This will be "" or "none". 
var	gFrameIsFullyLoadedAppData				= false;
var	gFrameIsFullyLoadedAppInfo				= true; // Per Ron Whalen, no longer affects ReadyLight. 
var	gFrameIsFullyLoadedAppNav				= false;
var	gFrameIsFullyLoadedMainNav				= false;
var	gFrmAppData								= null;	// gFrm vars not used, provided for backwards compatability. 
var	gFrmAppHidden							= null;	// gFrm vars not used, provided for backwards compatability. 
var	gFrmAppInfo								= null;	// gFrm vars not used, provided for backwards compatability. 
var	gFrmAppNav								= null;	// gFrm vars not used, provided for backwards compatability. 
var	gFrmMainNav								= null;	// gFrm vars not used, provided for backwards compatability. 
var	gHighlightCursor						= false;// Used in SlafMenuSelect. 
var	gLastPopUp								= null;	// Set by most recent call to SlafPopUpRegion. 
var	gLastPopUpRegion						= "";	// Set by most recent call to SlafPopUpRegion. 
var	gPageLoadTime							= new Date();
var	gPageLoadTimeMS							= gPageLoadTime.getTime();// Milliseconds since 01/01/1970. 
var	gPrevHeight								= 0;
var	gPrevWidth								= 0;
// Initialize all gRefs to top.self for now. That's because this script is included in the head, before the 
// screen regions have been defined. They won't be defined for-sure until SlafDoThisOnLoad, which sets their 
// true values. Note that, unlike gFrm vars, these are always usable, even when the region is not a frame: 
var	gRefAppData								= top.self;
var	gRefAppHidden							= top.self;
var	gRefAppInfo								= top.self;
var	gRefAppNav								= top.self;
var	gRefMainNav								= top.self;
var	gSlafShowAppTimeoutIntervalMS			= 60000;	// 60,000 milliseconds = once a minute.
var	gSlafShowAppTimeoutNowID				= null;
var	gSlafShowAppTimeoutRef					= null;
var	gThisPageIsFullyLoaded					= false;

// Functions, in aphabetical order: 

function AutoResize							(pToggleTextOnly)		// For compatability with old look-and-feel
	{
	if	(pToggleTextOnly)
		SlafToggleTextOnly					();
	}

function DoThisIfAllFullyLoaded				()
	{
	// Called by SetReadyIfAllFullyLoaded, which waits until top and all frames have all hit the window.load event. 
	// In a frame, include sbalookandfeelframe.js instead, which waits only until $(window).load() to do the same things. 
	// First remove all "UntilAllFullyLoaded" classes (defined in sba.css and noscript.css). Must do this before setting the 
	// ReadyLight to Ready, because these affect the actual usability of the page. (SetReadyLightToReady is more likely to 
	// error than these jQuery commands. If SetReadyLightToReady has problems, we need to leave the page usable, at least. 
	// Relatively speaking, it's okay to have "Loading" remain on the screen. But it's NOT okay to leave the page unusable.) 

	$(".HideUntilAllFullyLoadedBlock")		.removeClass("HideUntilAllFullyLoadedBlock")	.css({display:"block"});
	$(".HideUntilAllFullyLoadedInline")		.removeClass("HideUntilAllFullyLoadedInline")	.css({display:"inline"});
	// gSlafInlineBlock *SHOULD* have been defined by custom tags or other inclusions, but don't error if it wasn't: 
	var	sInlineBlock						= (gSlafInlineBlock		? gSlafInlineBlock
											: (top.gSlafInlineBlock	? top.gSlafInlineBlock
											: "inline-block"));// Should never get this far. 
	var	sInlineTable						= (gSlafInlineTable		? gSlafInlineTable
											: (top.gSlafInlineTable	? top.gSlafInlineTable
											: "inline-table"));// Should never get this far. 
	$(".HideUntilAllFullyLoadedInlBlk")		.removeClass("HideUntilAllFullyLoadedInlBlk")	.css({display:sInlineBlock});
	$(".HideUntilAllFullyLoadedInlTbl")		.removeClass("HideUntilAllFullyLoadedInlTbl")	.css({display:sInlineTable});
	$(".HideUntilAllFullyLoadedTblRowGrp")	.removeClass("HideUntilAllFullyLoadedTblRowGrp").css({display:"table-row-group"});
	$(".HideUntilAllFullyLoadedTblRow")		.removeClass("HideUntilAllFullyLoadedTblRow")	.css({display:"table-row"});
	$(".ShowUntilAllFullyLoadedBlock")		.removeClass("ShowUntilAllFullyLoadedBlock")	.addClass("hide");
	$(".ShowUntilAllFullyLoadedInline")		.removeClass("ShowUntilAllFullyLoadedInline")	.addClass("hide");
	$(".ShowUntilAllFullyLoadedInlBlk")		.removeClass("ShowUntilAllFullyLoadedInlBlk")	.addClass("hide");
	$(".ShowUntilAllFullyLoadedInlTbl")		.removeClass("ShowUntilAllFullyLoadedInlTbl")	.addClass("hide");
	$(".ShowUntilAllFullyLoadedTblRowGrp")	.removeClass("ShowUntilAllFullyLoadedTblRowGrp").addClass("hide");
	$(".ShowUntilAllFullyLoadedTblRow")		.removeClass("ShowUntilAllFullyLoadedTblRow")	.addClass("hide");
	if	(top.MainNav)
		{
		if	(top.MainNav.SetReadyLightToReady)			// In case (cf_sbalookandfeel ReadyLight="No"). 
			top.MainNav.SetReadyLightToReady();
		}
	else
		{
		if	(top.SetReadyLightToReady)					// In case (cf_sbalookandfeel ReadyLight="No"). 
			top.SetReadyLightToReady();
		}
	}

function DoThisOnLoad						()			// No longer used, provided for backwards compatability. 
	{
	SlafDoThisOnLoad();
	}

function SetReadyIfAllFullyLoaded			()
	{
	if	(top.gFrameIsFullyLoadedAppData
	&&	top.gFrameIsFullyLoadedAppNav
	&&	top.gFrameIsFullyLoadedMainNav)
		DoThisIfAllFullyLoaded();
	}

function SlafCenterInAppData				()
	{
	if	(!top.AppData)// Make sure this routine is used only when AppData is inline. Otherwise, this routine does nothing. 
		{
		var	sDiv							= $(gDivCenterThisInAppData);
		var	sWin							= $(gDivAppData);// sbalookandfeelframe.js uses $(window). 
		var	sDivHeight						= sDiv.height();
		var	sDivWidth						= sDiv.width();
		var	sWinHeight						= sWin.height();
		var	sWinWidth						= sWin.width();
		var	sLeft							= Math.floor((sWinWidth		- sDivWidth)	/ 2);
		var	sTop							= Math.floor((sWinHeight	- sDivHeight)	/ 2);
		sDiv.css({left:sLeft,top:sTop});
		}
	}

function SlafDoThisOnLoad					()			// Actually done at $(document).ready() time. See also DoThisOnWindowLoad. 
	{
	SlafInitGlobals();						// Only situation where SlafInitGlobals is executed unconditionally. 
	SlafShowAppTimeoutInit();				// May not do anything if document.getElementById("AppTimeout") is null. 
	// The jQuery hover function tracks the mouse better than onmouseover and onmouseout. (Doesn't leave the menu open.) 
	$("div[id^=DivSlafMenu]")				.hover(SlafMenuShow, SlafMenuHide);
	$("div[id^=DivMargin]")					.hover(SlafMarginHi, SlafMarginLo);// Lets users know that the margin is a control. 
	// Do a "vertical-align:middle" that works across all browsers:
	var	s$DivAppNameText					= $(gDivAppNameText);// Don't rebuild jQuery object twice. 
	var	sTopForMiddleAlignment				= 43 - Math.floor(s$DivAppNameText.height() / 2);
	s$DivAppNameText.css({top:sTopForMiddleAlignment});

	if		(self.innerHeight)
		{	// (all except Explorer)
		gPrevHeight							= self.innerHeight;
		gPrevWidth							= self.innerWidth;
		}
	else if	(document.documentElement && document.documentElement.clientHeight)
		{	// (Explorer 6 in Strict Mode)
		gPrevHeight							= document.documentElement.clientHeight;
		gPrevWidth							= document.documentElement.clientWidth;
		}
	else if	(document.body)
		{	// (other Explorers)
		gPrevHeight							= document.body.clientHeight;
		gPrevWidth							= document.body.clientWidth;
		}
	else
		{	// (just in case some funky, non-compliant browser comes along)
		gPrevHeight							= kHeightWindowDefault;
		gPrevWidth							= kWidthWindowDefault;
		}
	//	DumpObject(navigator, "navigator");
	SlafDoThisOnResize();
	SetReadyIfAllFullyLoaded();
	}

function SlafDoThisOnResize					()
	{
	if	(!gAllGlobalsInitialized)			// This function uses gDiv globals, so make sure their contents are initialized. 
		SlafInitGlobals();					// (Sometimes they won't be if the calling page trashes the onLoad.) 
	var	sDebug								= top.gSlafDebug ? top.gSlafDebug : false;
	if	(location.href.indexOf("DebugResize") >= 0) sDebug	= true;
	if	(sDebug)							alert("Entering SlafDoThisOnResize.");
	var	sHeightWindow						= "";
	var	sWidthWindow						= "";
	// Haven't yet figured out how to calculate AppData's scrolled content height, so that overflow:visible can 
	// push down BotMost. But save the code, if only to serve as memory of what DOESN'T work: 
	//if	(gDivAppData.style.overflow == "visible")
	//	{
	//	if	(sDebug) alert("Getting scrolled height and width, which is never less than that of the window.")
	//	if	(document.body.scrollHeight > document.body.offsetHeight)// All browsers support both. Use the larger. 
	//		{	// all but Explorer Mac
	//		sHeightWindow					= document.body.scrollHeight;
	//		sWidthWindow					= document.body.scrollWidth;
	//		}
	//	else
	//		{	// Explorer Mac, but would also work in Explorer 6 Strict, Mozilla and Safari
	//		sHeightWindow					= document.body.offsetHeight;
	//		sWidthWindow					= document.body.offsetWidth;
	//		}
	//	}
	//else
	//	{
		if	(sDebug) alert("Getting window height and width.")
		if		(self.innerHeight)
			{	// (all except Explorer)
			sHeightWindow					= self.innerHeight;
			sWidthWindow					= self.innerWidth;
			}
		else if	(document.documentElement && document.documentElement.clientHeight)
			{	// (Explorer 6 in Strict Mode)
			sHeightWindow					= document.documentElement.clientHeight;
			sWidthWindow					= document.documentElement.clientWidth;
			}
		else if	(document.body)
			{	// (other Explorers)
			sHeightWindow					= document.body.clientHeight;
			sWidthWindow					= document.body.clientWidth;
			}
		else
			{	// (just in case some funky, non-compliant browser comes along)
			sHeightWindow					= kHeightWindowDefault;
			sWidthWindow					= kWidthWindowDefault;
			}
	//	}

	if	(sDebug) alert("Raw: sHeightWindow = "+sHeightWindow+", sWidthWindow = "+sWidthWindow+".");

	var	sExpandingHeight					= (sHeightWindow	> gPrevHeight)	? true : false;
	var	sExpandingWidth						= (sWidthWindow		> gPrevWidth)	? true : false;
	gPrevHeight								= sHeightWindow;
	gPrevWidth								= sWidthWindow;

	//	If the user sizes the window too small, to heck with trying to prevent scrollbars: 
	if	(sHeightWindow						< kHeightWindowMin)
		sHeightWindow						= kHeightWindowMin;
	if	(sWidthWindow						< kWidthWindowMin)
		sWidthWindow						= kWidthWindowMin;
	if	(sDebug) alert("Adjusted: sHeightWindow = "+sHeightWindow+", sWidthWindow = "+sWidthWindow+".");

	//	Adjust for DivMargin divs:
	var	sHeightEnvelope						= sHeightWindow		- (2 * kEnvelopeMargin);
	var	sWidthEnvelope						= sWidthWindow		- (2 * kEnvelopeMargin);
	if	(sDebug) alert("Envelope: sHeightEnvelope = "+sHeightEnvelope+", sWidthEnvelope = "+sWidthEnvelope+".");

	//	Adjust for DivEnvelope's 1 pixel border (on both sides): 
	var	sHeightContent						= sHeightEnvelope	- (2 * kEnvelopeBorder);
	var	sWidthContent						= sWidthEnvelope	- (2 * kEnvelopeBorder);
	if	(sDebug) alert("Content: sHeightContent = "+sHeightContent+", sWidthContent = "+sWidthContent+".");

	gDivMarginL.style.height				=
	gDivMarginR.style.height				= sHeightEnvelope						- kFudgeFactorMSIE	+ "px";
	gDivMarginB.style.top					= sHeightEnvelope	+ kEnvelopeMargin	- kFudgeFactorMSIE	+ "px";
	gDivMarginT.style.width					=
	gDivMarginB.style.width					= sWidthEnvelope	+ (2 * kEnvelopeMargin)					+ "px";
	gDivMarginR.style.left					= sWidthEnvelope	+ kEnvelopeMargin	- kFudgeFactorMSIE	+ "px";
	if	(sDebug) alert("Margins done.");

	if	(sExpandingHeight)
		gDivEnvelope.style.height			= sHeightContent											+ "px";
	if	(sExpandingWidth)
		gDivEnvelope.style.width			= sWidthContent												+ "px";
	if	(sDebug) alert("Envelope expansions done.");

	sHeightContent							-= kFudgeFactorMSIE;
	sWidthContent							-= kFudgeFactorMSIE;
	if	(kBrowserIsMSIE && sDebug)			alert("Adjusted contents for standards non-compliant browser: "
											+ "sHeightContent = "+sHeightContent+", sWidthContent = "+sWidthContent+".");

	// The only reason why gDivSBALogo won't be visible is if the user toggled AppData to maximized (within margins), so:
	if	(gDivSBALogo.style.display == "none")// or: if	(gDivMarginT.title.substring(0,3) == "Min")
		{
		with (gDivAppData.style)
			{
			height							= sHeightContent;
			width							= sWidthContent;
			}
		}
	else
		{
		var	sAppDataHeight					= sHeightContent	- (kHeightTopOfAppData	+ kHeightBotMost);
		var	sAppDataWidthUsually			= sWidthContent		- (kWidthSBALogo		+ kEnvelopeCellSpacing);
		var	sAppDataWidth					= (gDspAppNav == "none") ? sWidthContent : sAppDataWidthUsually;
		if	(sDebug)						alert("AppData: sAppDataHeight = "+sAppDataHeight+", sAppDataWidthUsually = "+sAppDataWidthUsually
											+ ", sAppDataWidth = "+sAppDataWidth+".");
		gDivAppData.style.width				= sAppDataWidth												+ "px";
		gDivMainNav.style.width				= sAppDataWidthUsually										+ "px";
		gDivBotMost.style.width				= sWidthContent												+ "px";
		gDivAppData.style.height			=
		gDivAppNav.style.height				= sAppDataHeight											+ "px";
		gDivBotMost.style.top				= sAppDataHeight	+ kHeightTopOfAppData					+ "px";
		if	(sDebug) alert("Inner regions done.");
		}

	sHeightContent							+= kFudgeFactorMSIE;
	sWidthContent							+= kFudgeFactorMSIE;
	if	(kBrowserIsMSIE && sDebug)			alert("Reverted contents for standards non-compliant browser: "
											+ "sHeightContent = "+sHeightContent+", sWidthContent = "+sWidthContent+".");

	if	(!sExpandingHeight)
		gDivEnvelope.style.height			= sHeightContent							+ "px";
	if	(!sExpandingWidth)
		gDivEnvelope.style.width			= sWidthContent								+ "px";
	if	(sDebug)							alert("Envelope contractions done.");
	if	(gDivCenterThisInAppData)
		SlafCenterInAppData();
	return;
	}

$(window).resize(SlafDoThisOnResize);

// The "DoSomethingDifferentOnLoad" mechanism is now deprecated. Instead, you should convert your onload routine 
// to use $(window).load or $(document).ready instead. Otherwise, you'll be redundantly calling MainNavDoThisOnLoad 
// and SlafDoThisOnLoad. (Doesn't hurt anything, but it's a waste of time and CPU.) This keeps old code running: 

$(window).load(function()
	{
	if	(top.DoSomethingDifferentOnLoad)	// Possibly defined by developer in JSInline. 
		top.DoSomethingDifferentOnLoad();
	});

function SlafHighlightCursor				(pTurnHighlightingOn)
	{// Not yet debugged, but use it if you like. Makes the cursor more visible on a projector screen. 
	if	(gHighlightCursor = pTurnHighlightingOn)
		{
		$(gDivWindow).mousedown	(function(e){
											if	(gHighlightCursor)// prevents bug in MSIE
												with (gDivHighlightCursor.style)
													{
													backgroundImage	= "url(/library/images/sbalookandfeel/cursor_hi.gif)";
													top				= e.pageY - 32;
													left			= e.pageX - 32;
													}
											return true;
											})
					.mouseup	(function(e){
											if	(gHighlightCursor)// prevents bug in MSIE
												with (gDivHighlightCursor.style)
													{
													backgroundImage	= "url(/library/images/sbalookandfeel/cursor_lo.gif)";
													top				= e.pageY - 32;
													left			= e.pageX - 32;
													}
											return true;
											})
					.mousemove	(function(e){
											if	(gHighlightCursor)// prevents bug in MSIE
												with (gDivHighlightCursor.style)
													{
													top				= e.pageY - 32;
													left			= e.pageX - 32;
													}
											return true;
											})
					.click		(function(e){
											return $(gDivWindow).mouseup();
											})
					.dblclick	(function(e){
											return $(gDivWindow).mouseup();
											});
		$(gDivHighlightCursor).css({display:"block",cursor:"crosshair"}).fadeTo(1000, 0.5);
		$("#SlafMenuHighlight").each(function(){this.innerHTML	= "Turn Cursor Back into a Cursor";});
		}
	else// Turn highlighting off: 
		{
		$(gDivWindow).unbind("mousedown").unbind("mouseup").unbind("mousemove");
		$(gDivHighlightCursor).css({display:"none",cursor:"auto"}).fadeOut(1);
		$("#SlafMenuHighlight").each(function(){this.innerHTML	= "Turn Cursor into a \"Laser Pointer\"";});
		}
	}

function SlafInitGlobals					()
	{
	gDivAppData								= document.getElementById("DivAppData");
	gDivAppInfo								= document.getElementById("DivAppInfo");
	gDivAppName								= document.getElementById("DivAppName");
	gDivAppNameText							= document.getElementById("DivAppNameText");
	gDivAppNav								= document.getElementById("DivAppNav");
	gDivBotMost								= document.getElementById("DivBotMost");
	gDivCenterThisInAppData					= document.getElementById("CenterThisInAppData");// Probably null;
	gDivEnvelope							= document.getElementById("DivEnvelope");
	gDivHighlightCursor						= document.getElementById("DivHighlightCursor");
	gDivMainNav								= document.getElementById("DivMainNav");
	gDivMarginT								= document.getElementById("DivMarginT");// Standard CSS order = top, right, bottom, left. 
	gDivMarginR								= document.getElementById("DivMarginR");// Standard CSS order = top, right, bottom, left. 
	gDivMarginB								= document.getElementById("DivMarginB");// Standard CSS order = top, right, bottom, left. 
	gDivMarginL								= document.getElementById("DivMarginL");// Standard CSS order = top, right, bottom, left. 
	gDivSBALogo								= document.getElementById("DivSBALogo");
	gDivSlafMenu							= document.getElementById("DivSlafMenu");
	gDivWindow								= document.getElementById("DivWindow");
	gDspAppInfo								= (gDivAppInfo	? gDivAppInfo.style.display	: "");
	gDspAppNav								= (gDivAppNav	? gDivAppNav.style.display	: "");
	if	(top.AppData)	gFrmAppData			= gRefAppData	= top.AppData;	else gFrameIsFullyLoadedAppData	= true;
						gFrmAppHidden		= gRefAppHidden	= top.AppHidden;	// always a frame
	if	(top.AppInfo)	gFrmAppInfo			= gRefAppInfo	= top.AppInfo;	else gFrameIsFullyLoadedAppInfo	= true;
	if	(top.AppNav)	gFrmAppNav			= gRefAppNav	= top.AppNav;	else gFrameIsFullyLoadedAppNav	= true;
	if	(top.MainNav)	gFrmMainNav			= gRefMainNav	= top.MainNav;	else gFrameIsFullyLoadedMainNav	= true;
	gThisPageIsFullyLoaded					= true;
	gAllGlobalsInitialized					= true;
	}

function SlafMarginHi						()				// Highlight margin so that users realize that it's a control. 
	{
	if	(!gAllGlobalsInitialized)			// This function uses gDiv globals, so make sure their contents are initialized. 
		SlafInitGlobals();					// (Sometimes they won't be if the calling page trashes the onLoad.) 
	gDivMarginT.style.backgroundColor		=				// Standard CSS order = top, right, bottom, left. 
	gDivMarginR.style.backgroundColor		=				// Standard CSS order = top, right, bottom, left. 
	gDivMarginB.style.backgroundColor		=				// Standard CSS order = top, right, bottom, left. 
	gDivMarginL.style.backgroundColor		= '#c1e3ed';	// Standard CSS order = top, right, bottom, left. Azure. 
	}

function SlafMarginLo						()				// Lowlight margin so that users realize that it's a control. 
	{
	if	(!gAllGlobalsInitialized)			// This function uses gDiv globals, so make sure their contents are initialized. 
		SlafInitGlobals();					// (Sometimes they won't be if the calling page trashes the onLoad.) 
	gDivMarginT.style.backgroundColor		=				// Standard CSS order = top, right, bottom, left. 
	gDivMarginR.style.backgroundColor		=				// Standard CSS order = top, right, bottom, left. 
	gDivMarginB.style.backgroundColor		=				// Standard CSS order = top, right, bottom, left. 
	gDivMarginL.style.backgroundColor		= '#ffffff';	// Standard CSS order = top, right, bottom, left. White. 
	}

function SlafMenuHide						()
	{
	if	(!gAllGlobalsInitialized)			// This function uses gDiv globals, so make sure their contents are initialized. 
		SlafInitGlobals();					// (Sometimes they won't be if the calling page trashes the onLoad.) 
	gDivSlafMenu.style.display				= "none";
	}

function SlafMenuSelect						(pActionCode)
	{
	// Although this function doesn't use gDiv globals, the file opened by pActionCode "Print" (printer_friendly.html) does. 
	// The problem is that printer_friendly.html can't test for the existence of the SBA look-and-feel globals if the user 
	// is using the Opera browser for Windows. So it falls to this routine to make sure that the gDiv globals' contents are 
	// properly initialized. (Sometimes they won't be if the calling page trashes the onLoad.) 
	if	(!gAllGlobalsInitialized)
		SlafInitGlobals();
	var	sWindow								= null;
	var	sWindIntName						= "PoputWindowCreatedAtMilliseconds" + (new Date()).getTime();
	switch (pActionCode)
		{
		case "Help":
			gLastPopUp						= window.open("/library/html/sba_look_and_feel_help.html",
											sWindIntName, "location,menubar,resizable,scrollbars,titlebar,toolbar");
			gLastPopUp.focus();
			break;
		case "HighlightCursor":
			SlafHighlightCursor(!gHighlightCursor);
			break;
		case "Print":
			gLastPopUp						= window.open("/library/html/printer_friendly.html",
											sWindIntName, "location,menubar,resizable,scrollbars,titlebar,toolbar");
		//	gLastPopUp.print();				// Now handled by /library/html/printer_friendly.html, don't do it twice. 
			break;
		case "Show/Hide":
			SlafToggleAppData();
			break;
		case "TextOnly":
			top.document.SlafToggleTextOnlyForm.submit();
		default:
			alert("No action defined for this hotlink yet.");
		}
	SlafMenuHide();
	}

function SlafMenuShow						()
	{
	if	(!gAllGlobalsInitialized)			// This function uses gDiv globals, so make sure their contents are initialized. 
		SlafInitGlobals();					// (Sometimes they won't be if the calling page trashes the onLoad.) 
	gDivSlafMenu.style.display				= gSlafInlineBlock;
	}

function SlafPopUpRegion					(pRegion)	// pRegion is a string: "AppData", "AppNav", etc.
	{
	if	(!gAllGlobalsInitialized)			// This function uses gDiv globals, so make sure their contents are initialized. 
		SlafInitGlobals();					// (Sometimes they won't be if the calling page trashes the onLoad.) 
	var	sWindow								= null;
	var	sWindIntName						= "PoputWindowCreatedAtMilliseconds" + (new Date()).getTime();
	switch (pRegion)
		{
		case "AppData":
		case "AppHidden":
		case "AppInfo":
		case "AppInfoAndAppData":
		case "AppName":
		case "AppNav":
		case "BotMost":
		case "MainNav":
		case "Print":						// logical synonym for AppInfoAndAppData
		case "SBALogo":
			break;
		default:
			alert("SlafPopUpRegion called with unknown region \"" + pRegion + "\".\n\n"
				+ "Allowable region names are \"AppData\", \"AppHidden\", \"AppInfo\", \"AppInfoAndAppData\", "
				+ "\"AppName\", \"AppNav\", \"BotMost\", \"MainNav\", \"Print\" or \"SBALogo\".");
			return;
		}
	gLastPopUpRegion						= pRegion;
	if	(eval("top."+pRegion))				// That is, if it's a frame:
		sWindow								= window.open(eval("top."+pRegion+".location.href"),
											sWindIntName, "location,menubar,resizable,scrollbars,titlebar,toolbar");
	else									// That is, if it's inline or a non-region name that's allowed:
		sWindow								= window.open("/library/html/pop_up_region.html",
											sWindIntName, "location,menubar,resizable,scrollbars,titlebar,toolbar");
	gLastPopUp								= sWindow;	// Allows caller to manipulate popup. 
	}

function SlafSetReadyLightToLoading			()
	{
	if	(top.MainNav)
		{
		if	(top.MainNav.SetReadyLightToLoading)		// In case (cf_sbalookandfeel ReadyLight="No"). 
			top.MainNav.SetReadyLightToLoading();
		}
	else
		{
		if	(top.SetReadyLightToLoading)				// In case (cf_sbalookandfeel ReadyLight="No"). 
			top.SetReadyLightToLoading();
		}
	}

function SlafSetFrameLoaded					(pFrame)
	{
	if	(pFrame)							// Don't error on unexpected conditions. (Just do nothing.) 
		if	(pFrame.name)					// Don't error on unexpected conditions. (Just do nothing.) 
			switch (pFrame.name)			// Don't error on unexpected conditions. (Just do nothing.) 
				{
				case "AppData":				top.gFrameIsFullyLoadedAppData	= true; SetReadyIfAllFullyLoaded(); break;
				case "AppNav":				top.gFrameIsFullyLoadedAppNav	= true; SetReadyIfAllFullyLoaded(); break;
				case "MainNav":				top.gFrameIsFullyLoadedMainNav	= true; SetReadyIfAllFullyLoaded(); break;
				}
	// On every frame load, reset gPageLoadTime and gPageLoadTimeMS, in case timeout countdown is being displayed: 
	gPageLoadTime							= new Date();
	gPageLoadTimeMS							= gPageLoadTime.getTime();// Milliseconds since 01/01/1970. 
	if	(gSlafShowAppTimeoutRef != null)
		{
		if	(gSlafShowAppTimeoutIntervalMS	== 1000)// If once a second, fall back to once a minute: 
			{
			if	(gSlafShowAppTimeoutNowID)
				{
				window.clearInterval(gSlafShowAppTimeoutNowID);
				gSlafShowAppTimeoutNowID	= null;
				}
			gSlafShowAppTimeoutIntervalMS	= 60000;
			gSlafShowAppTimeoutNowID		= window.setInterval(SlafShowAppTimeoutNow, gSlafShowAppTimeoutIntervalMS);
			}
		gSlafShowAppTimeoutRef.className	= "";	// Removes AppTimeoutDangerZone if it was there. 
		SlafShowAppTimeoutNow();
		}
	}

function SlafSetFrameLoading				(pFrameName)
	{
	switch (pFrameName)						// Don't error on unexpected conditions. (Just do nothing.) 
		{
		case "AppData":						top.gFrameIsFullyLoadedAppData	= false; break;
		case "AppNav":						top.gFrameIsFullyLoadedAppNav	= false; break;
		case "MainNav":						top.gFrameIsFullyLoadedMainNav	= false; break;
		}
	SlafSetReadyLightToLoading(); 
	}

function SlafShowAppTimeoutInit				()
	{
	gSlafShowAppTimeoutRef					= document.getElementById("AppTimeout");
	if	(gSlafShowAppTimeoutRef == null)
		return;								// If AppTimeout isn't defined, SlafShowAppTimeoutNow never gets executed. 
	gSlafShowAppTimeoutNowID				= window.setInterval(SlafShowAppTimeoutNow, gSlafShowAppTimeoutIntervalMS);
	SlafShowAppTimeoutNow();
	}

function SlafShowAppTimeoutNow				()
	{
	if	(gSlafShowAppTimeoutRef == null)	// Don't throw errors if executed in some nonstandard way. 
		{
		if	(gSlafShowAppTimeoutNowID)
			{
			window.clearInterval(gSlafShowAppTimeoutNowID);
			gSlafShowAppTimeoutNowID		= null;
			}
		return;
		}
	var	sMillisecondsSincePageLoadTimeMS	= (new Date()).getTime()
											- gPageLoadTimeMS;
	var	sSecondsSincePageLoadTime			= sMillisecondsSincePageLoadTimeMS / 1000;
	var	sSecondsToSessionTimeout			= kServerSessionTimeoutInSeconds
											- sSecondsSincePageLoadTime;
	if	(sSecondsToSessionTimeout < 0)
		{
		gSlafShowAppTimeoutRef.innerHTML	= "Session probably timed out. ";
		if	(gSlafShowAppTimeoutNowID)
			{
			window.clearInterval(gSlafShowAppTimeoutNowID);
			gSlafShowAppTimeoutNowID		= null;
			}
		return;
		}
	var	sMinutesToSessionTimeout			= Math.floor(sSecondsToSessionTimeout / 60);
	if	(sMinutesToSessionTimeout > 5)
		{
		gSlafShowAppTimeoutRef.innerHTML	= "Session timeout in "
											+ sMinutesToSessionTimeout
											+ " minutes. ";
		return;
		}
	if	(gSlafShowAppTimeoutIntervalMS		== 60000)	// Initialized with 60000 milliseconds = once a minute.
		{
		if	(gSlafShowAppTimeoutNowID)		// Don't do it once a minute anymore. 
			{
			window.clearInterval(gSlafShowAppTimeoutNowID);
			gSlafShowAppTimeoutNowID		= null;
			}
		gSlafShowAppTimeoutIntervalMS		= 1000;		// Instead, switch to 1000 milliseconds = once a second.
		gSlafShowAppTimeoutNowID			= window.setInterval(SlafShowAppTimeoutNow, gSlafShowAppTimeoutIntervalMS);
		gSlafShowAppTimeoutRef.className	= "AppTimeoutDangerZone";	// Brick red, bold. 
		}
	var	sSecondsAfterMinutes				= Math.floor(sSecondsToSessionTimeout - (sMinutesToSessionTimeout * 60));
	if	(sSecondsAfterMinutes >= 60)		// Sometimes happens due to Math.floor(). Anti-alias it back to secular time. 
		{
		sMinutesToSessionTimeout			+= 1;		// Add one to minutes. 
		sSecondsAfterMinutes				-= 60;		// Subtract 60 from seconds. 
		}
	if	(sSecondsAfterMinutes < 10)			// Add leading zero so that it'll display as m:ss, not m:s. 
		sSecondsAfterMinutes				= ("y0" + sSecondsAfterMinutes).substring(1,3);
	gSlafShowAppTimeoutRef.innerHTML		= "Session timeout in "
											+ sMinutesToSessionTimeout
											+ ":"
											+ sSecondsAfterMinutes
											+ ". ";
	}

function SlafToggleAppData					()
	{
	if	(!gAllGlobalsInitialized)			// This function uses gDiv globals, so make sure their contents are initialized. 
		SlafInitGlobals();					// (Sometimes they won't be if the calling page trashes the onLoad.) 
	var	sHeight								= gDivAppData.style.height;
	var	sWidth								= gDivAppData.style.width;
	if	(gDivMarginT.title.substring(0,3) == "Max")
		{
		gDivMarginT.title					=
		gDivMarginL.title					=
		gDivMarginB.title					=
		gDivMarginR.title					= "Min" + gDivMarginT.title.substring(3,gDivMarginT.title.length);
		$("#DivAppData").animate(
			{
			top:							"0px",
			left:							"0px",
			height:							(parseInt(sHeight,10) + kHeightTopOfAppData + kHeightBotMost)	+ "px",
			width:							(parseInt(sWidth, 10)
											+ ((gDspAppNav == "none")? 0 : kWidthSBALogo))					+ "px"
			},
			{
			duration: 1000,					// 1000 milliseconds = 1 second 
			complete: (function()			// "Completion routine" (will be done after the animation completes). 
				{
				gDivSBALogo.style.display	=
				gDivMainNav.style.display	=
				gDivAppName.style.display	=
				gDivAppInfo.style.display	=
				gDivAppNav.style.display	=
				gDivBotMost.style.display	= "none";
				})
			});
		}
	else
		{
		gDivMarginT.title					=
		gDivMarginL.title					=
		gDivMarginB.title					=
		gDivMarginR.title					= "Max" + gDivMarginT.title.substring(3,gDivMarginT.title.length);
		// In the maximize operation, above, we delayed execution of the code to hide other regions till the completion 
		// of the growth animation. We did this with a "complete:" propertty in the animate call's second object literal 
		// parameter. That way, the animation is seen to grow over the other regions before they're hidden. But in the 
		// case of the shrinkage animation, below, we want the other regions visible BEFORE beginning the animation, so 
		// that the shrinkage is seen to uncover the other regions. So we show them first. It's not really a functional 
		// requirement. It's mostly just showmanship, so that the user is favorably impressed with their SBA Web experience. 
		// (It might also be argued to be a Section 508 requirement, not to subject the user to "cognitive dissonance".) 
		gDivSBALogo.style.display			=
		gDivMainNav.style.display			=
		gDivAppName.style.display			=
		gDivBotMost.style.display			= "";
		gDivAppInfo.style.display			= gDspAppInfo;
		gDivAppNav.style.display			= gDspAppNav;
		$("#DivAppData").animate(
			{
			top:							kHeightTopOfAppData												+ "px",
			left:							((gDspAppNav == "none") ? 0 : kWidthLeftOfAppData)				+ "px",
			height:							(parseInt(sHeight,10) - kHeightTopOfAppData - kHeightBotMost)	+ "px",
			width:							(parseInt(sWidth, 10)
											- ((gDspAppNav == "none")? 0 : kWidthSBALogo))					+ "px"
			}, 1000);						// If parameter 2 is numeric, it's the duration in milliseconds. 
		}
	}

function SlafToggleTextOnly				()
	{
	if	(top.document.SlafToggleTextOnlyForm)
		with (top.document.SlafToggleTextOnlyForm)
			{
			JavaScriptOn.value				= "Yes";
			submit();
			return;
			}
	// If the form doesn't exist, to the same thing using the URL. The following will probably never be done: 
	var	sHRef								= "";
	var	sSearch								= top.location.search;
	if	(sSearch.length > 1)
		{
		var	sString							= unescape(sSearch);
		var	sArray							= sString.substring(1,sString.length).split("&");		// Strip initial "?"
		var	sAlreadyHasToggleTextOnly		= false;
		for	(var i = 0; i < sArray.length; i++)
			{
			var	sElt						= sArray[i];
			if	((sElt.length > 18) && (sElt.substring(0,18) == "SlafToggleTextOnly"))
				{
				sAlreadyHasToggleTextOnly	= true;
				break;
				}
			}
		if	(!sAlreadyHasToggleTextOnly)
			sSearch							+= "&SlafToggleTextOnly=Yes";
		}
	else
		sSearch								= "?SlafToggleTextOnly=Yes";

	with (top.location)
		{
		sHRef								= protocol;
		sHRef								+= "//";
		sHRef								+= host;
		sHRef								+= pathname;
		sHRef								+= sSearch;
		if	(hash.length > 0)
			sHRef							+= hash;
		}
	top.location.href						= sHRef;
	}

// End sbalookandfeel.js


