var tooltip;
var tooltipLocationObj;
var tooltipHover;
var tooltipTimeoutID;

function toggleTooltip (title, text, locationObj) {
	if (tooltip != null && locationObj == tooltipLocationObj) {
		hideTooltip();
	} else {
		hideTooltip();
		showTooltip(title, text, locationObj);
	}
}

function showHoverTooltip (title, text, locationObj) {
	tooltipHover = 1;
	tooltipTimeoutID = window.setTimeout(function () {showTooltip(title, text, locationObj);}, 500);
	modifyEventListener("add","onmouseout",locationObj,hideTooltipEvtHover);
	modifyEventListener("add","onclick",locationObj,function () {window.clearTimeout(tooltipTimeoutID);});
}

function showTooltip (title, text, locationObj) {
	// hide any tooltip that's already showing
	if (tooltip) {
		hideTooltip();
	}

	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 + "px";
		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 + "px";
		tooltip.style.top = offsetTop + "px";
		
		if (window.jQuery && window.jQuery(tooltip).hasClass('tooltip')) {
			tooltip.style.display = "none";
		}

		document.body.appendChild(tooltip);
		
		if (window.jQuery && window.jQuery(tooltip).hasClass('tooltip')) {
			window.jQuery(tooltip).fadeIn();
		}

	// the div is given instead of text
	} else {
		tooltip = text;
		tooltip.style.left = getOffsetLeft(locationObj) + "px";
		tooltip.style.top = getOffsetTop(locationObj) + locationObj.offsetHeight + "px";
		
		if (window.jQuery && (window.jQuery(tooltip).hasClass('tooltipMenu') || window.jQuery(tooltip).hasClass('navTooltipMenu'))) {
			window.jQuery(tooltip).slideDown("fast");
		} else {
			tooltip.style.display = "";
		}
		
		if (tooltipHover) {
			modifyEventListener("add","onmouseout",tooltip,hideTooltipEvtHover);
		}
	}

	modifyEventListener("add","onmousedown",document,hideTooltipEvt);
}

function hideTooltip () {
	modifyEventListener("remove","onmousedown",document,hideTooltipEvt);

	if (tooltip && tooltip.id) {
		if (window.jQuery && (window.jQuery(tooltip).hasClass('tooltipMenu') || window.jQuery(tooltip).hasClass('navTooltipMenu'))) {
			window.jQuery(tooltip).slideUp("fast");
		} else if (window.jQuery && window.jQuery(tooltip).hasClass('tooltip')) {
			window.jQuery(tooltip).fadeOut();
		} else {
			tooltip.style.display = "none";
		}
	} else if (tooltip) {
		if (window.jQuery && window.jQuery(tooltip).hasClass('tooltip')) {
			window.jQuery(tooltip).fadeOut();
		} else {
			document.body.removeChild(tooltip);
		}
	}

	tooltip = null;
	tooltipLocationObj = null;
	tooltipHover = 0;
}

// called onmousedown, hides the tooltip if the click was outside the tooltip or tooltip trigger
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();
}

// called onmouseout, hides the tooltip if the mouse was moved outside the tooltip or tooltip trigger
function hideTooltipEvtHover (evt) {
	var elem = evt.relatedTarget || evt.toElement;
	
	// onmouseout event can be triggered when the tooltipLocationObj is within a UL
	if (elem.tagName == "UL") {
		return;
	}
	
	if (tooltip.id == "ddSettings") {
		alert("tagName:" + elem.tagName);
		alert("id:" + elem.id);
		alert("obj:" + tooltipLocationObj);
	}

	// ignore any mouse movement within the tooltip object
	while (elem.parentNode) {
		if (elem == tooltipLocationObj || elem == tooltip) {
			return;
		}
		
		elem = elem.parentNode;
	}
	
	window.clearTimeout(tooltipTimeoutID);
	if (tooltipLocationObj) modifyEventListener("remove","onmouseout",tooltipLocationObj,hideTooltipEvtHover);
	if (tooltip) modifyEventListener("remove","onmouseout",tooltip,hideTooltipEvtHover);

	if (tooltip) 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;
}
