/* =================================================================================================
* NiceTitles
* 21st January 2004
* http://neo.dzygn.com/code/nicetitles
*
* NiceTitles turns your boring (X)HTML tags into a dynamic experience
*
* Copyright (c) 2003 - 2004 Stuart Langridge, Paul McLanahan, Peter Janes, Brad Choate, Dunstan Orchard, Ethan Marcotte, Mark Wubben
*
* Licensed under MIT - http://www.opensource.org/licenses/mit-license.php
==================================================================================================*/

function NiceTitles(nDelay) {
	var oTimer;
	var oTimeoutTimer;
	var isActive = false;
	var sNameSpaceURI = "http://www.w3.org/1999/xhtml";
	
	var oContainer = document.getElementById("nicetitlecontainer");
	if (!oContainer) {
		oContainer = document.createElementNS ? document.createElementNS(sNameSpaceURI, "div") : document.createElement("div");
		oContainer.setAttribute("id", "nicetitlecontainer");
		oContainer.style.display = "none";
		document.getElementsByTagName("body").item(0).appendChild(oContainer);
	}
	
	this.addElements = function addElements(collNodes, sAttribute) {
		var currentNode, sTitle;
		
		for(var i = 0; i < collNodes.length; i++) {
			currentNode = collNodes[i];
		
			sTitle = currentNode.getAttribute(sAttribute);
			if (sTitle) {
				currentNode.setAttribute("nicetitle", sTitle);
				currentNode.removeAttribute(sAttribute);
				addEvent(currentNode, 'mouseover', show);
				addEvent(currentNode, 'mouseout', hide);
			}
		}

	}
	
	function show(e) {
		if (isActive) { hide(); }

		var oNode = window.event ? window.event.srcElement : e.currentTarget;
		if (!oNode.getAttribute("nicetitle")) { 
			while(oNode.parentNode) {
				oNode = oNode.parentNode; // immediately goes to the parent, thus we can only have element nodes
				if (oNode.getAttribute("nicetitle")) { break; }
			}
		}
		
		addEvent(oContainer, 'mouseover', hide);

		var sOutput = parseTemplate(oNode);
		setContainerContent(sOutput);
		var oPosition = setPosition(e, oNode);

		if (nDelay) {	
			oTimer = setTimeout(function() { oContainer.style.display = "block"; }, nDelay);
		} else {
			oContainer.style.display = "block";
		}
		
		oTimeoutTimer = setTimeout(function() {hide();},(55 * oContainer.innerHTML.length));
		isActive = true;		
		// Let's put this event to a halt before it starts messing things up
		window.event ? window.event.cancelBubble = true : e.stopPropagation();
	}

	function setContainerContent(sOutput) {
		sOutput = sOutput.replace(/&/g, "&amp;");
		if (document.createElementNS && window.DOMParser) {
			var oXMLDoc = (new DOMParser()).parseFromString("<root xmlns=\""+sNameSpaceURI+"\">"+sOutput+"</root>", "text/xml");
			var oOutputNode = document.importNode(oXMLDoc.documentElement, true);
			var oChild = oOutputNode.firstChild;
			var nextChild;
			while(oChild) {
				nextChild = oChild.nextSibling; // One's the child is appended, the nextSibling reference is gone
				oContainer.appendChild(oChild);
				oChild = nextChild;
			}
		} else {
			oContainer.innerHTML = sOutput;
		}
	}
	
	function hide() {
		clearTimeout(oTimer);
		clearTimeout(oTimeoutTimer);
		oContainer.style.display = "none";
		var oChild = oContainer.firstChild;
		var nextChild;

		if (!oChild) { return; }
		while(oChild) {
			nextChild = oChild.nextSibling;
			oContainer.removeChild(oChild);
			oChild =  nextChild;
		}
		isActive = false;
	}
	
	function setPosition(e, oNode) {
		var oViewport = getViewport();
		var commonEventInterface = window.event ? window.event : e;

		oContainer.style.visibility = "hidden";
		oContainer.style.display = "block";
		oContainer.style.left = "0px";
		oContainer.style.top = "0px";
		oContainer.style.width = "auto";
		
		if (oContainer.offsetWidth > 8) {
			var containerSize = { width : oContainer.offsetWidth+14, height : oContainer.offsetHeight+15 };
		} else {
			var oSearch = containerSize.firstChild
			var theWidth = 0;
			var theHeight = 0;
			while (oSearch) {
				if (oSearch.offsetWidth) theWidth += oSearch.offsetWidth;
				if (oSearch.offsetHeight) theHeight += oSearch.offsetHeight;
				oSearch = oSearch.nextSibling;
			}
			var containerSize = { width : theWidth, height : theHeight };
		}
		
		oContainer.style.display = "none";
		oContainer.style.visibility = "visible";

		if (commonEventInterface.offsetX) {
			var element = commonEventInterface;
			var oCoords = {
				left : ((commonEventInterface.clientX - commonEventInterface.offsetX) + oViewport.left), 
				top : ((commonEventInterface.clientY - commonEventInterface.offsetY) + oViewport.top)
			};
		} else {
			var element = commonEventInterface.target;
			var target = commonEventInterface.target;
			if (!target.offsetLeft) return false;
			if (typeof target.offsetLeft == 'undefined') target = target.parentNode;
			
			var oCoords = { left : 0, top : 0 };
			while (target) {
				oCoords.left += target.offsetLeft;
				oCoords.top += target.offsetTop;
				target = target.offsetParent;
			}
		}

		oCoords.right = oCoords.left + oNode.offsetWidth;
		oCoords.bottom = oCoords.top + oNode.offsetHeight;

		oCoords.x = oCoords.right;
		oCoords.y = oCoords.top - containerSize.height;
		
		if ((oCoords.x + containerSize.width) > oViewport.right) { 		
			oCoords.x = oCoords.left - containerSize.width;
		}

		if (oCoords.y < oViewport.top) { 
			oCoords.y = oCoords.bottom;
		}
		
		oContainer.style.left = oCoords.x + "px";
		oContainer.style.top = oCoords.y + "px";

		return true;
	}

	function parseTemplate(oNode) {
		if (!ie) {
			return oNode.getAttribute('nicetitle') + '<span id="nicetitle-right"> </span>' + 
						 '<span id="nicetitle-bottom"><span id="nicetitle-bottom-right"></span></span>';
		} else if (oNode.getAttribute('nicetitle')) {
			return oNode.getAttribute('nicetitle');
		}
	}
	
	// Idea from 13thParallel: http://13thparallel.net/?issue=2002.06&title=viewport
	function getViewport() {
		var width = 0;
		var height = 0;
		var right = 0;
		var bottom = 0;
		var left = 0;
		var top = 0;

		if (document.documentElement && document.documentElement.clientWidth) {
			width = document.documentElement.clientWidth;
			height = document.documentElement.clientHeight;
			left = document.documentElement.scrollLeft;
			top = document.documentElement.scrollTop;
		} else if (document.body && document.body.clientWidth) {
			width = document.body.clientWidth;
			height = document.body.clientHeight;
			left = document.body.scrollLeft;
			top = document.body.scrollTop;
		}

		// we don't use an else if here, since Opera 7 tends to get the height on the documentElement wrong
		if (window.innerWidth) { 
			width = window.innerWidth - 18;
			height = window.innerHeight - 18;
		}
		
		if (window.pageXOffset) {
			left = window.pageXOffset;
			top = window.pageYOffset;
		} else if (window.scrollX) {
			left = window.scrollX;
			top = window.scrollY;
		}
		
		return { width : width, height : height, left : left, top : top, bottom : top + height, right : left + width };		
	}
}

//=====================================================================
// Event Listener
// by Scott Andrew - http://scottandrew.com
// edited by Mark Wubben, <useCapture> is now set to false
//=====================================================================
function addEvent(obj, evType, fn) {
	if (obj.addEventListener) {
		obj.addEventListener(evType, fn, false); 
		return true;
	} else if (obj.attachEvent) {
		var r = obj.attachEvent('on'+evType, fn);
		return r;
	} else {
		return false;
	}
}

NiceTitles.autoCreation = function() {
	var timeoutTime1 = 1000;
	
	NiceTitles.autoCreated = new Object();
	
	NiceTitles.autoCreated.img = new NiceTitles(timeoutTime1);
	NiceTitles.autoCreated.alnk = new NiceTitles(timeoutTime1);
	NiceTitles.autoCreated.div = new NiceTitles(timeoutTime1);
	NiceTitles.autoCreated.span = new NiceTitles(timeoutTime1);
	NiceTitles.autoCreated.input = new NiceTitles(timeoutTime1);
	NiceTitles.autoCreated.select = new NiceTitles(timeoutTime1);
	NiceTitles.autoCreated.li = new NiceTitles(timeoutTime1);
	NiceTitles.autoCreated.td = new NiceTitles(timeoutTime1);
		
	NiceTitles.autoCreated.img.addElements(document.getElementsByTagName("img"), "title");
	NiceTitles.autoCreated.alnk.addElements(document.getElementsByTagName("a"), "title");
	NiceTitles.autoCreated.div.addElements(document.getElementsByTagName("div"), "title");
	NiceTitles.autoCreated.span.addElements(document.getElementsByTagName("span"), "title");	
	NiceTitles.autoCreated.input.addElements(document.getElementsByTagName("input"), "title");		
	NiceTitles.autoCreated.select.addElements(document.getElementsByTagName("select"), "title");
	NiceTitles.autoCreated.li.addElements(document.getElementsByTagName("li"), "title");		
	NiceTitles.autoCreated.td.addElements(document.getElementsByTagName("td"), "title");		
}

var agt = navigator.userAgent.toLowerCase();
var ie    = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));

if (document.getElementsByTagName && !ie) { addEvent(window, "load", NiceTitles.autoCreation); }


