﻿// based on http://www.siff.net/_inc/js/tooltip.js
//TODO: 
//		add fade/appear effects
var Tooltip = Class.create({
	initialize: function (sTiplayerId, rxClassName, sXmlUrl, hOptions) {	
		this._tipId = sTiplayerId;
		this._rxClassName = rxClassName; 
		this._sXmlUrl = sXmlUrl;
		this.options = Object.extend({
			xOffset: 0,
			yOffset: 0,
			minMargin: 10,
			bUseEffects: false //TODO: fix effects; not working (ie7 freaks on inline opacity)
		}, hOptions || {});

		this._cache = new Array();
		this._elem_tip = this._createToolTipBox();
		this._int_tip_id = false;
		this._last_tip = false;
		this._target = false;
		this._in_target = false;
		this._timeoutId = null;

		this._oLnks = $$('.tooltip');
		for (var i=0; i<this._oLnks.length; i++) {
			Event.observe(this._oLnks[i], 'mouseover', this._handleEvents.bindAsEventListener(this));
			Event.observe(this._oLnks[i], 'mouseout', this._handleEvents.bindAsEventListener(this));
		}
	},
	
	_createToolTipBox: function() {
		if(this._tipId) {	
			var tip_elem = $(this._tipId) ? $(this._tipId) : false;
			
			if(!tip_elem) {
				//tip elem not found so add to body
				var tool_tip_layer = new Element('div');
				if(this.options.bUseEffects){tool_tip_layer.writeAttribute('style', 'display:none; opacity: 0; filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);');}
				tool_tip_layer.id = this._tipId;
				tool_tip_layer.observe('mouseout', this.hideTip.bindAsEventListener(this));
				tool_tip_layer.observe('mouseover', this.showTip.bindAsEventListener(this));
				
				tip_elem = document.body.insertBefore( tool_tip_layer, document.body.firstChild );
			}
			return tip_elem;
		}
		return false;
	},
	
	_handleEvents: function(event) {
		this._target = Event.element(event);
		this._int_tip_id = this.getCurrentTipId();
		
		if(event.type=='mouseover') {
			this._in_target = true;
			this.getTipContent();
		} else if(event.type=='mousemove' && this._in_target && this._cache[this._int_tip_id]!='') {
			this.positionBox();
		} else if(event.type=='mouseout') {
			this._in_target = false;
			//Element.hide(this._elem_tip);
			this.hideTip();
		}
	},
	showTip: function(){
		clearTimeout(this._timeoutId);
		this._elem_tip.show();
		/*
		if(!(this._elem_tip.visible())){
			this._timeoutId = setTimeout(
				function(){
					this._elem_tip.show();
					//this._elem_tip.appear({duration:0.2});
				}.bind(this)
				, 100
			);
		}
		*/
		//Element.show(this._elem_tip);
	},
	hideTip: function(){
		if(!(this._elem_tip.visible())){
			clearTimeout(this._timeoutId);
      }
      else{
			this._timeoutId = setTimeout(
				function(){
					this._elem_tip.hide();
					//this._elem_tip.fade({duration:0.5});
				}.bind(this)
				, 500
			);
      }
		//Element.hide(this._elem_tip);
	},
	getTipContent: function() {
		if(!this._cache[this._int_tip_id]) {
			//var pars = 'perfno='+this._int_tip_id;
			var pars = $H(this._target.href.toQueryParams()); // pass extra params from href to tooltip page
			pars.set('perfno', this._int_tip_id);
			
			var request_url = this._sXmlUrl;
			
			new Ajax.Request( request_url,{
				method: 'get',
				parameters: pars,
				onComplete:this._cacheData.bind(this)
			});
		} else { // use data cache
			this._last_tip = this._int_tip_id;
			Element.update(this._elem_tip, this._cache[this._int_tip_id]);
			this.positionBox();
		}
	},
	_cacheData: function (originalRequest) {
		//save response
		var form = originalRequest.responseXML.getElementsByTagName('form')[0];
		var perfno = parseInt(originalRequest.responseXML.getElementsByTagName('perfno')[0].firstChild.nodeValue);
		
		for (var i=0; i<form.childNodes.length; i++) {
			var node = form.childNodes[i];
			if (node.nodeType == 4) {
				//this._cache[this._int_tip_id] = node.nodeValue;
				this._cache[perfno] = node.nodeValue;
				if(this._int_tip_id == perfno){
					Element.update(this._elem_tip, node.nodeValue);
				}
				break;
			}
		}
		this._last_tip = this._int_tip_id;
		this.positionBox();
		
	},
	positionBox: function() {
		var tipLeft, tipTop;
		var elTrigger = this._target;
		var elTip = this._elem_tip;
		
		//get various dimensions and positions
		var trigOffset = elTrigger.cumulativeOffset();
		var trigDim = elTrigger.getDimensions();
		var trigVpOffset = elTrigger.viewportOffset();
		var tipDim = elTip.getDimensions();
		var viewportDim = document.viewport.getDimensions();
		var viewportOffset = document.viewport.getScrollOffsets();

		// South positioning
		tipLeft = (trigOffset.left + this.options.xOffset) - Math.ceil(tipDim.width/2 - trigDim.width/2);
		if(tipLeft < (this.options.minMargin + this.options.xOffset)){ // too far to the left;
			tipLeft = this.options.minMargin + this.options.xOffset;
		}
		if((tipLeft + tipDim.width + this.options.minMargin) > viewportDim.width){ // too far to the right
			tipLeft = viewportDim.width - (tipDim.width + this.options.minMargin);
		}
		// get arrows and set their left position
		var elArrowUp = elTip.down('div.tooltip_arrowup');
		var elArrowDown = elTip.down('div.tooltip_arrowdown');
		var useUpArrow = true;
		var arrowLeft = (trigOffset.left) - tipLeft;
		
		tipTop = (trigOffset.top + this.options.yOffset + trigDim.height);
		if((tipTop + this.options.minMargin + tipDim.height) > (viewportDim.height + viewportOffset.top)){ // too far below
			// switching to north orientation; use down arrow
			tipTop = ((trigOffset.top - this.options.yOffset) - tipDim.height);
			useUpArrow = false;
		}
		
		if(useUpArrow){
			elArrowUp.setStyle({display: 'block', left: arrowLeft+'px'});
			elArrowDown.setStyle({display: 'none'});
		}
		else{
			elArrowDown.setStyle({display: 'block', left: arrowLeft+'px'});
			elArrowUp.setStyle({display: 'none'});
		}

		elTip.setStyle({left: tipLeft+'px', top: tipTop+'px'});
		
		this.showTip();
		
		return {left: tipLeft, top: tipTop};
	},
	
	getCurrentTipId: function() {
		// specific to implementation: using perfno attribute of triggering link.
		return this._target.readAttribute('perfno');
	}
});
/*
document.observe("dom:loaded", function(){
	// detail Tooltip
	Tooltip = new Tooltip('tooltip', new RegExp(/tip_(\d*)/), '/calendar/performanceToolTip.aspx', {xOffset: 0, yOffset: 0, minMargin: 10,	bUseEffects: false});
});
*/