/*-------------------------------------------------------------
Tool tip popup
* Display a div with html info when rolling over a link.
* Information stored in the link itself
* Mouse and Auto positioning modes

Author: Terry Hibbert
-------------------------------------------------------------*/

function ToolTip(sInstanceName) {
	
	//--------------- JavaScript sugar ---------------
		var that = this;
		
		this.sInstanceName = sInstanceName;
		
		//Debug with Firebug Console on FF, else alert
		if (typeof(console) == "undefined") {
			console = {};
			console.log = function(sMessage) {
				alert(sMessage);
			}
		}
	
	//--------------- Default settings ---------------
		
		//Mouse-over to display delay (ms)
		this.delayOver = 500;
		
		//Mouse-over to display delay (ms)
		this.delayOut = 1000;
		
		//--- PopUp positioning mode ---//
		// "mouse" or "auto"
		this.positionMode = "mouse";
		
		//Container margin
		this.nContainerMargin = 5;
		
		//--- Component element Id ---
		this.sContainerId = sInstanceName + "Container";
		
		//--- Component element Class ---
		this.sInnerClass = "toolTipInner";
		this.SSettingsClass = "settings";
		
	//--------------- Status ---------------
		
		//Is the preview shown
		this.isOpen = false;
		
	//=============== Initialisation ===============
	this.init = function(sLinkClass) {
		
		//Make sLinkClass Public
		if (typeof(sLinkClass) != "undefined") {
			that.sLinkClass = sLinkClass;
		} else {
		 	that.sLinkClass = false;
			
		}
		
		///Event function for roll-over of link
		var linkOver = function(e) {
			//--- Cross browser event code ---
			if (!e) {
				var e = window.event;
			}
			
			if (e.target) {
				var targ = e.target;
			} else if (e.srcElement) {
				targ = e.srcElement;
			}
			
			// Defeat Safari bug
			if (targ.nodeType == 3) {
				targ = targ.parentNode;
			}				
			
			//--- Action code ---
			
			//If the target element has the correct class on it, show the preview element
			if (targ.getAttribute('toolTip') != null && targ.getAttribute('toolTip') != "") {
				
				//If the preview element doesn't exist, create it
				if (typeof(that.eContainer) != "object") {
					
					//Create and add element to DOM
					that.eContainer = that.addElement("", "div", []);
					that.eContainer.id = that.sContainerId;
					
					//Attach blurb and fill
					that.eToolTipInner = that.addElement(that.sContainerId, "div", [["class", that.sInnerClass]]);
					that.eToolTipInner.innerHTML = targ.getAttribute('toolTip');
					
				} else {
					
					//The Popup exists, so clear it, then repopulate it
					that.eToolTipInner.innerHTML = targ.getAttribute('toolTip');
				}
				
				//Position element on page
				that.positionElement(targ, e);
			
				//Set status to open
				this.isOpen = true;
				
			}//End Class check if
			
		}//End linkOver function
		
		
		///Event function for roll-out of link
		var linkOut = function(e) {
			//--- Cross browser event code ---
			if (!e) {
				var e = window.event;
			}
			
			//Define 'targ' as event target object
			if (e.target) {
				var targ = e.target;
			} else if (e.srcElement) {
				targ = e.srcElement;
			}
			
			//Defeat Safari bug
			if (targ.nodeType == 3) {
				targ = targ.parentNode;
			}				
			
			//--- Action code ---
			
			//If the target element has the correct class on it, show the preview element
			if (true) {
				
				//If the preview element doesn't exist, create it
				if (typeof(that.eContainer) != "undefined") {
					that.eContainer.style.display = "none";
				}
				
				//Set status to closed
				this.isOpen = false;
				
			}//End Class check if
			
		}//End linkOut function
		
		
		//Add the link over event listener to the body element
		if (typeof(document.body.addEventListener) != 'undefined') {
			document.body.addEventListener('mouseover',linkOver,false);
		} else {
			document.body.attachEvent('onmouseover',linkOver);
		}
		
		//Add the link out event listener to the body element
		if (typeof(document.body.addEventListener) != 'undefined') {
			document.body.addEventListener('mouseout',linkOut,false);
		} else {
			document.body.attachEvent('onmouseout',linkOut);
		}
		
	}//End this.init
	
	
	//=============== Other functions ===============
	
	////Create and add element to the DOM, return the element object
	  //sParent: parent id or "" = document.body
	  //sType: the element type e.g. "a", "div", "li" etc.
	  //aAttributes: an array containing the element attributes e.g.
	  //			 aAttributes = [ ["id", "header"], ["onclick","alert('hello')"] ];
	this.addElement = function(sParent, sType, aAttributes) {
		
		//Define new element
		var newElement = document.createElement(sType);
		
		//Loop through attribute array
		for (var i=0; i < aAttributes.length; i++) {
			
			//Recognise and attach events
			if (aAttributes[i][0] == "onclick" || 
				aAttributes[i][0] == "onload" ||
				aAttributes[i][0] == "onmouseover") {
				
				if (document.all) {
					
					//Attach event in the IE way
					function makeEventFunc(sEvents) {
						return function() {
							eval(sEvents);
						}
					}
					newElement.attachEvent(aAttributes[i][0], makeEventFunc(aAttributes[i][1]), true);
					
				} else {
					
					//Attach event in the Moz way
					newElement.setAttribute(aAttributes[i][0], aAttributes[i][1]);
				}
			
			//If not event, check if class
			} if (aAttributes[i][0] == "class") {
				
				//Attach class to object
				newElement.className = aAttributes[i][1];
			} else {
				
				//Must be general attribute, set it
				newElement.setAttribute(aAttributes[i][0],aAttributes[i][1]);
			}
			
		}//End attribute list loop
				
		//If a parent element is defined append the new element as it's child
		if (sParent != "") {
			document.getElementById(sParent).appendChild(newElement);
		} else {
			
			//Otherwise, append as child of the body element
			document.body.appendChild(newElement);
		}
		
		return newElement;
		
	}//End this.addElement
	
	
	////Get element position
	this.getPosition = function(eElement) {
		
		//Extract element positions
		var curleft = curtop = 0;
		if (eElement.offsetParent) {
			curleft = eElement.offsetLeft;
			curtop = eElement.offsetTop;
			while (eElement = eElement.offsetParent) {
				curleft += eElement.offsetLeft;
				curtop += eElement.offsetTop;
			}
		}
		
		//Return array pair of [<left pixels>, <top pixels>]
		return [curleft,curtop];
	}//End getPosition
	
	
	this.positionElement = function(eTarget, e) {
		
		var nLeft = 0;
		var nTop = 0;
		
		switch (this.positionMode) {
			//-------------------------------------------------------------------------------
			case "auto":
				//Get the target element position
				var aPosition = that.getPosition(eTarget);
		
				//Place preview object horizontally on right unless off screen
				if (aPosition[0] + that.eContainer.offsetWidth < document.body.offsetWidth) {
					
					nLeft = aPosition[0];
				} else {
					
					//link too far left
					if (aPosition[0] + eTarget.offsetWidth < document.body.offsetWidth) {
						nLeft = aPosition[0] + eTarget.offsetWidth - that.eContainer.offsetWidth;
						
					} else {
						nLeft = document.body.offsetWidth - that.eContainer.offsetWidth;
					}
				}
				
				//Place preview object on top unless off screen
				if (aPosition[1] - that.eContainer.offsetHeight > 0) {
					 nLeft = aPosition[1] - that.eContainer.offsetHeight;
				} else {
					nTop = aPosition[1] + eTarget.offsetHeight + that.nContainerMargin;
				}
			break;
			
			//-------------------------------------------------------------------------------
			case "mouse":
				var nLeft = 0;
				var nTop = 0;
				
				if (!e) {
					var e = window.event;
				}
				
				if (e.pageX || e.pageY) 	{
					nLeft = e.pageX;
					nTop = e.pageY;
				}
				
				else if (e.clientX || e.clientY) 	{
					nLeft = e.clientX + document.body.scrollLeft
						+ document.documentElement.scrollLeft;
					nTop = e.clientY + document.body.scrollTop
						+ document.documentElement.scrollTop;
				}
				
				// Offset the postion from the mouse
				nLeft += that.nContainerMargin;
				nTop += that.nContainerMargin;
				
			break;
		}
		
		//Position the toolTip element
		that.eContainer.style.left = nLeft + "px";
		that.eContainer.style.top = nTop + "px";
		
		//Reveal container div
		that.eContainer.style.display = "block";
		
	}//End this.positionElement function
	
		
} //End LinkPreview