// +++ Balloon +++ //

	function g_fncBalloon(n_objAnchor, n_objInnerObject, n_intWidth){
	
		this.objAnchor = null;
		this.strInnerHTML = "";
		this.objInnerObject = null;
		this.intWidth = 600;
		this.intMaxHeight = null;
	
		this.strBalloonOrientation = 'AUTO';
		
		var g_objThis = this;
		var m_objBalloonContainerDiv, m_objBalloonVMLObject, m_objPointerVMLObject, m_objContentDiv, m_objButtonSpan;
			
		m_objBalloonVMLObject = document.createElement('<v:roundrect fillcolor="#ffffff" arcsize=".05" style="width:99%;height:150;position:relative;padding:9px 24px 9px 15px;background-color:transparent" strokecolor="#666666" strokeweight="1px"></v:roundrect>');
		m_objPointerVMLObject = document.createElement('<v:shape style="width:100;height:46;position:relative;padding:0px;background-color:transparent" coordorigin="0 0" strokecolor="#666666" strokeweight="1px" fillcolor="#ffffff"></v:shape>');
		
		m_objIFrame = document.createElement("<iframe style='filter:progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0);width:99%;left:0px;position:absolute;top:0px' src='javascript:false;' frameBorder='0' scrolling='no'></iframe>");
		m_objBalloonContainerDiv = document.createElement("<div style='width:100%;position:absolute;visibility:hidden;background-color:; '></div>");
		m_objContentDiv = document.createElement("<div style='margin:0;overflow-x:auto;overflow-y:auto;'></div>");
		m_objButtonSpan = document.createElement("<span style='border:1px solid #888888;color:#888888;position:absolute;right:9px;top:9px;font-family:verdana;font-weight:bold;font-size:10px;height:14px;width:14px;text-align:center;cursor:hand' title='Close'></span>");
		m_objButtonSpan.innerHTML = 'X';
				
		m_objBalloonContainerDiv.appendChild(m_objBalloonVMLObject);
		m_objBalloonContainerDiv.appendChild(m_objPointerVMLObject);
		m_objBalloonVMLObject.appendChild(m_objIFrame);
		m_objBalloonVMLObject.appendChild(m_objButtonSpan);
		m_objBalloonVMLObject.appendChild(m_objContentDiv);
		
		// private members
		this._objBalloonContainerDiv = m_objBalloonContainerDiv;
		this._objBalloonVMLObject = m_objBalloonVMLObject;
		this._objPointerVMLObject = m_objPointerVMLObject;
		this._objContentDiv = m_objContentDiv;
		this._objButtonSpan = m_objButtonSpan;
		this._objIFrame = m_objIFrame;
		this._intTimeoutID = null;
		this.intMaxBalloonZindex = 9000;
		
		if (typeof(n_objAnchor) == 'object')
			this.objAnchor = n_objAnchor;
	
		if (typeof(n_objInnerObject) == 'object')
			this.fncSetInnerObject(n_objInnerObject);
	
		if (typeof(n_objInnerObject) == 'string')
			this.fncSetInnerHTML(n_objInnerObject);
	
		if (typeof(n_intWidth) == 'number')
			this.fncSetWidth(n_intWidth);
		
		this.fncHide = function(){
			g_objThis._fncDetachBalloonEvents();
			g_objThis._fncHandleHide();
		};
		
		this.fncShow = function(n_intTimeout){
			g_objThis._fncDetachBalloonEvents();
			g_objThis._fncHandleShow();
			g_objThis._fncReorderIndex();
			g_objThis._fncSetTimeout(n_intTimeout);
		};
		
		this.fncUnload = function(){
			g_objThis._fncDetachBalloonEvents();
			window.detachEvent("onunload", g_objThis.fncUnload);
		};
		
		this.fncClick = function(){
			g_objThis._fncReorderIndex();
		}
		
		window.attachEvent("onunload", this.fncUnload);
		
	}
	
	g_fncBalloon.prototype.fncSetOrientation = function (n_strBalloonOrientation){
		this.strBalloonOrientation = n_strBalloonOrientation;
	}
	
	g_fncBalloon.prototype.fncSetInnerObject = function (n_objInnerObject){
		this.objInnerObject = n_objInnerObject;
		
		this._fncClearDisplayArea();
			
		this._objContentDiv.appendChild(this.objInnerObject);
		this.objInnerObject.style.display = 'block';
		
		if (this.fncIsVisible())
			this.fncShow();
			
	}
	
	g_fncBalloon.prototype.fncSetInnerHTML = function (n_strInnerText){
		this._fncClearDisplayArea();
		
		this.strInnerHTML = n_strInnerText;
		this._objContentDiv.innerHTML = this.strInnerHTML
		
		if (this.fncIsVisible())
			this.fncShow();
		
	}
		
	g_fncBalloon.prototype.fncSetWidth = function (n_intWidth){
		this.intWidth = isNaN(n_intWidth) ? 0 : n_intWidth;
	}
	
	g_fncBalloon.prototype.fncSetMaxHeight = function (n_intHeight){
		this.intMaxHeight = isNaN(n_intHeight) ? null : n_intHeight;
	}
	
	g_fncBalloon.prototype.fncIsVisible = function (){
		return this._objBalloonContainerDiv.style.visibility == 'visible';
	}
	
	g_fncBalloon.prototype._fncHandleShow = function (){
	
		var m_objThis = this;
		var m_strXAxis = 'E';
		var m_strYAxis = 'N'
		var m_lngBalloonSlidePercent = 0.40;
		var m_intPointerOffset = 0;
		var m_intTargetSpaceRight = 0;
		var m_intTargetSpaceLeft = 0;
		var m_objElementPosition = this._fncGetPositioningFunctions();

		// these are the paths the make up the pointer
		var m_arrPointerPath = []; 
			m_arrPointerPath['NE'] = 'm 550, 0 l 0, 1000, 1000, 0 e';
			m_arrPointerPath['NW'] = 'm -550, 0 l 0, 1000, -1000, 0 e';
			m_arrPointerPath['SE'] = 'm 550, 0 l 0, -1000, 1000, 0 e';
			m_arrPointerPath['SW'] = 'm -550, 0 l 0, -1000, -1000, 0 e';
						
		// calculate the height and set the width of the entire bubble
		this._objBalloonContainerDiv.style.width = this.intWidth < 240 ? 240 : this.intWidth + 'px';
		this._objBalloonVMLObject.style.height = this._objContentDiv.clientHeight;
					
		// assign the onclick event handler to the button
		this._objButtonSpan.attachEvent('onclick', this.fncHide);
		this._objBalloonContainerDiv.attachEvent('onclick', this.fncClick);
	
		// get the left and right space around the anchor object
		m_intTargetSpaceRight = m_objElementPosition.fncGetRightSpace(this.objAnchor);
		m_intTargetSpaceLeft = m_objElementPosition.fncGetLeftSpace(this.objAnchor);
		
		// figure out the orientation of the balloon relative the target and set the x and y cardinal directions
		if (!m_arrPointerPath[this.strBalloonOrientation])
			this.strBalloonOrientation = (m_objElementPosition.fncGetTopSpace(this.objAnchor) >= m_objElementPosition.fncGetBottomSpace(this.objAnchor) ? 'N' : 'S') + (m_objElementPosition.fncGetLeftSpaceFromCenter(this.objAnchor) >= m_objElementPosition.fncGetRightSpaceFromCenter(this.objAnchor) ? 'W' : 'E');
	
		m_strYAxis = this.strBalloonOrientation.charAt(0);
		m_strXAxis = this.strBalloonOrientation.charAt(1);
		
		// set the correct path for the pointer
		this._objPointerVMLObject.path = m_arrPointerPath[m_strYAxis + m_strXAxis];
		this._objPointerVMLObject.coordorigin = m_strYAxis == 'S' ? '0 14' : '0 11' ;
	
		// insert the balloon container into the DOM near its anchor object
		this.objAnchor.insertAdjacentElement('afterEnd', this._objBalloonContainerDiv);
		
		// adjust the height incase the contents of teh balloon are a bit too big
		this._objContentDiv.style.height = this._objBalloonVMLObject.clientHeight > this.intMaxHeight ? this.intMaxHeight : this._objContentDiv.style.height;
		
		// postion the pointer in the correct position relative to the balloon
		this._objBalloonVMLObject.style.top = m_strYAxis == 'S' ? this._objPointerVMLObject.clientHeight - 5 : 0;
		this._objPointerVMLObject.style.top = m_strYAxis == 'S' ? - this._objBalloonVMLObject.clientHeight + 2 : -4;		
	
		this._objPointerVMLObject.style.marginBottom = m_strYAxis == 'S' ? 0 : -5;
		this._objPointerVMLObject.style.marginTop = m_strYAxis == 'S' ? -5 : 0;
		this._objBalloonContainerDiv.style.top = m_objElementPosition.fncGetTopSpace(this.objAnchor) + (m_strYAxis == 'S' ?  this.objAnchor.offsetHeight : - this._objBalloonContainerDiv.clientHeight);
		
		if (m_strXAxis == 'E')
			this._objBalloonContainerDiv.style.left =  m_objElementPosition.fncGetLeftSpaceFromCenter(this.objAnchor) - ((this._objBalloonVMLObject.clientWidth - this._objPointerVMLObject.clientWidth/2) * m_lngBalloonSlidePercent) ;
		
		if (m_strXAxis == 'W')
			this._objBalloonContainerDiv.style.left =  m_objElementPosition.fncGetLeftSpaceFromCenter(this.objAnchor) - this._objBalloonVMLObject.clientWidth + (this._objPointerVMLObject.clientWidth/2) + (this.objAnchor.clientWidth/2) * m_lngBalloonSlidePercent;
		
		m_intPointerOffset = (this.objAnchor.offsetWidth/2) - (m_strXAxis == 'E' ? 4 : (this._objPointerVMLObject.clientWidth - 4));
		
		// right clip
		if ((m_objElementPosition.fncGetLeftSpace(this._objBalloonContainerDiv) + this._objBalloonContainerDiv.clientWidth) - (this.objAnchor.clientWidth + m_objElementPosition.fncGetLeftSpace(this.objAnchor))  > m_intTargetSpaceRight)
			this._objBalloonContainerDiv.style.left = m_objElementPosition.fncGetLeftSpace(this.objAnchor) + this.objAnchor.clientWidth + m_intTargetSpaceRight - this._objBalloonContainerDiv.clientWidth;
		
		// left clip		
		if (m_intTargetSpaceLeft <=0)
			this._objBalloonContainerDiv.style.left = 0;
	
		this._objPointerVMLObject.style.left = m_intPointerOffset + m_objElementPosition.fncGetLeftClip(this._objBalloonContainerDiv, this.objAnchor);
		this._objIFrame.style.height = this._objBalloonVMLObject.clientHeight;
		this._objIFrame.style.width = this._objBalloonVMLObject.clientWidth;
		this._objIFrame.style.zIndex = -1; // make sure that the iframe is setting below any object with in balloon object
			
	
		// finally display the balloon
		this._objBalloonContainerDiv.style.visibility = 'visible';
		
		try {		
			this._objBalloonContainerDiv.focus();
		} catch (e){}
			
	}
	
	g_fncBalloon.prototype._fncReorderIndex = function (){
		// reallign the zIndex
		var m_objElementPosition = this._fncGetPositioningFunctions();
		this._objBalloonContainerDiv.style.zIndex = m_objElementPosition.fncGetMaxZindex() + 1;
		
	}
	
	g_fncBalloon.prototype._fncHandleHide = function (){
		clearTimeout(this._intTimeoutID);
		this._objBalloonContainerDiv.style.visibility = 'hidden';
	}
	
	g_fncBalloon.prototype._fncDetachBalloonEvents = function (){
		this._objButtonSpan.detachEvent('onclick', this.fncHide);
		this._objBalloonContainerDiv.detachEvent('onclick', this.fncClick);
	}
	
	g_fncBalloon.prototype._fncSetTimeout = function(n_intTimeout){
		var m_intAutoHideInterval;
		var m_blnAutoHide;
		
		clearTimeout(this._intTimeoutID);
		
		m_intAutoHideInterval = (typeof(n_intTimeout) == 'number' && n_intTimeout > 0) ? n_intTimeout : 0;
		m_blnAutoHide = m_intAutoHideInterval > 0;
		
		if (m_blnAutoHide && !isNaN(m_intAutoHideInterval))
			this._intTimeoutID = window.setTimeout(this.fncHide, m_intAutoHideInterval * 1000);
	}
	
	g_fncBalloon.prototype._fncGetPositioningFunctions = function(){
		var m_objElementPosition = {
			fncGetRightSpace : function (objElement) {return objElement.offsetParent.scrollWidth - (objElement.clientWidth + objElement.offsetLeft);},
			fncGetRightSpaceFromCenter : function (objElement) {return objElement.offsetParent.scrollWidth - ((objElement.clientWidth/2) + objElement.offsetLeft);},
			fncGetLeftSpace : function (objElement) {return objElement.offsetLeft;},
			fncGetLeftSpaceFromCenter : function (objElement) {return objElement.offsetLeft + objElement.clientWidth/2;},
			fncGetTopSpace : function (objElement) {return objElement.offsetTop;},
			fncGetBottomSpace : function (objElement) {return objElement.offsetParent.offsetHeight - ((objElement.offsetHeight/2) + objElement.offsetTop);},
			fncGetLeftClip : function (objTopElement, objBottomElement) {return this.fncGetLeftSpace(objBottomElement) - this.fncGetLeftSpace(objTopElement);},
			fncGetMaxZindex : function (){return this.intMaxBalloonZindex++;}
		}
		
		return m_objElementPosition;
	}
	
	g_fncBalloon.prototype._fncClearDisplayArea = function (){
		this._objContentDiv.innerHTML = '';
		if (this.objInnerObject)
			this.objInnerObject.removeNode(true);
	}
		
	// --- Balloon --- //
function g_fncPageDisplayHandler(){
		this.arrMenuItemElements = new Array('div', 'span');
		this.arrScrollContainers = [];
		
		this.intRightNavWidth = 320;
		this.intMaxBalloonZindex = 9000;
		this.blnRighNavVisible = false;
		
	}
