/** *********************************************************************************
*	FILE:		busy.js
*
*	REQUIRES:	FireFox browser
*						prototype.js
*						busy.css
*
*********************************************************************************** */

window.Busy = function()
{

	// Singleton class
	if (window.Busy)	return window.Busy;

	/* -- Public  ------------------------------------------------------------- */
	var _public =
	{
		// initialize s/b executed when the Busy.js is loaded
		//		The busy presentation elements are created and cached for when when they are used.
		initialize: function()
		{
			// Load the style sheet
			//setTimeout(function(){loadStyleFile("script/css/Busy.css");},0);

			// Retrieve the background image and extract the image geometries
			if (!window.top.busyBackground)
				(window.top.busyBackground=new Image()).src = "script/css/busy/BusyBackground.gif";
			_private.busyBackground=window.top.busyBackground;
			_private.busyBackground.bkgrdWidth = _private.busyBackground.naturalWidth;
			_private.busyBackground.bkgrdHeight = _private.busyBackground.naturalHeight;

			// Pre-create the busy container
			var busyElm = $(document.createElement("div"));
			_private.busyElm = busyElm;
			busyElm = Object.extend(busyElm, {id:"busy", name:"busy", className:"busy"});
			busyElm.observe('click', _private.emptyFunction);
			busyElm.setStyle({
				display:"block",
				border:"0px transparent none",
				position:"absolute",
				opacity: 0,
				left:"0px", top:"0px",
				font:"10pt Arial",
				zIndex:1000,
				height:_private.busyBackground.bkgrdHeight+"px",
				width:_private.busyBackground.bkgrdWidth+"px",
				background:'url("'+_private.busyBackground.src+'") no-repeat scroll 0 0 transparent'
				});

			// Create busy icon and calculate position within the container
			(_private.busyImage=$(new Image())).src = "script/css/busy/Busy.gif";
			_private.busyImage.imgwidth = _private.busyImage.naturalWidth;
			_private.busyImage.imgheight = _private.busyImage.naturalHeight;
			_private.busyImage.setStyle({
				position:"absolute",
				left:Math.round((_private.busyBackground.bkgrdWidth-_private.busyImage.imgwidth)/2)+"px",
				top:Math.round((_private.busyBackground.bkgrdHeight-_private.busyImage.imgheight)/8)+"px",	/*Math.round((_private.busyBackground.bkgrdHeight-_private.busyImage.imgheight)/8)*/
				display:"block"
				});

			// Pre-create the message container
			_private.messageElm=document.createElement("p");
			_private.messageElm.setStyle({
				/*position:"absolute",
				left:"0px",
				top:(parseInt(_private.busyImage.style.top)+_private.busyImage.imgheight)+"px",*/
				padding:(parseInt(_private.busyImage.style.top)+_private.busyImage.imgheight+2)+"px 5px 2px 5px",
				display:"auto",
				textAlign:"center",
				marginLeft: "auto",
				marginRight: "auto",
				font: "normal 9px Verdana, Geneva, Arial, Helvetica, sans-serif",
				color: "#006600"
				});

			// Add the busy icon and message container to the busy presentation container
			busyElm.appendChild(_private.busyImage);
			busyElm.appendChild(_private.messageElm);
		},


		// Show the busy presentation with default behavior, almost immediate show the fog, 1/2 second later show the spinner
		showBusy : function(message)
		{
			_public.showBusyTimer(message, 100, 500);
			//setTimeout(function(){if (Busy.isBusy()) Busy.removeBusy();},7000);
		},


		// Display the busy presentation with custom fade in setting for fog and spinner
		showBusyTimer : function(message, delayFog, delaySpinner)
		{
			// Don't let the busy message stay up for more than 30 seconds
			//setTimeout(function(){if (Busy.isBusy()) Busy.removeBusy();},delaySpinner+30000);

			// Stuff the message into the busy presentation
			message = (!message || typeof(message)!='string') ? 'Please Wait...' : message;
			if (message.length > 80)
                                message = message.substr(0,80) + ' ...';
			_private.messageElm.innerHTML = message;

			_private.pageSize = getPageSize(document.body);	//_private.getPageSize(document.body);
			_private.buildWaitUnderlay();

			// Position the busy presentation
			var waitLeft = _private.pageSize.scrollLeft + parseInt(Math.abs(_private.pageSize.windowWidth-_private.busyBackground.bkgrdWidth)/2);
			var waitTop = _private.pageSize.scrollTop + parseInt(Math.abs(_private.pageSize.windowHeight-_private.busyBackground.bkgrdHeight)/3);
			_private.busyElm.setStyle({position:"absolute", left:waitLeft+"px", top:waitTop+"px",opacity:0});

			// Add the busy presentation into the page DOM for display
			var htmlBody = document.getElementsByTagName("body")[0];
			htmlBody.appendChild(_private.busyElm);

			// Perform the presentation behavior, fade the fog in then fade the spinner in
			_private.waitOpacity = 0;
			setTimeout(function() { _private.setDivOpacity('_waitunderlay',70)}, delayFog);
			_private.waitTimer = setTimeout(_private.fadeInWait, delaySpinner);
		},


		// Hide the busy presentation by pulling it from the DOM
		removeBusy : function()
		{
			// If we are still waiting to show the Please Wait, cancel that action
			if (_private.waitTimer)
			{
				clearTimeout(_private.waitTimer);
				_private.waitTimer = null;
			}

			_private.unhideDropDowns();

			_private.removeWaitUnderlay();

			var pwDiv = document.getElementById("busy");
			if (pwDiv)
			{
				var prnt = pwDiv.parentNode;
				prnt.removeChild(pwDiv);
			}
		},



		// Determines if the busy presentation is currently being display by simply determining its existence in the DOM
		isBusy : function()
		{
			return ( document.getElementById("busy") );
		},


		// Provides the minimal html to render the Busy within the overlay while loading the content page
		renderHtml : function(message, delayFog, delaySpinner, url)
		{
			var html =
				"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" +
				"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">" +
				"<head>" +
					"<script type=\"text/javascript\">history.forward()<\/script>" +
					"<script type=\"text/javascript\" src=\"/scriptcompressed/prototype-1.6.1.0.js\"><\/script>" +
					"<script type=\"text/javascript\" src=\"/scriptcompressed/Overlay.js\"><\/script>" +
					"<script type=\"text/javascript\" src=\"/scriptcompressed/Busy.js\"><\/script>" +
					"<script type=\"text/javascript\">" +
						"function pageInit()" +
						"{" +
							"Busy.showBusyTimer('"+message+"',"+(delayFog ? delayFog:0)+","+(delaySpinner ? delaySpinner:200)+");"+
							"window.location.href = '"+url+"';"+
						"}" +
					"Event.observe(document, 'dom:loaded', pageInit);"+
					"<\/script>" +
				"<\/head>" +
				"<body><\/body>" +
				"<\/html>";
			return html;
		}


	};


	/* -- Private ------------------------------------------------------------- */
	var _private =
	{
		/*
		document:			(window.self.frameElement) ?
										(window.self.frameElement.contentWindow) ?
											window.self.frameElement.contentWindow.document :
											(window.self.frameElement.contentDocument) ?
												window.self.frameElement.contentDocument.document : window.top.document :
										window.top.document,
		*/
		busyElm:				null,	// busy presentation top element (div id="busy")
		busyImage:			null,  // Image object of the spinner	"busy/Busy.gif"
		busyBackground:	null,	// Background image of the busy message "busy/BusyBackground.gif"
		messageElm:		null,	// message container
		waitOpacity:			0,
		waitTimer:			null,
		pageSize:				null,
		// The fade speed needs to be faster in IE since it's slower to fade
		fadeDelay : (Prototype.Browser.IE ? 6 : 20),


		fadeInWait : function()
		{
			_private.waitTimer = null;

			if (_private.waitOpacity == 0)	_private.hideDropDowns();

			if(_private.waitOpacity < 100)
			{
				_private.waitOpacity += 2;
				_private.setDivOpacity("busy", _private.waitOpacity);
				setTimeout(_private.fadeInWait, _private.fadeDelay);
			}
		},


		buildWaitUnderlay: function()
		{
			var	htmlBody = document.getElementsByTagName("body")[0],
					isUnderlayThere = htmlBody.select('#_waitunderlay');
			if (!isUnderlayThere || isUnderlayThere.length==0)
			{
				var waitUnderlay = $(document.createElement("div"));
				waitUnderlay = Object.extend(waitUnderlay, {id:"_waitunderlay", name:"_waitunderlay", className:"wait-underlay"});
				waitUnderlay.setStyle({display:'inline', position:'absolute', top:'0px', left:'0px', backgroundColor:'#dddddd', opacity:0.0,
										height:_private.pageSize.pageHeight+"px", width:"100%", zIndex:'999'});
				htmlBody.appendChild(waitUnderlay);
			}
		},

		removeWaitUnderlay: function()
		{
			var	htmlBody = document.getElementsByTagName("body")[0],
					waitUnderlay = htmlBody.select('#_waitunderlay');
			if (waitUnderlay && waitUnderlay.length>0)
			{
				waitUnderlay = waitUnderlay[0];
				Event.stopObserving(waitUnderlay, 'click', _private.emptyFunction);
				waitUnderlay.style.display = 'none';
				waitUnderlay.style.zIndex = 0;
				var prnt = waitUnderlay.parentNode;
				prnt.removeChild(waitUnderlay);
			}
		},


		// Sets the opacity / transparency of an element to a specified opacity.
		// Supports IE, Gecko (Firefox, Netscape), WebKit (Safari, Chrome)
		// argDivName: Either the name of the Element or the Object itself
		// argOpacity: Opacity to set (0 to 100)
		setDivOpacity : function(argDivName, argOpacity)
		{
			// Updated to support all browsers including Safari / Chrome
			var	value = parseInt(argOpacity) / 100,
					div = $(argDivName);

			if (div)
			{
				if (Prototype.Browser.IE)
				{
					div.filters.alpha.opacity = (value*100);
					return;  // Stop at special case for IE to improve performance
				}
			    div.style.opacity = value;
			    div.style.MozOpacity = value;
			    div.style.KhtmlOpacity = value;
			}
		},


		// Hides a list of SELECT elements (use for IE browser only)
		hideDropDowns: function()
		{
			if (!Prototype.Browser.IE) return;
			var	elements = document.getElementsByTagName("select"),
					e, element, description, dLength;
			for (e = elements.length-1; e>=0; e--)
			{
				element = elements[e];
				if (element.style.display != 'none')
				{
					description = (element.selectedIndex >= 0) ? element.options[element.selectedIndex].text : '';
					dLength = Math.ceil(1.1*description.length);
					dLength = (dLength <= 0) ? 1: dLength;
					var newInputelement = document.createElement('input');
					newInputelement = Object.extend(newInputelement,
						{id:"xbusy_"+element.id, readOnly:true, className:'ReadOnly', type:'text', value:description, size:dLength});
					element.parentNode.insertBefore(newInputelement,element.nextSibling);
					newInputelement.style.width = parseInt(element.style.width)+'px';
					newInputelement.style.height = parseInt(element.style.height)+'px';
					element.style.display = 'none';
				}
			}
		},

		// Unhides all the elements that were hidden  (use for IE browser only)
		unhideDropDowns: function()
		{
			if (!Prototype.Browser.IE) return;
			var element, tmpElement, e, elements = document.getElementsByTagName("select");
			for (e = elements.length-1; e>=0; e--)
			{
				element = elements[e];
				tmpElement = $("xbusy_"+element.id);
				if (tmpElement)
				{// Existence of element prefixed by xcal_ indicates the calendar hid the select element
					element.parentNode.removeChild(tmpElement);
					element.style.display = '';
				}
			}
		},

		// Determine the page dimensions
		/* Use function from common.js
		getPageSize: function(documentbody)
		{
			documentbody = documentbody || document.body;
			var windowWidth, windowHeight, pageHeight, pageWidth;
			if ( documentbody  != document.body )
			{
				windowWidth = $(documentbody).getWidth();
				windowHeight = $(documentbody).getHeight();
				pageWidth = documentbody.scrollWidth;
				pageHeight = documentbody.scrollHeight;
			}
			else
			{
				var xScroll, yScroll, dde = document.documentElement;
				if (window.innerHeight && window.scrollMaxY)
				{
					xScroll = document.body.scrollWidth;
					yScroll = window.innerHeight + window.scrollMaxY;
				}
				else if (document.body.scrollHeight > document.body.offsetHeight)
				{ // all but Explorer Mac
					xScroll = document.body.scrollWidth;
					yScroll = document.body.scrollHeight;
				}
				else
				{ // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
					xScroll = document.body.offsetWidth;
					yScroll = document.body.offsetHeight;
				}

				// If the ScrollHeight from the document element is taller, use that
				if (dde && dde.scrollHeight > yScroll)
					yScroll = dde.scrollHeight;

				if (self.innerHeight)
				{  // all except Explorer
					windowWidth = self.innerWidth;
					windowHeight = self.innerHeight;
				}
				else if (dde && dde.clientHeight)
				{ // Explorer 6 Strict Mode
					windowWidth = dde.clientWidth;
					windowHeight = dde.clientHeight;
				}
				else if (document.body)
				{ // other Explorers
					windowWidth = document.body.clientWidth;
					windowHeight = document.body.clientHeight;
				}

				// for small pages with total height less then height of the viewport
				if( yScroll < windowHeight )
				{
					pageHeight = windowHeight;
				}
				else
				{
					pageHeight = yScroll;
				}

				// for small pages with total width less then width of the viewport
				if(xScroll < windowWidth)
				{
					pageWidth = windowWidth;
				}
				else
				{
					pageWidth = xScroll;
				}
			}

			var scrOfX = 0, scrOfY = 0;
			if (typeof( window.pageYOffset ) == 'number')
			{
				//Netscape compliant
				scrOfY = window.pageYOffset;
				scrOfX = window.pageXOffset;
			}
			else if (document.body && (document.body.scrollLeft || document.body.scrollTop))
			{
				//DOM compliant
				scrOfY = document.body.scrollTop;
				scrOfX = document.body.scrollLeft;
			}
			else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop))
			{
				//IE6 standards compliant mode
				scrOfY = document.documentElement.scrollTop;
				scrOfX = document.documentElement.scrollLeft;
			}
			return( {pageWidth: pageWidth ,pageHeight: pageHeight ,
						windowWidth: windowWidth, windowHeight: windowHeight,
						scrollLeft: scrOfX, scrollTop: scrOfY} );
		},
		*/

		emptyFunction : function(evnt)
		{
			evnt.stop();
			return(false);
		}
	};

	return _public;
}();


// When the DOM is constructed, make sure the formMgr initialization is executed.
Event.observe(document, "dom:loaded", Busy.initialize);


