//turn balloon on and off
var defaultsEnabled = true,								//suppress tooltips
defaultsShowDelay = 0,									//delay show of tooltip
defaultsHideDelay = 0;

//set physical information about images
var defaultsBlank = "/covers/blank.gif",				//location of blank cover image
defaultsLoading = "/covers/loading.gif",				//location of blank loading image
defaultsImageWidth = 200,
defaultsBorderWidth = 19,								//width of border on background image -- separation from div
defaultsBuffer =  5,									//distance to offset borders to avoid overlap on corners
defaultsBubbleImg = new Array(1);  						//preload; array allows for different corners but would need changes to code
	defaultsBubbleImg[0] = new Image(); defaultsBubbleImg[0].src = '/content/resource/js/tooltip/balloon.gif'; 

//change how the balloons look when displayed
var defaultsLocateX = 10, defaultsLocateY = 90,			//move bubble top/left - too close and overlap causes flickering
defaultsStemLength = defaultsImageWidth/4, 				//amount stem sticks out
defaultsStemHeight = defaultsImageWidth/6;				//height of stem

//declare variable
var aElements = new Array(7), 							//array of elements in html divs
sImgContent, sTxtContent,								// arguments passed in
sImgSmall,												//translate sImgContent into a link to the small version
iX=0, iY=0, iW=0, iH=0, iScrollX=0, iScrollY=0, iMouseX, iMouseY, oActiveElement, bLeft=false, bStem=false,
bOpera, bIE, bIE56, bSafari, bOldBoxModel,						// Browser flags
oBodyDOM, oBody,
iState = 0;												// Tooltip active 1, shown 2, move with mouse 4

// timers
Number.prototype.Timer = function(sCode, iTime, bUrge)			//bUrge?
{	if(!this.value || bUrge)
		this.value = window.setTimeout(sCode, iTime);
}
Number.prototype.EndTimer = function()
{	if(this.value)
	{	window.clearTimeout(this.value);
		this.value = 0;
	}
}
var tShow = new Number(0);
var tHide = new Number(0);
var tDuration = new Number(0);
var tFade = new Number(0); 
var tMoveWait = new Number(0);
var bWait = false;

//===================================
function balloon() 
{	fBalloon(arguments, null);
}
//===================================
function fBalloon(arg)
{	if(!oBodyDOM)
		return;
	if(iState)					//iState turned off
		fHide();
	if(!defaultsEnabled)
		return;
	iState = 0x1 | 0x4;			//set to active and move with mouse
	fBalloonContent(arg);
	fCreateDivContent();
	fFormatDivContent();
	fMove();
	fShowInit();
}
//===================================
function fBalloonContent(a)
{	sImgContent = a[0];
	sTxtContent = a[1];
}
//===================================
function fCreateDivContent()
{	var aID = new Array("wrapper", "cover", "tr", "tl", "br", "bl", "hide", "stem", "text"); //array counts from 1
	var sImage = defaultsLoading;
//	sImgSmall = sImgContent.replace('/l/', '/s/').replace('/m/', '/s/').replace('.jpg','.gif');
	aElements[0].innerHTML =
		(	'<div id="wrapper">'
			+ '<span id="stem"></span>'
			+ '<img id="cover" src="' + sImage + '" />'
			+ ((sTxtContent != undefined) ? ('<div id="text">Ref: ' + sTxtContent + '</div>') : '')
			+ '<div id="tr">'
				+ '<div id="tl">'
					+ '<div id="br">'
						+ '<div id="bl">'
							+ '<img id="hide" src="' + sImage + '" />'
						+ '</div>'
					+ '</div>'
				+ '</div>'
			+ '</div>'
		+ '</div>'
		);
// loop through all the css settings
	for(var i = aID.length; i; --i)
		aElements[i] = fGetElement(aID[i - 1]);
// preload the large image and replace when complete
	var i = new Image();
	i.onload = function() 
	{	aElements[2].src = sImgContent;		//cover
		aElements[7].src = sImgContent;		//hide
		fResetMainDivHeight();
	}
	i.src = sImgContent;
}
//===================================
function fResetMainDivHeight()
{	var iBorderSize = defaultsBorderWidth;
	var iBuffer = defaultsBuffer;
	var h = iBorderSize + fGetDivHeight(aElements[2]) + iBorderSize;
	aElements[0].style.height = h + 'px';
}
//===================================
function fFormatDivContent()
{	var css;
	var iBorderSize = defaultsBorderWidth;
	var iBuffer = defaultsBuffer;

	if (aElements[1])
	{	css = aElements[1].style;		//wrapper
		css.zIndex = 21;
		css.position = 'relative';
		css.left = defaultsStemLength + 'px';
		css.top = iBorderSize + 'px';
		css.border = '0px solid #000000';
		css.margin = '0px';
		css.padding = '0px';
	}
	if (aElements[2])					//img
	{	css = aElements[2].style;
		css.zIndex = 22;
		css.position = 'absolute';
		css.width = defaultsImageWidth + 'px';
		css.left = '0px';
		css.border = '0px solid #000000';
		css.margin = '0px';
		css.padding = '0px';
	}
	if (aElements[3])					//top right
	{	css = aElements[3].style;
		css.position = 'absolute';
		css.background = 'url(' + defaultsBubbleImg[0].src + ') no-repeat';
		css.backgroundPosition = '100% 0';
		css.zIndex = 23;
		css.left = iBorderSize + 2*iBuffer + 'px'; 
		css.top = -iBorderSize + 'px';
		css.border = '0px solid #000000';
		css.margin = '0px';
		css.padding = '0px';
	}
	if (aElements[4])	//top left
	{	css = aElements[4].style;
		css.background = 'url(' + defaultsBubbleImg[0].src + ') no-repeat';
		css.position = 'relative';
		css.zIndex = 24;
		css.backgroundPosition = '0% 0%';
		css.left = - (2*iBorderSize + 2*iBuffer) + 'px'; 
		css.top = '0px';
		css.border = '0px solid #000000';
		css.margin = '0px';
		css.padding = '0px';
	}
	if (aElements[5])	// bottom right
	{	css = aElements[5].style;
		css.background = 'url(' + defaultsBubbleImg[0].src + ') no-repeat';
		css.backgroundPosition = '100% 100%';
		css.position = 'relative';
		css.zIndex = 25;
		css.left = 2*iBorderSize + 2*iBuffer + 'px'; 
		css.top = - 8 + 2*iBorderSize + 2*iBuffer + 'px';			//the bottom drops down in Firefox -- not clear why
		css.border = '0px solid #000000';
		css.margin = '0px';
		css.padding = '0px';
	}
	if (aElements[6])	//bottom left
	{	css = aElements[6].style;
		css.background = 'url(' + defaultsBubbleImg[0].src + ') no-repeat';
		css.backgroundPosition = '0 100%';
		css.position = 'relative';
		css.zIndex = 26;
		css.left = - (2*iBorderSize + 2*iBuffer) + 'px'; 
		css.top = '0px';
		css.border = '0px solid #000000';
		css.margin = '0px';
		css.padding = '0px';
	}
	if (aElements[7])	//hidden image
	{	css = aElements[7].style;
		css.visibility = 'hidden';
		css.position = 'relative';
		css.width = defaultsImageWidth + 'px';
		css.margin = - iBuffer + 'px';
		css.border = '0px solid #000000';
		css.padding = '0px';
		css.top = '-10px';
	}
	if (aElements[8])	//stem
	{	css = aElements[8].style;
		css.zIndex = 19;
		css.display = 'block';
		css.fontSize = 0;
		css.height = '1px';
		css.width = '1px';
		css.position = 'absolute';
		css.top =  iBorderSize + iBuffer + 'px';
		css.borderTop = defaultsStemHeight + 'px solid transparent'; // set angle of arrow
		css.borderBottom = '0px solid transparent';
		if (bLeft == true)
		{	css.left = defaultsImageWidth + 'px'; //
			css.borderLeft = defaultsStemLength + 'px solid #000000'; // pixel size = tail size
		}
		else if (bLeft == false)
		{	css.left = - defaultsStemLength + 'px'; // - defaultsStemLength - iBorderSize + iBuffer + 'px';
			css.borderRight = defaultsStemLength + 'px solid #000000'; // pixel size = tail size
		}
		if (bIE56)
		{	css.borderTopColor = 'cyan'; //No 'transparent' borders in IE6
			css.borderBottomColor = 'cyan';
   			css.filter = 'chroma(color="cyan")'; /* filter out the cyan color */ 
		}
	}
	if (aElements[9])	//text if no image
	{	css = aElements[9].style;
		if (aElements[2].src.indexOf(defaultsBlank) == -1)
		{	css.display = 'none';
		}
		else
		{	css.fontSize = '8pt';
			css.position = 'absolute';
			css.top = '0px';
			css.left =  2*defaultsBorderWidth + 'px';
			css.zIndex = 27;
		}
	}

	iW = defaultsStemLength + fGetDivWidth(aElements[2]) + defaultsStemLength;
	iH = iBorderSize + fGetDivHeight(aElements[2]) + iBorderSize;

	if (aElements[0])				//container
	{	css = aElements[0].style;
		css.zIndex = 1020;
		css.border = "0px solid #ff00ff";
		css.width = iW + 'px'
		css.height = iH + 'px';
	}
}
//===================================
//function fGetClientW()
//{	return(document.body && (typeof(document.body.clientWidth) != "undefined") ? document.body.clientWidth
//		: (typeof(window.innerWidth) != "undefined") ? window.innerWidth
//		: oBodyDOM ? (oBodyDOM.clientWidth || 0)
//		: 0);
//}
//===================================
//function fGetClientH()
//{	return(document.body && (typeof(document.body.clientHeight) != "undefined") ? document.body.clientHeight
//		: (typeof(window.innerHeight) != "undefined") ? window.innerHeight
//		: oBodyDOM ? (oBodyDOM.clientHeight || 0)
//		: 0);
//}
//===================================
function fGetDivWidth(el)
{	return(el ? (el.offsetWidth || el.style.pixelWidth || 0) : 0);
}
//===================================
function fGetDivHeight(el)
{	return(el ? (el.offsetHeight || el.style.pixelHeight || 0) : 0);
}
//===================================
function fShowInit()
{	tShow.Timer("fShow()", defaultsShowDelay, true);
}
//===================================
function fShow()
{	var css = aElements[0].style;
	css.visibility = "visible";
	iState |= 0x2;			//set shown in iState
	fShowIfrm();
}
//===================================
function fShowIfrm()
{	if(bIE56)
	{	var ifrm = aElements[aElements.length - 1];
		if(ifrm)
		{	var css = ifrm.style;
			css.zIndex = aElements[0].style.zIndex - 1;
			css.display = "block";
		}
	}
}
//===================================
//The following run on page load.
//===================================
function fInitialise()
{	if(!fValidBrowser() || !fMakeDiv()) return;
	fW3cBoxModel();
	fAddEventFunction(document, "mousemove", fMove);
	fAddEventFunction(window, "scroll", fScroll);
	fAddEventFunction(window, "unload", fHide);
	fHide();
}
//===================================
function fValidBrowser()
{	var n, nv, n6, w3c;
	n = navigator.userAgent.toLowerCase(),
	nv = navigator.appVersion;
	bOpera = (document.defaultView && typeof(eval("window.opera")) != "undefined");		//defaultView is general a reference to Window
	bIE = n.indexOf("msie") && document.all && !bOpera;
	bSafari = n.indexOf("safari");
	if(bIE)
	{	var bOldIE = (!document.compatMode || document.compatMode == "BackCompat");  //"BackCompat" for Quirks; "CSS1Compat" for Strict 
		oBodyDOM = !bOldIE ? document.documentElement : (document.body || null);
		if(oBodyDOM)
			bIE56 = parseFloat(nv.substring(nv.indexOf("MSIE") + 5)) >= 5.5 && typeof document.body.style.maxHeight == "undefined";
	}
	else
	{	oBodyDOM = document.documentElement || document.body || (document.getElementsByTagName 
			? document.getElementsByTagName("body")[0]
			: null);
		if(!bOpera)
		{	n6 = document.defaultView && typeof document.defaultView.getComputedStyle != "undefined";
			w3c = !n6 && document.getElementById;
		}
	}
	oBody = (document.getElementsByTagName ? document.getElementsByTagName("body")[0] : (document.body || null));
	if(bIE || n6 || bOpera || bSafari || w3c)
	{	if(oBody && oBodyDOM)
		{	if(document.attachEvent || document.addEventListener)
				return true;
		}
	}
	oBodyDOM = null;
	return false;
}
//===================================
function fMakeDiv()		//create the balloon Div
{	if(oBody.insertAdjacentHTML)
		oBody.insertAdjacentHTML("afterBegin", fMakeMainDiv());
	else if(typeof oBody.innerHTML != "undefined" && document.createElement && oBody.appendChild)
		oBody.appendChild(fMakeMainDivDOM());
	if(window.fGetMainDiv && fGetMainDiv())
		return true;
	oBodyDOM = null;
	return false;
}
//===================================
function fMakeMainDiv()
{	return('<div id="container"></div>' +
			(bIE56 
			? ('<iframe id="blnIFrame" src="javascript:false" scrolling="no" frameborder="0" style="filter:Alpha(opacity=0);position:absolute;top:0px;left:0px;display:none;"></iframe>')
			: ''));
}
//===================================
function fMakeMainDivDOM()
{	var el = document.createElement("div");
	if(el)
		el.id = "container";
	return el;
}
//===================================
function fGetMainDiv()
{	aElements[0] = fGetElement("container");
	if(bIE56 && aElements[0])
	{	aElements[aElements.length - 1] = fGetElement("blnIFrame");
		if(!aElements[aElements.length - 1])
			aElements[0] = null;
	}
	if(aElements[0])
	{	var css = aElements[0].style;
		css.visibility = "hidden";
		css.position = "absolute";
		css.overflow = "hidden";
		return true;
	}
	return false;
}
//==================================
function fGetElement(id)
{	return(document.getElementById ? document.getElementById(id)
		: document.all ? document.all[id]
		: null);
}
//===================================
function fW3cBoxModel()
{	var css = aElements[0].style;
	css.padding = "10px";
	css.width = "40px";
	bOldBoxModel = (fGetDivWidth(aElements[0]) == 40);
	css.padding = "0px";
	fResetMainDiv();
}
//===================================
function fGetDivWidth(oElement)
{	return(oElement ? (oElement.offsetWidth || oElement.style.pixelWidth || 0) : 0);
}
//===================================
function fResetMainDiv()
{	var iWidth = (window.screen && screen.width) ? screen.width : 10000;
	fPositionBalloon(-iWidth, 0);
	aElements[0].innerHTML = "";
	aElements[0].style.width = (iWidth - 1) + "px";
}
//===================================
function fAddEventFunction(oElement, sEvent, fCalled)
{	if(oElement)
	{	if(oElement.addEventListener)
			oElement.addEventListener(sEvent, fCalled, false);
		else
			oElement.attachEvent("on" + sEvent, fCalled);
	}
}
//===================================
function fRemoveEventFunction(oElement, sEvent, PFnc)
{	if(oElement)
	{
		if(oElement.removeEventListener)
			oElement.removeEventListener(sEvent, PFnc, false);
		else
			oElement.detachEvent("on" + sEvent, PFnc);
	}
}
//===================================
function fMove(oEvent)
{	e = window.event || oEvent;
	if(e)
	{	iMouseX = fGetEventX(oEvent);
		iMouseY = fGetEventY(oEvent);
	}
	if(iState)			//if iState not turned off
	{	if(!oActiveElement && oEvent)
			fInitOverElement(oEvent);
		if(iState & 0x4)			//if Move with mouse is set in iState
		{	if(!bOpera && !bIE && !bSafari)		// Protect some browsers against jam of mousemove events
			{	if(bWait)
					return;
				bWait = true;
				tMoveWait.Timer("bWait = false;", 1, true);
			}
			fPositionBalloon(fDetermineX(), fDetermineY());
			fPositionStem(iY);
		}
	}
}
//===================================
function fPositionStem(y)
{	var y;	
	var iBorderSize = defaultsBorderWidth;
	var iBuffer = defaultsBuffer;
	var iOffsetY = defaultsLocateY;
	if (bStem == true)			//mouse is in the top zone
	{	y = (iMouseY - y) - (iOffsetY - (iBorderSize + iBuffer));
		if (y < - 10)
		{	y = - 10;
		}
		else if (y > fGetDivHeight(aElements[0]) - 70)
		{	y = fGetDivHeight(aElements[0]) - 70;
		}
	}
		else
	{
		y = iBorderSize + iBuffer;
	}
	css = aElements[8].style;			//stem
	css.top = y + 'px';
}
//===================================
function fPositionBalloon(x, y)
{	var css = aElements[0].style;
	iX = x;
	iY = y;
	css.left = x + "px";
	css.top = y + "px";
	if(bIE56)
	{	var ifrm = aElements[0];
		if(ifrm)
		{	ifrm.style.left = css.left;
			ifrm.style.top = css.top;
		}
	}
}

//===================================
function fDetermineX()
{	var x = 0;
	var iImageOffset = defaultsLocateX
	var iAreaWidth = fGetDivWidth(aElements[0])
	if ((iMouseX + iAreaWidth) > fGetWinWidth())
	{	x = iMouseX - iAreaWidth - iImageOffset;
		bLeft = true;
	}
	else
	{	x = iMouseX + iImageOffset;
		bLeft = false;
	}
	return x;
}
//===================================
function fDetermineY()
{	var y = 0;
	var iImageOffset = defaultsLocateY
	var iRemainingHeight = fGetDivHeight(aElements[0]) - iImageOffset
	if ((iMouseY - iScrollY) < (iImageOffset))
	{	y = iScrollY;
		bStem = true;
	}
	else if ((iMouseY - iScrollY + iRemainingHeight) > (fGetWinHeight()))
	{	y = (iScrollY + fGetWinHeight() - iImageOffset - iRemainingHeight);
		bStem = true;
	}
	else 
	{	y = iMouseY - iImageOffset;
		bStem = false;
	}
	return y;
}
//===================================
function fGetWinHeight() 
{	var h = 0;
	if( typeof( window.innerHeight ) == 'number' ) 
	{ //Non-IE
		h = window.innerHeight;
	}
	else if( document.documentElement && document.documentElement.clientHeight ) 
	{ //IE 6+ in 'standards compliant mode'
		h = document.documentElement.clientHeight;
	}
	else if( document.body && document.body.clientHeight ) 
	{ //IE 4 compatible
		h = document.body.clientHeight;
	}
	return h;
}
//===================================
function fGetWinWidth() 
{	var w = 0;
	if( typeof( window.innerWidth ) == 'number' ) 
	{ //Non-IE
		w = window.innerWidth;
	}
	else if( document.documentElement && document.documentElement.clientWidth ) 
	{ //IE 6+ in 'standards compliant mode'
		w = document.documentElement.clientWidth;
	}
	else if( document.body && document.body.clientWidth ) 
	{ //IE 4 compatible
		w = document.body.clientWidth;
	}
	return w;
}
//===================================
function fGetEventX(oEvent)
{	return (oEvent ? ((typeof(oEvent.pageX) != "undefined") ? oEvent.pageX : (oEvent.clientX + iScrollX)) : 0);
}
//===================================
function fGetEventY(oEvent)
{	return (oEvent ? ((typeof(oEvent.pageY) != "undefined") ? oEvent.pageY : (oEvent.clientY + iScrollY)) : 0);
}
//===================================
function fInitOverElement(oEvent)
{	oActiveElement = oEvent.target || oEvent.srcElement;
	fRemoveAlt(oActiveElement);
	fManageExit(true);
}
//===================================
function fRemoveAlt(oEl)
{	var aChildren;
	if(oEl.alt)
		oEl.alt = "";
	if(oEl.title)
		oEl.title = "";
	aChildren = oEl.childNodes || oEl.children || null;
	if(aChildren)
	{	for(var i = aChildren.length; i;)
			fRemoveAlt(aChildren[--i]);
	}
}
//===================================
function fManageExit(bAdd)
{	var oSetFunction = bAdd ? fAddEventFunction : fRemoveEventFunction;
	if(bAdd != fManageExit.bOn)
	{	oSetFunction(oActiveElement, "mouseout", fOnOut);
		fManageExit.bOn = bAdd;
	}
}

fManageExit.bOn = false;
//===================================
function fOnOut()
{	fManageExit(false);
	fHideInit();
}
//===================================
function fHideInit()
{	iState &= ~0x4;		//turn off move with mouse state 0x4 and retain other iState.
	tHide.Timer("fHide();", defaultsHideDelay, false);
}
//===================================
function fScroll()
	{	iScrollX = fGetScrollX();
		iScrollY = fGetScrollY();
		fHideInit();
	}
//===================================
function fGetScrollX()
{	return(window.pageXOffset || (oBodyDOM ? (oBodyDOM.scrollLeft || 0) : 0));
}
//===================================
function fGetScrollY()
{	return(window.pageYOffset || (oBodyDOM ? (oBodyDOM.scrollTop || 0) : 0));
}
//===================================
function fHide()
{	if(oBodyDOM && iState)		//take no action if iState = 0
	{
//		if(iState & 0x2) 		//if shown is turned on in iState
//		{	aElements[0].style.visibility = "hidden";			//getting rid of this allows smooth scrolling///*****
//		}
		tShow.EndTimer();
		tHide.EndTimer();
		tDuration.EndTimer();
		tFade.EndTimer();
		if(!bOpera && !bIE)
		{	tMoveWait.EndTimer();
			bWait = false;
		}
		fManageExit(false);
		iState = 0;
		oActiveElement = null;
		fResetMainDiv();
		if(aElements[aElements.length - 1])
			aElements[aElements.length - 1].style.display = "none";
	}
}
//===================================
fInitialise();

