// libnk-tooltips.js
//
// Supplies tool tips for help topics on selected elements at
// http://www.chromaonline.com
//
// This script is a part of libnk; libnk is a personal library of classes
// -- created by me, Nathan Kelly -- that use the prototype.js and
// scriptaculous.js libraries. libnk scripts will not work without these two
// libraries.
//
// SOFTWARE NAME: libnk
// SOFTWARE RELEASE: 1.0
// COPYRIGHT NOTICE: Copyright (c) 2007 Nathan Kelly <info@nathan-kelly.com>
// SOFTWARE LICENSE: GNU General Public License v2.0
// NOTICE: >
// This program is free software; you can redistribute it and/or modify it under
// the terms of version 2.0 of the GNU General Public License as published by
// the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of version 2.0 of the GNU General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// This script will not work without prototype.js or scriptaculous.js
// EACH OF THESE SCRIPTS ARE SUBJECT TO THEIR OWN LICENSE AGREEMENTS.
//

/////////////////////////////// START SCRIPT ///////////////////////////////////

// extend the Element object

Object.extend(Element, {
	setInnerHTML: function(element,content) {
		element = $(element);
		element.innerHTML = content;
	}
});

// global timer
var holdTimer;

var ToolTips = Class.create();
ToolTips.prototype = {
	initialize: function(element) {

// -----------------------------------------------------------------------------
// Here is the HTML output we are going to create for the overlay tooltip.

//<div class="tool-tip-open" style="top: ?px; left: ?px;" id="tool-tip">
//	<div id="tool-tip-content">

//	</div>
//	<div id="tool-tip-footer">
//		<a href="#" class="ui-button ui-button-close" id="close-tool-tip">Close</a>
//	</div>
//</div>

		var objBody = document.getElementsByTagName('body').item(0);
		// Tooltip Box
		var tooltipBox = document.createElement('div');
		tooltipBox.setAttribute('id','tool-tip');
		objBody.appendChild(tooltipBox);

		// Tooltip Wrapper (used to set relative positioning)
		//var tooltipWrapper = document.createElement('div');
		//tooltipWrapper.setAttribute('id','tool-tip-wrapper');
		//tooltipBox.appendChild(tooltipWrapper);

		// Tooltip Content
		var tooltipContent = document.createElement('div');
		tooltipContent.setAttribute('id','tool-tip-content');
		tooltipBox.appendChild(tooltipContent);

		// Tooltip Footer
		var tooltipFooter = document.createElement('div');
		tooltipFooter.setAttribute('id','tool-tip-footer');
		tooltipBox.appendChild(tooltipFooter);

		// Close Button (if tool-tip-stay defined)
		var closeAnchor = document.createElement('a');
		closeAnchor.setAttribute('id','close-tool-tip');
		closeAnchor.className = 'ui-button ui-button-close';
		closeAnchor.setAttribute('href','#');
		tooltipFooter.appendChild(closeAnchor);
		Element.setInnerHTML('close-tool-tip', 'Close');
		closeAnchor.onclick = function() {
			myToolTips.hideToolTip();
			return false;
		}

		// Tooltip Arrow (this is why we need relative positioning)
		var tooltipArrow = document.createElement('span');
		tooltipArrow.setAttribute('id', 'tool-tip-arrow');
		tooltipBox.appendChild(tooltipArrow);

		// Hide the Tooltip by default
		Element.hide('close-tool-tip');
		Element.hide('tool-tip');

		// get all of the elements that have class="has-tool-tip"
		// and append a tool tip button
		var ttParents = document.getElementsByClassName('has-tool-tip');

		for (var l=0; l<ttParents.length; l++) {
			var ttParent = ttParents[l];
			
			var infoToggle = document.createElement('img');
			infoToggle.className = 'ui-tool-tip-toggle';
			infoToggle.setAttribute('src', globalUIElements["GUI_tooltipicon_src"]);
			infoToggle.setAttribute('alt', globalTranslations["GT_tooltiptext"]);
			ttParent.appendChild(infoToggle);
			/*
			var infoToggle = document.createElement('a');
			infoToggle.setAttribute('href', '#');
			infoToggle.className = 'ui-tool-tip-toggle';
			ttParent.appendChild(infoToggle);

			var toggleEm = document.createElement('em');
			infoToggle.appendChild(toggleEm);
			
			var toggleText = document.createTextNode('What is This?');
			toggleEm.appendChild(toggleText);
			*/

		}

		var ttToggles = document.getElementsByClassName('ui-tool-tip-toggle');

		for (var i=0; i<ttToggles.length; i++) {
			var ttToggle = ttToggles[i];
			ttToggle.onclick = function() {return false;}
			this.element = ttToggle;
			// split the toggle parent className to see if there are
			// any tool-tips that need to stay after mouseout
			// these tool-tips might contain links and need a delay
			// so the links can be clicked.
			var a = this.element.parentNode.className.split(" ");
			
			this.eventMouseOver = this.showToolTip.bindAsEventListener(ttToggle);
			// we are looking for 'stay' and a number to set the timer with
			// className format should look like:
			// class="has-tool-tip tool-tip-[identifier] tool-tip-stay-[number]"
			// the timer can be set from the page, you might need it to stay open
			// longer if you have more links etc...
			if (a.length > 2 && a[2].indexOf('stay')) {				
				var b = a[2].split("-");				
				var toolTipTimer = b[3]; // should be = [number]
				this.eventMouseOut = this.holdToolTip.bindAsEventListener(ttToggle, toolTipTimer);
			} else {
				this.eventMouseOut = this.hideToolTip.bindAsEventListener(ttToggle);
			}
			
			this.eventMouseMove = this.moveToolTip.bindAsEventListener(ttToggle);
			this.registerEvents(ttToggle);
		}
		return false;
	},

	destroy: function(event) {
		Event.stopObserving(this.element, "mouseover", this.eventMouseOver);
		Event.stopObserving(this.element, "mouseout", this.eventMouseOut);
		Event.stopObserving(this.element, "mousemove", this.eventMouseMove);
	},

	registerEvents: function() {
		Event.observe(this.element, "mouseover", this.eventMouseOver);
		Event.observe(this.element, "mouseout", this.eventMouseOut);
		Event.observe(this.element, "mousemove", this.eventMouseMove);
	},

	moveToolTip: function(event){
		Event.stop(event);
		// get Mouse position
		var mouse_x = Event.pointerX(event) - 48;
		var mouse_y = Event.pointerY(event);

		// decide if wee need to switch sides for the tooltip
		var dimensions = Element.getDimensions( $('tool-tip') );
		var element_width = dimensions.width;
		var element_height = dimensions.height;

		// track the position so we can place a neat little arrow pointing to the toggle
		var trackPos = new Array();

		if ( (element_width + mouse_x) >= ( myToolTips.getWindowWidth() - 5) ){
			// too big for X
			mouse_x = mouse_x - element_width;
			// make sure that the mouse is not on the tool-tip
			mouse_x = mouse_x + 88;
			trackPos.push('x2');
		} else {
			mouse_x = mouse_x + 5;
			trackPos.push('x1');
		}

		if ( (element_height + mouse_y) >= ( myToolTips.getWindowHeight() - 5) ){
			// too big for Y
			mouse_y = mouse_y - element_height;
			// make sure that the mouse is not on the tool-tip
			mouse_y = mouse_y - 5;
			trackPos.push('y2');
		} else {
			mouse_y = mouse_y + 5;
			trackPos.push('y1');
		}

		var curPos = trackPos[0] += trackPos[1];
		switch (curPos) {
			case 'x1y1':
				$('tool-tip').className = 'ttp-tl';
				break;
			case 'x2y1':
				$('tool-tip').className = 'ttp-tr';
				break;
			case 'x1y2':
				$('tool-tip').className = 'ttp-bl';
				break;
			case 'x2y2':
				$('tool-tip').className = 'ttp-br';
				break;
			default:
				$('tool-tip').classname = '';
		}
		// clear the trackPos array
		trackPos = '';

		// now set the right styles
		myToolTips.setPosition(mouse_x, mouse_y);
	},

	showToolTip: function(event) {
		Event.stop(event);
		// find out which tool tip we want to show
		// get the className from the toggle parent element and grab the reference to
		// the tool tip ID, e.g. class="has-tool-tip tool-tip-[identifier]" we need the
		// tool-tip-[identifier] reference only
		var c = this.parentNode.className.split(" ");
		var whichToggle = c[1];
		// the tooltip to show will have the ID of tool-tip-[identifier]
		var whichToolTip = $(whichToggle);
		
		if (c.length > 2 && c[2].indexOf('stay')) {
			Element.show('close-tool-tip');
			$('tool-tip-footer').className = 'button-visible';
		}

		// get the content div ready
		var toolTipContentDiv = $('tool-tip-content');
		// make sure there is only ever one child inside content
		// this is to work around an issue where the hold tool tip is
		// still open while mousing over another tool tip, this clears
		// the content and resets the tool-tip
		if (toolTipContentDiv.childNodes.length > 0) {
			clearTimeout(holdTimer);
			var oldToolTipContent = toolTipContentDiv.firstChild;
			toolTipContentDiv.removeChild(oldToolTipContent);
			if ($('tool-tip-footer').className == 'button-visible') {
				Element.hide('close-tool-tip');
				$('tool-tip-footer').className = '';
			}
		}
		
		var toolTipContent = whichToolTip.cloneNode(true);
		toolTipContentDiv.appendChild(toolTipContent);		
		
		// before we display the tooltip we will need to hide any select elements
		myToolTips.hideSelectBoxes();
		myToolTips.moveToolTip(event);
		// IE doesn't get the fancy stuff because it just makes it look bad
		if (navigator.appVersion.indexOf('MSIE')>0) {
			new Element.show('tool-tip');	
		} else {
			new Effect.Appear('tool-tip', {
				from: 0.0,
				to: 1.0,
				duration: 0.2,
				afterFinish: function() {
					new Element.show('tool-tip');
				}
			});
		}
		return false;				
	},

	holdToolTip: function(event, toolTipTimer) {		
		holdTimer = setTimeout( function() {
			myToolTips.hideToolTip();
		}, toolTipTimer * 1000);
		return false;
	},

	hideToolTip: function(event) {
		clearTimeout(holdTimer);
		// I should split this into a cleanup function but not right now
		// IE doesn't get the fancy stuff because it just makes it look bad
		if (navigator.appVersion.indexOf('MSIE')>0) {
			Element.hide('tool-tip');
			Element.hide('close-tool-tip');
			$('tool-tip').classname = '';
			$('tool-tip-footer').className = '';
			var toolTipContentDiv = $('tool-tip-content');
			var toolTipContent = toolTipContentDiv.firstChild;
			// check for not null to avoid an error
			if (toolTipContentDiv.childNodes.length > 0) {
				toolTipContentDiv.removeChild(toolTipContent);
			}
			myToolTips.showSelectBoxes();
		} else {
			new Effect.Fade( 'tool-tip', {
				from: 1.0,
				to: 0.0,
				duration: 0.2,
				afterFinish: function() {
					Element.hide('tool-tip');
					Element.hide('close-tool-tip');
					$('tool-tip').classname = '';
					$('tool-tip-footer').className = '';
					var toolTipContentDiv = $('tool-tip-content');
					var toolTipContent = toolTipContentDiv.firstChild;
					// check for not null to avoid an error
					if (toolTipContentDiv.childNodes.length > 0) {
						toolTipContentDiv.removeChild(toolTipContent);
					}
					myToolTips.showSelectBoxes();
				}
			});
		}
		return false;
	},

	setPosition: function(x, y){
		// set the right styles to position the tool tip
		Element.setStyle($('tool-tip'), {
				top:y + "px",
				left:x + "px"
		});
	},

	getWindowHeight: function(){
		var innerHeight;
		if (navigator.appVersion.indexOf('MSIE')>0) {
			innerHeight = document.body.clientHeight;
		} else {
			innerHeight = window.innerHeight;
		}
		return innerHeight;
	},

	getWindowWidth: function(){
		var innerWidth;
		if (navigator.appVersion.indexOf('MSIE')>0) {
			innerWidth = document.body.clientWidth;
		} else {
			innerWidth = window.innerWidth;
		}
		return innerWidth;
	},

	showSelectBoxes: function(){
		if (navigator.appVersion.indexOf("MSIE")!= -1) {
			selects = document.getElementsByTagName("select");
			for (var i = 0; i != selects.length; i++) {
				selects[i].style.visibility = "visible";
			}
		}
	},

	hideSelectBoxes: function(){
		if (navigator.appVersion.indexOf("MSIE")!= -1) {
			selects = document.getElementsByTagName("select");
			for (var i = 0; i != selects.length; i++) {
				selects[i].style.visibility = "hidden";
			}
		}
	}
};

function initToolTips(){if(!document.getElementById('container')) return; myToolTips=new ToolTips();};
Event.observe(window, 'load', initToolTips);
Event.observe(window,'unload', Event.unloadCache);

