Tooltip = function ()
{
	Dispatcher.call(this, "onmouseover", "onmouseout", "onmousemove");
	Tooltip.instances.push(this);

	this.init();
	this.hideTimeout = null;

	evt.addHandler(this.closeElem, "onclick", createCallback(this, "close"));

}
Tooltip.prototype = new Dispatcher;

Tooltip.alignTopLeft = "TL";
Tooltip.alignTopRight = "TR";
Tooltip.alignTopCenter = "TC";
Tooltip.alignBottomLeft = "BL";
Tooltip.alignBottomRight = "BR";
Tooltip.alignBottomCenter = "BC";
Tooltip.alignMiddleLeft = "ML";
Tooltip.alignMiddleRight = "MR";
Tooltip.alignMiddleCenter = "MC";

Tooltip.ponterHeight = 51;
Tooltip.ponterOffsetLeft = 50;
Tooltip.defaultWidth = 200;
Tooltip.defaultShowClose = true;
Tooltip.defaultAlign = Tooltip.alignTopLeft;
Tooltip.defaultClassName = "";
Tooltip.instances = [];

Tooltip.cleanup = function ()
{
	while (Tooltip.instances.length)
	{
		var inst = Tooltip.instances.shift();
		inst.elem = null;
		inst.pointerElem = null;
		inst.closeElem = null;
		inst.textElem = null;
		inst.textTarget = null;
		inst.contentElem = null;
	}
}

Tooltip.prototype.init = function ()
{
	this.elem = document.body.insertBefore(document.createElement("div"), document.body.childNodes[0]);
	this.elem.id = "info_tooltip";
	this.pointerElem = this.elem.appendChild(document.createElement("div"));
	this.pointerElem.id = "info_pointer";
	with (this.elem.appendChild(document.createElement("div")))
	{
		className = "toprow";
		with (appendChild(document.createElement("div")))
			className = "tl";
		with (appendChild(document.createElement("div")))
			className = "tr";
		with (appendChild(document.createElement("div")))
			className = "tm";
	}
	with (this.contentElem = this.elem.appendChild(document.createElement("div")))
	{
		id = "info_content";
		with (appendChild(document.createElement("div")))
			className = "ml";
		with (appendChild(document.createElement("div")))
			className = "mr";

		this.textElem = appendChild(document.createElement("div"));
		this.textElem.id = "info_tooltip_text";
		this.closeElem = this.textElem.appendChild(document.createElement("div"));
		this.closeElem.id = "info_tooltip_close";
		this.textTarget = this.textElem.appendChild(document.createElement("span"));
	}
	with (this.elem.appendChild(document.createElement("div")))
	{
		className = "bottomrow";
		with (appendChild(document.createElement("div")))
			className = "bl";
		with (appendChild(document.createElement("div")))
			className = "br";
		with (appendChild(document.createElement("div")))
			className = "bm";
	}
	evt.addHandler(this.elem, "onmouseover", createCallback(this, "onmouseover"));
	evt.addHandler(this.elem, "onmouseout", createCallback(this, "onmouseout"));
	evt.addHandler(this.elem, "onmousemove", createCallback(this, "onmousemove"));

	ui.preloadImages(
		"images/info_pointer_top_left.png",
		"images/info_pointer_top_right.png",
		"images/info_pointer_bottom_right.png",
		"images/info_pointer_bottom_left.png",
		"images/info_edge_tl.png",
		"images/info_edge_top.png",
		"images/info_edge_tr.png",
		"images/info_edge_left.png",
		"images/info_edge_right.png",
		"images/info_edge_bl.png",
		"images/info_edge_bottom.png",
		"images/info_edge_br.png");
}
Tooltip.prototype.onmouseover = function (e)
{
	this.fireEvent("onmouseover");
}
Tooltip.prototype.onmouseout = function (e)
{
	this.fireEvent("onmouseout");
}
Tooltip.prototype.onmousemove = function (e)
{
	this.fireEvent("onmousemove");
}

Tooltip.prototype.show = function (tooltipText, alignElem, alignSide, newWidth, showClose, hideTimeout, className, offsetLeft, offsetTop)
{
	if (this.hideTimeout != null)
		window.clearTimeout(this.hideTimeout);

	showClose = showClose != null ? showClose : Tooltip.defaultShowClose;
	alignSide = alignSide != null ? alignSide : Tooltip.defaultAlign;
	newWidth  = newWidth  != null ? newWidth  : Tooltip.defaultWidth;

	this.elem.className = className || Tooltip.defaultClassName;

	this.elem.style.width = newWidth + "px";
	this.textElem.style.height = "auto";
	this.textTarget.innerHTML = tooltipText;
	this.contentElem.style.height = (this.textElem.offsetHeight) + "px";

	var alignH = "L";
	if (alignSide.indexOf("C") != -1)
		alignH = "C";
	if (alignSide.indexOf("R") != -1)
		alignH = "R";

	var alignV = "T";
	if (alignSide.indexOf("M") != -1)
		alignV = "M";
	if (alignSide.indexOf("B") != -1)
		alignV = "B";

	var targetTop = this.getTargetTop(alignElem, alignV);
	var targetLeft = this.getTargetLeft(alignElem, alignH);

	if (alignV == "T" && targetTop < 0)
		alignV = "B";
	if (alignV == "B" && (targetTop + this.getHeight()) > document.body.offsetHeight)
		alignV = "T";

	if (alignH == "L" && targetLeft < 0)
		alignH = "R";
	if (alignH == "R" && (targetLeft + this.getWidth()) > document.body.offsetWidth)
		alignH = "L";

	this.elem.style.top = (this.getTargetTop(alignElem, alignV) + (offsetTop || 0)) + "px";
	this.elem.style.left = (this.getTargetLeft(alignElem, alignH) + (offsetLeft || 0)) + "px";

	if (alignH == "L" || alignH == "C")
		css.replaceClassName(this.pointerElem, "right", "left");
	if (alignH == "R")
		css.replaceClassName(this.pointerElem, "left", "right");

	if (alignV == "T" || alignV == "M")
		css.replaceClassName(this.pointerElem, "bottom", "top");
	if (alignV == "B")
		css.replaceClassName(this.pointerElem, "top", "bottom");

	this.closeElem.style.display = showClose ? "block" : "none";
	this.elem.style.visibility = "visible";

	if (hideTimeout != null)
		this.hideTimeout = window.setTimeout(createCallback(this, "close"), hideTimeout);

	return this.elem;
}

Tooltip.prototype.getTargetTop = function (alignElem, alignSide)
{
	var targetTop;
	if (alignSide == "B")
		targetTop = dom.getTop(alignElem) + alignElem.offsetHeight + Tooltip.ponterHeight - 5;
	else if (alignSide == "M")
		targetTop = dom.getTop(alignElem) - (this.getHeight() - 10) + alignElem.offsetHeight / 2;
	else
		targetTop = dom.getTop(alignElem) - (this.getHeight() - 15);

	return targetTop;
}

Tooltip.prototype.getTargetLeft = function (alignElem, alignSide)
{
	var targetLeft;
	if (alignSide == "R")
		targetLeft = (dom.getLeft(alignElem) + alignElem.offsetWidth) - this.getWidth();
	else if (alignSide == "C")
		targetLeft = dom.getLeft(alignElem) + (alignElem.offsetWidth / 2 - Tooltip.ponterOffsetLeft);
	else
		targetLeft = dom.getLeft(alignElem);

	return targetLeft;
}

Tooltip.prototype.getWidth = function ()
{
	return (this.elem.offsetWidth);
}

Tooltip.prototype.getHeight = function ()
{
	return (this.elem.offsetHeight + (Tooltip.ponterHeight));
}

Tooltip.prototype.close = function ()
{
	this.elem.style.visibility = "hidden";
}

Tooltip.prototype.hide = function ()
{
	this.close();
}

evt.addHandler(window, "onunload", Tooltip.cleanup);
