/******************************************************************************
Files:			dom-tooltips.js, dom-tooltips.css
Version:		1.4
Author:			John Ha
Author URI:		http://ink.bur.st
Description:	Add tooltips to any web page without modifying any code, as
				long as there are already title atributes used in the page.
				An implementation of tooltips using DOM. The script will search
				the document for all title attributes and automaticaly assign
				the title text to a toolip for that element.
				The element to attach a tooltip to can also be defined when
				calling this class.
*******************************************************************************
						Copyright (c) 2005, 2006 John Ha
*******************************************************************************
This work is licensed under the Creative Commons Attribution License. To view
a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/2.5/
*******************************************************************************
If this code has helped you in anyway, any acknowledgement would be appreciated
*******************************************************************************
*/
tooltip = {
	name: 'dom-tooltips',
	offsetX: 15,
	offsetY: 20,
	maxWidth: 250,
	enabled: false,
	tip: null,
	ie: document.all,
	ns6: document.getElementById && !document.all,
	opr: window.opera,

	init: function (tags) {
		if (!document.getElementById) return;

		typeof tags == 'undefined' ? tags = new Array('a', 'acronym') : 0; // default elements (* for all)

		with (this) {
			if (!document.getElementById(name)) {
				tip = document.createElement ('div');
				tip.id = name;
				// CSS Validator won't see these invalid proprietary rules
				tip.style.cssText = 'filter:alpha(opacity=85);-moz-opacity:.85;-khtml-opacity:.85;opacity:.85;';
			}
			document.getElementsByTagName('body')[0].appendChild(tip);
		}

		for (j = 0; j < tags.length; j++) {
			var all = document.getElementsByTagName(tags[j]);
			for (i = 0; i < all.length; i++) {
				// TextArea resizer and tinyMCE uses title = 'true' for ID purposes, so no need to process their title
				if (all[i].nodeName != 'TEXTAREA' && all[i].title != 'true' && all[i].title && typeof(all[i].title) == 'string') {
					tooltip.addtip(all[i], all[i].title);
					all[i].alt = all[i].title;
					all[i].title = '';
					addEvent(all[i], 'mouseout', all[i].mouseoutHandler = function () { tooltip.hide(); }, false);
				}
			}
		}

		typeof document.mousemoveHandler != 'undefined' ? removeEvent(document, 'mouseover', document.mousemoveHandler, false) : 0;
		addEvent(document, 'mousemove', document.mousemoveHandler = function (evt) { tooltip.move (evt); }, false);
	},

	addtip: function (obj, tiptext) {
		tiptext = tooltip.format(tiptext);
		addEvent(obj, 'mouseover', obj.mouseoverHandler = function () { tooltip.enable(tiptext); }, false);
	},

	changetip: function (obj, tiptext) {
		typeof obj.mouseoverHandler != 'undefined' ? removeEvent(obj, 'mouseover', obj.mouseoverHandler, false) : 0;
		tooltip.addtip(obj, tiptext);
	},

	ietruebody: function () {
		return document.compatMode && document.compatMode != 'BackCompat' ? document.documentElement : document.body;
	},

	format: function (s) {
		//s = s.replace(/(.{1,50})(?:[\s\/]|$)/g, '$1<br />'); // Word wrap long lines
		//s = s.replace(/\'/g, '\\\'');
		s = s.replace(/[\r\n]/g, '');
		return s;
	},

	move: function (evt) {
		with (this) {
			if (enabled) {
				var curX = ns6 ? evt.pageX : event.x + tooltip.ietruebody().scrollLeft;
				var curY = ns6 ? evt.pageY : event.y + tooltip.ietruebody().scrollTop;

				//tip.innerHTML = 'x:'+curX+', y:'+curY+', w:'+tip.offsetWidth+', h:'+tip.offsetHeight; // Uncomment for debugging

				//Find out how close the mouse is to the corner of the window
				var rightedge = ie && ! opr ? tooltip.ietruebody().clientWidth - event.clientX - offsetX : window.innerWidth - evt.clientX - offsetX - 18;
				var bottomedge = ie && ! opr ? tooltip.ietruebody().clientHeight - event.clientY - offsetY : window.innerHeight - evt.clientY - offsetY;
				var leftedge = offsetX < 0 ? offsetX * (-1) : -1000;

				//if the horizontal distance isn't enough to accomodate the width of the tooltip
				if (rightedge < tip.offsetWidth) {
					//move the horizontal position of the tooltip to the left by it's width
					tip.style.left = ie ? tooltip.ietruebody().scrollLeft + event.clientX - tip.offsetWidth - 10 + 'px' : window.pageXOffset + evt.clientX - tip.offsetWidth - 10 + 'px';
				} else if (curX < leftedge) {
					tip.style.left = '5px';
				} else {
					//horizontal position of the tooltip
					tip.style.left = curX + offsetX + 'px';
				}

				//same concept with the vertical position
				if (bottomedge < tip.offsetHeight) {
					tip.style.top = ie ? tooltip.ietruebody().scrollTop + event.clientY - tip.offsetHeight + 'px' : window.pageYOffset + evt.clientY - tip.offsetHeight + 'px';
				} else {
					tip.style.top = curY + offsetY + 'px';
				}
				tip.style.visibility = 'visible';
			}
		}
	},

	enable: function (text) {
		with (this) {
			if (!tip) return;
			if (ns6 || ie) {
				tip.innerHTML = text;
				tip.style.cssText = tip.style.cssText.replace(/width: ?\d+(px;?)?/i, '');
				if (tip.offsetWidth > maxWidth) tip.style.width = maxWidth + 'px';
				enabled = true;
			}
		}
	},

	hide: function () {
		with (this) {
			if (!tip) return;
			if (ns6 || ie) {
				tip.style.visibility = 'hidden';
				enabled = false;
			}
		}
	}
};
function addEvent(obj, evType, fn, useCapture) {
	if (obj.addEventListener) {
		obj.addEventListener(evType, fn, useCapture);
		return true;
	} else if (obj.attachEvent) {
		var r = obj.attachEvent("on"+evType, fn);
		return r;
	} else {
		alert("Handler could not be attached");
	}
}
function removeEvent(obj, evType, fn, useCapture){
	if (obj.removeEventListener){
		obj.removeEventListener(evType, fn, useCapture);
		return true;
	} else if (obj.detachEvent){
		var r = obj.detachEvent("on"+evType, fn);
		return r;
	} else {
		alert("Handler could not be removed");
	}
}
addEvent(window, 'load', function () { tooltip.init(new Array('a', 'acronym', 'div', 'li', 'input', 'img')); }, false);