/*
	TooltipBalloon object to display and control a tooltip balloon.
	v. 1.0.2.0, 10.02.2007
*/

function TooltipBalloon(el){
	var balloon=this;
	if(typeof el == 'string') el=document.getElementById(el);
	el.style.display='none';
	el.style.position='absolute';
	balloon.imagesFolder='images';
	balloon.isShowing=false;
/*
	balloon.activeBorderWidth is the width of the side images (borders and shadows)
	that is taken into account when calculating if mouse is over the balloon. This
	parameter is used to calculate balloon._activeArea
*/
	balloon.activeBorderWidth=15;
/*
	balloon._activeArea is the space on the page where mouse will be considered within
	the balloon. If mouse goes out of this area the balloon will try to close.
*/
	balloon._activeArea={top:0, left:0, width:0, height:0};
/*	
	balloon.el is a reference to the TABLE element
*/
	balloon.el=el;
/*	
	balloon.thumbHostSpot holds coordinates of the hotspot 
	in the up version of the left thumb bitmap
*/
	balloon.thumbHostSpot={dx:15, dy:17};
	balloon.leftThumb=el.rows[1].cells[0].getElementsByTagName('DIV').item(0);
	balloon.rightThumb=el.rows[1].cells[2].getElementsByTagName('DIV').item(0);
	balloon.activeThumb=null;
/*	
	balloon.bodyEl is a reference to the center TD element
	which is intended to hold tooltip content
*/
	balloon.bodyEl=el.rows[1].cells[1];
	balloon.bodyEl.style.backgroundColor='#FFFFFF';
/*	
	balloon.forceResetImages forces balloon.resetImages when balloon.showAtPos is invoked.
	This is necessary when new set of images are loaded but the balloon has not yet been
	made redrawn on the screen. On some browsers balloon.resetImages can not properly determine
	width and height of the images before they have been shown.
*/
	balloon.forceResetImages=true;
	balloon.showAtPos=function(x, y, x2){
		balloon.getBrowserWindowSize();
		var screenWidth = balloon.getBrowserWindowSize().width, screenHeight = balloon.getBrowserWindowSize().height;
		var scrollX = balloon.getPageScrollValues().scrollX, scrollY = balloon.getPageScrollValues().scrollY;
		balloon.isShowing=true;
		balloon.el.style.display='block'; 	//	This will give elements their offsetWidth/offsetHeight
		if(balloon.forceResetImages){ 
			setTimeout(balloon.resetImages, 10);
//			balloon.forceResetImages=false;
		}
		var left=parseInt(x)-balloon.thumbHostSpot.dx;
		var top=parseInt(y)-balloon.thumbHostSpot.dy-parseInt(balloon.el.rows[0].style.lineHeight);
		if(top<scrollY || screenHeight<balloon.el.offsetHeight)
			top=scrollY;
		else if(top+balloon.el.offsetHeight>scrollY+screenHeight)
			top=scrollY+screenHeight-balloon.el.offsetHeight;
		var thumbPointerY=top+parseInt(balloon.el.rows[0].style.lineHeight)+balloon.thumbHostSpot.dy;
		var dThumbY=0;
		if(thumbPointerY<y){
			dThumbY=y-thumbPointerY;
			var switchThumbDown=false;
			if(dThumbY>balloon.bodyEl.offsetHeight-balloon.leftThumb.offsetHeight){
				dThumbY=balloon.bodyEl.offsetHeight-balloon.leftThumb.offsetHeight;
				thumbPointerY=top+parseInt(balloon.el.rows[0].style.lineHeight)+dThumbY+balloon.leftThumb.offsetHeight-balloon.thumbHostSpot.dy;
				if(thumbPointerY>y)
					dThumbY-=thumbPointerY-y;
				switchThumbDown=true;
			}
		}
		balloon.activeThumb=balloon.leftThumb;
		if(left<scrollX || screenWidth<balloon.el.offsetWidth)
			left=scrollX;
		else if(left+balloon.el.offsetWidth>scrollX+screenWidth){ 
			var left2=parseInt(x2)+balloon.thumbHostSpot.dx-balloon.el.offsetWidth;
			if(left2>scrollX){
				left=left2;
				balloon.activeThumb=balloon.rightThumb;
			}
		}
		var imageToLoadInThumb=(balloon.activeThumb==balloon.leftThumb)?'/thl':'/thr';
		imageToLoadInThumb+=(switchThumbDown)?'d.png':'u.png';
//window.status=imageToLoadInThumb+(new Date());
		balloon.rightThumb.style.visibility=(balloon.activeThumb==balloon.rightThumb)?'visible':'hidden';
		balloon.leftThumb.style.visibility=(balloon.activeThumb==balloon.leftThumb)?'visible':'hidden';
		balloon._loadImageInThumb(balloon.activeThumb, balloon.imagesFolder+imageToLoadInThumb);
		balloon.activeThumb.style.marginTop=dThumbY+'px';
		balloon.el.style.left=left+'px';
		balloon.el.style.top=top+'px';
		balloon._activeArea.left=(balloon.activeThumb==balloon.leftThumb)?left:balloon.getX(balloon.bodyEl)-balloon.activeBorderWidth;
		balloon._activeArea.top=balloon.getY(balloon.bodyEl)-balloon.activeBorderWidth;
		balloon._activeArea.width=balloon.bodyEl.offsetWidth+balloon.activeThumb.offsetWidth+balloon.activeBorderWidth;
		balloon._activeArea.height=balloon.bodyEl.offsetHeight+2*balloon.activeBorderWidth;
	};
	balloon.hideTimer;
	balloon.hide=function(delayHide){
		clearTimeout(balloon.hideTimer);
		clearTimeout(balloon.showTimer);
		if(delayHide)
			balloon.hideTimer = setTimeout(balloon.hide, 250);
		else if(!balloon.mouseIsOver){
			balloon.XMLHttpRequestObject.abort();
			balloon.el.style.display='none';
			balloon.isShowing=false;
			balloon.lastTrigger=null;		
		}
	};
	balloon.mouseIsOver=false;
	balloon.showTimer;
	balloon.showDelay=750;
	balloon.show=function(delayShow){
		clearTimeout(balloon.showTimer);
		clearTimeout(balloon.hideTimer);
		if(delayShow){
			balloon.showTimer = setTimeout(balloon.show, balloon.showDelay);
		}else if(balloon.mouseIsOver){
			if(balloon.onContentNeeded)	balloon.onContentNeeded(balloon.lastTrigger);
			if(typeof(balloon.contentUrl)=='string')
				balloon.loadContent(balloon.contentUrl, true);
			else
				balloon.showAtPos(balloon.showPosition.x, balloon.showPosition.y, balloon.showPosition.x2);
		}
	};
/*	
	balloon.mouseMove is executed when mouse moves over a trigger
*/
	balloon.mouseMove=function(evt){
		var trigger=evt.srcElement?evt.srcElement:evt.target;
		while(trigger && !trigger._isTooltipTriggerObject){
			trigger=trigger.parentNode;
		}
		balloon.mouseIsOver=false;
		if(!trigger)
			balloon.hide(true);
		else if(trigger!=balloon.lastTrigger){
			balloon.hide();
			balloon.lastTrigger=trigger;		
			balloon.showPosition={x:balloon.getX(trigger)+trigger.offsetWidth-5, y:balloon.getY(trigger)+3, x2:balloon.getX(trigger)+5};
			balloon.show(true);
		}else
			balloon.mouseIsOver=true;
	}
/*	
	balloon.mouseMove is executed when mouse leaves a trigger
*/
	balloon.mouseOut=function(evt){
		balloon.mouseIsOver=false;
		balloon.hide(true);
	}
/*	
	balloon.mouseMove is executed when mouse moves over the balloon.el element
*/
	balloon._elMouseMove=function(evt){
		var evtX=(evt.pageX)?evt.pageX:evt.clientX + balloon.getPageScrollValues().scrollX;
		var evtY=(evt.pageY)?evt.pageY:evt.clientY + balloon.getPageScrollValues().scrollY;
		if( balloon._activeArea.left>evtX || balloon._activeArea.left+balloon._activeArea.width<evtX || balloon._activeArea.top>evtY || balloon._activeArea.top+balloon._activeArea.height<evtY ){
			if(balloon.mouseIsOver){
				balloon.mouseIsOver=false;
				balloon.hide(true);
			}
		}else{
			balloon.mouseIsOver=true;
			clearTimeout(balloon.hideTimer);
		}
	}
/*	
	balloon.mouseMove is executed when mouse leaves the balloon.el element
*/
	balloon._elMouseOut=function(evt){
		balloon.mouseIsOver=false;
		balloon.hide(true);
	}
/*	
	balloon.XMLHttpRequestObjectReadyStateHandler
*/
	balloon.XMLHttpRequestObjectReadyStateHandler=function(){
		try{
			if(balloon.XMLHttpRequestObject.readyState == 4 && balloon.XMLHttpRequestObject.status == 200){
				balloon.bodyEl.innerHTML=balloon.XMLHttpRequestObject.responseText;
				balloon.showAtPos(balloon.showPosition.x, balloon.showPosition.y, balloon.showPosition.x2);
			}
		}catch(e){}
	}
/*	
	balloon.XMLHttpRequestObject
*/
	balloon.XMLHttpRequestObject=null;
	if (window.XMLHttpRequest) { // Mozilla, Safari,... 
	   balloon.XMLHttpRequestObject = new XMLHttpRequest(); 
	} else if (window.ActiveXObject) { // IE 
	   try { 
		   balloon.XMLHttpRequestObject = new ActiveXObject("Msxml2.XMLHTTP"); 
	   } catch (e) { 
		   try { 
			   balloon.XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP"); 
		   } catch (e) {} 
	   } 
	} 
/*	
	balloon.contentUrl 
*/
	balloon.contentUrl=null;
	balloon.displayLoadingIndication=true;
/*	
	balloon.loadContent 
*/
	balloon.loadContent=function(url, nocache){
		if(balloon.displayLoadingIndication){
			balloon.el.style.display='block';
			var tmpImg=document.createElement('IMG');
			tmpImg.src=balloon.imagesFolder+'/Loading...gif';
			var size={w:balloon.bodyEl.offsetWidth, h:balloon.bodyEl.offsetHeight};
			for(var i=0; i<balloon.bodyEl.childNodes.length; ++i)
				balloon.bodyEl.removeChild(balloon.bodyEl.childNodes.item(i));
			balloon.bodyEl.appendChild(tmpImg);
			tmpImg.style.margin=parseInt((size.h-tmpImg.offsetHeight)/2)+'px '+parseInt((size.w-tmpImg.offsetWidth)/2)+'px'; 
			balloon.showAtPos(balloon.showPosition.x, balloon.showPosition.y, balloon.showPosition.x2);
		}
		if(nocache){	// avoid request caching 
			var param='';
			if(url.indexOf('?')>-1) param='&';
			else param='?';
			param+=encodeURIComponent((new Date()).getTime());
			var anchInd=url.indexOf('#');
			if(anchInd>-1)
				url=url.substring(0, anchInd)+param+url.substr(anchInd);
			else
				url+=param;
		}
		balloon.XMLHttpRequestObject.open('GET', url, true);
		balloon.XMLHttpRequestObject.onreadystatechange=balloon.XMLHttpRequestObjectReadyStateHandler;
		balloon.XMLHttpRequestObject.send(null);
	}
/*	
	balloon.onContentNeeded event handler is invoked before an AJAX request for data is made
*/
	balloon.onContentNeeded=function(param1){	}

	balloon.setImagesFolder=function(imagesFolder){
		balloon.imagesFolder=(typeof imagesFolder=='string' && imagesFolder!='')?imagesFolder:'.';
		balloon.preloadImages();
		balloon.resetImages();
		balloon.forceResetImages=true;
	}
/*	
	balloon.resetImages sets which bitmaps are used by the balloon
	and calculates necessary elements dimensions
*/
	balloon.resetImages=function(){
		if(window.ActiveXObject){ // broser is IE
			el.rows[0].cells[0].style.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+balloon.imagesFolder+'/tl.png", sizingMethod="image")';
			el.rows[0].cells[1].style.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+balloon.imagesFolder+'/t.png", sizingMethod="scale")';
			el.rows[0].cells[2].style.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+balloon.imagesFolder+'/tr.png", sizingMethod="image")';
			el.rows[1].cells[0].style.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+balloon.imagesFolder+'/l.png", sizingMethod="scale")';
			el.rows[1].cells[2].style.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+balloon.imagesFolder+'/r.png", sizingMethod="scale")';
			el.rows[2].cells[0].style.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+balloon.imagesFolder+'/bl.png", sizingMethod="image")';
			el.rows[2].cells[1].style.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+balloon.imagesFolder+'/b.png", sizingMethod="scale")';
			el.rows[2].cells[2].style.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+balloon.imagesFolder+'/br.png", sizingMethod="image")';
			balloon.leftThumb.style.filter=(balloon.activeThumb==balloon.leftThumb)?balloon.leftThumb.style.filter:'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+balloon.imagesFolder+'/thlu.png", sizingMethod="image")';
			balloon.rightThumb.style.filter=(balloon.activeThumb==balloon.rightThumb)?balloon.rightThumb.style.filter:'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+balloon.imagesFolder+'/thru.png", sizingMethod="image")';
		}else{
			el.rows[0].cells[0].style.background='url('+balloon.imagesFolder+'/tl.png) no-repeat';
			el.rows[0].cells[1].style.background='url('+balloon.imagesFolder+'/t.png) repeat-x';
			el.rows[0].cells[2].style.background='url('+balloon.imagesFolder+'/tr.png) no-repeat';
			el.rows[1].cells[0].style.background='url('+balloon.imagesFolder+'/l.png) repeat-y';
			el.rows[1].cells[2].style.background='url('+balloon.imagesFolder+'/r.png) repeat-y';
			el.rows[2].cells[0].style.background='url('+balloon.imagesFolder+'/bl.png) no-repeat';
			el.rows[2].cells[1].style.background='url('+balloon.imagesFolder+'/b.png) repeat-x';
			el.rows[2].cells[2].style.background='url('+balloon.imagesFolder+'/br.png) no-repeat';
			balloon.leftThumb.style.background=(balloon.activeThumb==balloon.leftThumb)?balloon.leftThumb.style.background:'url('+balloon.imagesFolder+'/thlu.png) no-repeat';
			balloon.rightThumb.style.background=(balloon.activeThumb==balloon.rightThumb)?balloon.rightThumb.style.background:'url('+balloon.imagesFolder+'/thru.png) no-repeat';
		}
		var tmpImg=document.createElement('IMG');
		tmpImg.style.visibility='hidden';
		tmpImg.style.position='absolute';
		tmpImg.style.top='10px';
		tmpImg.style.left='10px';
		document.body.appendChild(tmpImg);
		tmpImg.src=balloon.imagesFolder+'/tl.png';
		el.rows[0].style.lineHeight=tmpImg.offsetHeight+'px';
		el.rows[0].style.height=tmpImg.offsetHeight+'px';
		tmpImg.src=balloon.imagesFolder+'/bl.png';
		el.rows[2].style.lineHeight=tmpImg.offsetHeight+'px';
		el.rows[2].style.height=tmpImg.offsetHeight+'px';
		tmpImg.src=balloon.imagesFolder+'/thlu.png';
		balloon.leftThumb.style.width=tmpImg.offsetWidth+'px';
		balloon.leftThumb.style.height=tmpImg.offsetHeight+'px';
		balloon.rightThumb.style.width=tmpImg.offsetWidth+'px';
		balloon.rightThumb.style.height=tmpImg.offsetHeight+'px';
		document.body.removeChild(tmpImg);
		if(el.rows[0].style.lineHeight=='0px' || el.rows[2].style.lineHeight=='0px'){
			setTimeout(balloon.resetImages, 10);
		}
	}
/*	
	balloon.attachToObject attaches event listeners to the objects
	that will be triggers. Objects may be passed as either id's or
	by direct references. Also they may be passed here as multiple
	parameters or in an array as one parameter
*/
	balloon.attachToObject=function(el){	
		if(arguments.length>1){
			for(var i=0; i<arguments.length; ++i)
				balloon.attachToObject(arguments[i]);
			return;
		}
		if(arguments.length==0)
			el=balloon.getAllElementsByAttribute(document.body, 'xTooltip', 'true');
		if(el instanceof Array){
			for(var i=0; i<el.length; ++i)
				balloon.attachToObject(el[i]);
			return;
		}
		if(typeof el == 'string') el=document.getElementById(el);
		balloon.addListener(el, 'mouseover', balloon.mouseMove);
		balloon.addListener(el, 'mousemove', balloon.mouseMove);
		balloon.addListener(el, 'mouseout', balloon.mouseOut);
		el._isTooltipTriggerObject=true;
	}
	balloon._loadImageInThumb=function(thumb, imgUrl){ 
		if(window.ActiveXObject){ // broser is IE
			thumb.style.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+imgUrl+'", sizingMethod="image")';
		}else{
			thumb.style.background='url('+imgUrl+') no-repeat';
		}
	}
	balloon.preloadedImagesStore={};
	balloon.preloadImages=function(){
		if (document.images){
			balloon.preloadedImagesStore={};
			balloon.preloadedImagesStore.tl=new Image();
			balloon.preloadedImagesStore.tl.src=balloon.imagesFolder+'/tl.png';
			balloon.preloadedImagesStore.t=new Image();
			balloon.preloadedImagesStore.t.src=balloon.imagesFolder+'/t.png';
			balloon.preloadedImagesStore.tr=new Image();
			balloon.preloadedImagesStore.tr.src=balloon.imagesFolder+'/tr.png';
			balloon.preloadedImagesStore.l=new Image();
			balloon.preloadedImagesStore.l.src=balloon.imagesFolder+'/l.png';
			balloon.preloadedImagesStore.r=new Image();
			balloon.preloadedImagesStore.r.src=balloon.imagesFolder+'/r.png';
			balloon.preloadedImagesStore.bl=new Image();
			balloon.preloadedImagesStore.bl.src=balloon.imagesFolder+'/bl.png';
			balloon.preloadedImagesStore.b=new Image();
			balloon.preloadedImagesStore.b.src=balloon.imagesFolder+'/b.png';
			balloon.preloadedImagesStore.br=new Image();
			balloon.preloadedImagesStore.br.src=balloon.imagesFolder+'/br.png';
			balloon.preloadedImagesStore.thlu=new Image();
			balloon.preloadedImagesStore.thlu.src=balloon.imagesFolder+'/thlu.png';
			balloon.preloadedImagesStore.thru=new Image();
			balloon.preloadedImagesStore.thru.src=balloon.imagesFolder+'/thru.png';
		}
	}
	balloon.addListener(balloon.el, 'mouseover', balloon._elMouseMove);
	balloon.addListener(balloon.el, 'mousemove', balloon._elMouseMove);
	balloon.addListener(balloon.el, 'mouseout', balloon._elMouseOut);
	balloon.resetImages();
}
TooltipBalloon.prototype.getPageScrollValues=function(){
	var scrollX = 0, scrollY = 0;
	if( typeof( window.pageYOffset ) == 'number' ) { 
	  //Netscape compliant
		scrollX = window.pageXOffset;
		scrollY = window.pageYOffset;
	} else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
	  //DOM compliant
		scrollX = document.body.scrollLeft;
		scrollY = document.body.scrollTop;
	} else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
	  //IE6 standards compliant mode
		scrollX = document.documentElement.scrollLeft;
		scrollY = document.documentElement.scrollTop;
	}
	return {scrollX:scrollX, scrollY:scrollY};
}
TooltipBalloon.prototype.getBrowserWindowSize=function(){
	var screenWidth = 0, screenHeight = 0;
	if( typeof( window.innerWidth ) == 'number' ) {
		//Non-IE
		screenWidth = window.innerWidth;
		screenHeight = window.innerHeight;
	} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
		//IE 6+ in 'standards compliant mode'
		screenWidth = document.documentElement.clientWidth;
		screenHeight = document.documentElement.clientHeight;
	} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
		//IE 4 compatible
		screenWidth = document.body.clientWidth;
		screenHeight = document.body.clientHeight;
	}
	return {width:screenWidth, height:screenHeight};
}
TooltipBalloon.prototype.getX=function(el){
	if(!el)	return 0;
	if(typeof el == 'string') el=document.getElementById(el);
	if(el.getBoundingClientRect){
		x=el.getBoundingClientRect().left;
		x+=(document.documentElement && document.documentElement.scrollLeft)?document.documentElement.scrollLeft:document.body.scrollLeft;
		x-=2;
	}else{ 
		var x = el.offsetLeft;
		var parent=el.offsetParent;
		while (parent) {
			x += parent.offsetLeft;
			parent = parent.offsetParent;
		}
		parent=el.parentNode;
		while(parent && parent.tagName!='BODY'){
			x -= parent.scrollLeft;
			parent=parent.parentNode;
		}
	}
	return x;
}
TooltipBalloon.prototype.getY=function(el){
	if(!el)	return 0;
	if(typeof el == 'string') el=document.getElementById(el);
	if(el.getBoundingClientRect){
		y=el.getBoundingClientRect().top;
		y+=(document.documentElement && document.documentElement.scrollTop)?document.documentElement.scrollTop:document.body.scrollTop;
		y-=2;
	}else{ 
		var y = el.offsetTop;
		var parent=el.offsetParent;
		while (parent) {
			y += parent.offsetTop;
			parent = parent.offsetParent;
		}
		parent=el.parentNode;
		while(parent && parent.tagName!='BODY'){
			y -= parent.scrollTop;
			parent=parent.parentNode;
		}
	}
	return y;
}
TooltipBalloon.prototype.addListener=function(obj, eventName, func){
	if(window.ActiveXObject){ // broser is IE
		obj.attachEvent('on'+eventName, func);
	}else{
		obj.addEventListener(eventName, func, false);
	}
}
TooltipBalloon.prototype.removeListener=function(obj, eventName, func){
	if(window.ActiveXObject){ // broser is IE
		obj.detachEvent('on'+eventName, func);
	}else{
		obj.removeEventListener(eventName, func, false);
	}
}
TooltipBalloon.prototype.getAllElementsByAttribute=function(obj, attrName, attrValue){
	var elements=new Array();
	if(obj.nodeType==1){
		if(obj.getAttribute(attrName)==attrValue)
			elements.push(obj);
		for(var i=0; i<obj.childNodes.length; ++i)
			if(obj.childNodes.item(i).nodeType==1)
				elements=elements.concat(arguments.callee(obj.childNodes.item(i), attrName, attrValue));
	}
	return elements;
}

