var tooltip;
var tooltipLocationObj;

function toggleTooltip (title, text, locationObj) {
	if (tooltip != null) {
		hideTooltip();
	} else {
		showTooltip(title, text, locationObj);
	}
}

function showTooltip (title, text, locationObj) {
	tooltipLocationObj = locationObj;

	if (typeof text == 'string') {
		var divWidth = (text.length + 150 > 400) ? 400 : text.length + 150;

		// create the tooltip
		tooltip = document.createElement('DIV');
		tooltip.className = 'tooltip';
		tooltip.style.width = divWidth;
		tooltip.innerHTML = "<b>" + title + "</b><p>" + text;

		var screenWidth = (window.innerWidth) ? window.innerWidth - 25 : document.body.clientWidth;
		var screenHeight = (window.innerHeight) ? window.innerHeight : document.body.clientHeight;
		
		// position the tooltip, make sure it doesn't go out of view
		var offsetLeft = getOffsetLeft(locationObj);
		var offsetTop = getOffsetTop(locationObj) + locationObj.offsetHeight;
		if ((offsetLeft + divWidth) > screenWidth) offsetLeft = screenWidth - divWidth;
		tooltip.style.left = offsetLeft;
		tooltip.style.top = offsetTop;

		document.body.appendChild(tooltip);

	// the div is given instead of text
	} else {
		tooltip = text;
		tooltip.style.left = getOffsetLeft(locationObj);
		tooltip.style.top = getOffsetTop(locationObj) + locationObj.offsetHeight;
		tooltip.style.display = "";
	}

	modifyEventListener("add","onmousedown",document,hideTooltipEvt);
}

function hideTooltip () {
	modifyEventListener("remove","onmousedown",document,hideTooltipEvt);

	if (tooltip.id) {
		tooltip.style.display = "none";
	} else {
		document.body.removeChild(tooltip);
	}

	tooltip = null;
	tooltipLocationObj = null;
}

function hideTooltipEvt (evt) {
	var inTooltip;
	var isLink;
	var elem = getEventObjectsElement(evt);

	if (document.all && evt.screenX > document.body.clientWidth) return;

	while (elem.parentNode) {
		if (elem == tooltipLocationObj || elem.tagName == 'scrollbar') return;
		if (elem == tooltip) inTooltip = true;
		if (elem.tagName == 'A') isLink = true;
		elem = elem.parentNode;
	}

	// don't hide on click if a link in the div was clicked or
	// if the HTML attribute 'clickable' has been set and we click inside the div
	if (isLink || (inTooltip && tooltip.clickable)) return;

	hideTooltip();
}

function modifyEventListener(psAction, psEventName, poElement, poFunction){
	var isAdd = ((psAction == "add")||(psAction == "attach"))?true:false;

	psEventName = psEventName.toLowerCase(); // just in case
	if (psEventName.substring(0,2) != "on") {
		psEventName = "on"+psEventName; // in case they gave click instead of onclick
	}

	if ( poElement.addEventListener ) { // W3C DOM2
		if (isAdd) {
			// strip the 'on' off the front of the event name
			poElement.addEventListener(psEventName.substr(2),poFunction,false);
		} else {
			poElement.removeEventListener(psEventName.substr(2),poFunction,false);
		}
		return true;
	} else if ( poElement.attachEvent ) { // IE5+
		if (isAdd) {
			poElement.attachEvent(psEventName,poFunction);
		} else {
			poElement.detachEvent(psEventName,poFunction);
		}
		return true;
	} else if ( document.getElementById ) { // crappola pre-IE5 or NS6 browsers
		if ( poElement.captureEvents ) { // if NS4 must reg then bind
			var sFunc = (isAdd)?"captureEvents":"releaseEvents";
			// event should strip off 'on' and then uppercase
			eval("poElement."+sFunc+"(Event."+psEventName.substr(2).toUpperCase()+");");
		}
		//if add need the name of the function to use in the eval
		var sFunc = (isAdd)?(poFunction.toString().split(' ')[1].split('(')[0]):"null";
		eval("poElement."+psEventName+" = "+sFunc+";");
		return true;
	}

	return false; // none of the above so no event attached, return false
}

function getEventObjectsElement (evt) {
	evt = (evt) ? evt : ((window.event) ? event : null);
	if ( evt ) {
		var elem = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
		// if element contains a text node then need to pop up one
		while ( elem.nodeType == 3 ) {
			elem = elem.parentNode;
		}
		return elem;
	}
	return null;
}

function getOffsetTop (elm) {
	var mOffsetTop = elm.offsetTop;
	var mOffsetParent = elm.offsetParent;

	while (mOffsetParent) {
		mOffsetTop += mOffsetParent.offsetTop;
		mOffsetParent = mOffsetParent.offsetParent;
	}

	return mOffsetTop;
}

function getOffsetLeft (elm) {
	var mOffsetLeft = elm.offsetLeft;
	var mOffsetParent = elm.offsetParent;

	while (mOffsetParent) {
		mOffsetLeft += mOffsetParent.offsetLeft;
		mOffsetParent = mOffsetParent.offsetParent;
	}

	return mOffsetLeft;
}