/*
 * filename:      tooltip.js
 * project:       NUSTEP web application core libs
 * app:           ---
 * copyright:     NUSTEP s.r.o. 2002,2006
 * author:        Cestmir Hybl Jr. <cestmir@nustep.net>
 * created:       2004/02
 * modified:      2005/02/04
 * version:       0.901
 * requirements:  JScript 5.0+
 * classes:
 *                - Tooltip
 * global instances:
 *                - tooltip
 * description:
 *     DHTML tooltip component
 *       - direct (string) or indirect (element id) tooltip content
 *       - CSS skinable
 *
 * todo:
 *       - auto move on-screen logic
 */

function Tooltip()
{
  function getElementPosition(el)
  {
    if (!el) return {'x': 0, 'y': 0};

    var pos = {
      'x': el.offsetLeft,
      'y': el.offsetTop
    };

    var parent = el.offsetParent;
    while (parent) {
      pos.x += parent.offsetLeft;
      pos.y += parent.offsetTop;
      parent = parent.offsetParent;
    }

    return result;
  }

  function getEventElement(e)
  {
    var moz = (typeof(window.screenLeft) == "undefined");
    if (moz) {
      var el = e.target;
      while(el.nodeType != el.ELEMENT_NODE)
        el = el.parentNode;
    } else
      var el = e.srcElement;
    // alert(el.onmouseover);
    return el;
  }
  this.getEventElement = getEventElement;

  function getTooltipElement()
  {
    if (!this.elTooltip) {
      var elTooltip = document.getElementById(this.tooltipId);
			if (!elTooltip) {
				elTooltip = document.createElement('div');
				elTooltip.id = this.tooltipId;
				elTooltip.className = this.tooltipCssClass;
				elTooltip.style.display = "none";
				elTooltip.style.position = "absolute";
				document.body.appendChild(elTooltip);
		  }
			this.elTooltip = elTooltip;
		}
		return this.elTooltip;
	}
	this.getTooltipElement = getTooltipElement;

  function documentKeyDown(e)
  {
    if (e.keyCode == 27)
      this.hide();
  }
  this.documentKeyDown = documentKeyDown;

  function documentMouseDown(e)
  {
    this.hide();
  }
  this.documentMouseDown = documentMouseDown;

  function hide()
  {
    if (!this.shown)
      return;

    var elTooltip = this.getTooltipElement();
    elTooltip.style.display = "none";

		this.content = null;
		this.event = null;

    document.onkeydown = this.oldDocumentOnKeyDown;
    document.onmousedown = this.oldDocumentOnMouseDown;

    this.shown = false;
  }
  this.hide = hide;

  function hideDelayed()
  {
    if (this.showTimeoutId) {
      clearTimeout(this.showTimeoutId);
      this.showTimeoutId = null;
    }
    if (this.hideTimeoutId)
      clearTimeout(this.hideTimeoutId);
    this.hideTimeoutId = setTimeout('tooltip.hide();', this.hideDelay);
    this.event = null;
  }
  this.hideDelayed = hideDelayed;

  function cancelHideDelayed()
  {
    if (this.hideTimeoutId) {
      clearTimeout(this.hideTimeoutId);
			this.hideTimeoutId = null;
		}
  }
  this.cancelHideDelayed = cancelHideDelayed;

  function targetOnMouseMove(e)
	{
    if (this.shown && this.sticky)
			this.updatePosition(e);
    this.event = {'clientX': e.clientX, 'clientY': e.clientY, 'srcElement': e.srcElement, 'target': e.target};
	}
	this.targetOnMouseMove = targetOnMouseMove;

  function showDelayed(e, content)
  {
    // cache event and content
    this.event = {'clientX': e.clientX, 'clientY': e.clientY, 'srcElement': e.srcElement, 'target': e.target};
    this.content = content;

    var elEvent = this.getEventElement(e);
    if (!elEvent.onclick)
      elEvent.onclick = function(e) {tooltip.show(e ? e : event); return false;};
    if (!elEvent.onmousedown)
      elEvent.onmousedown = function(e) {tooltip.cancelShowDelayed();};
    if (!elEvent.onmousemove)
      elEvent.onmousemove = function(e) {tooltip.targetOnMouseMove(e ? e : event);};
    if (!elEvent.onmouseout)
      elEvent.onmouseout = function(e) {tooltip.hideDelayed();};

    this.cancelHideDelayed();
    if (this.showTimeoutId)
      clearTimeout(this.showTimeoutId);
    this.showTimeoutId = setTimeout('tooltip.show();', this.showDelay);
  }
  this.showDelayed = showDelayed;

	function cancelShowDelayed()
	{
    if (this.showTimeoutId) {
      clearTimeout(this.showTimeoutId);
      this.showTimeoutId = null;
    }
	}
	this.cancelShowDelayed = cancelShowDelayed;

  function updatePosition(e)
  {
    var rx = document.body.scrollLeft + e.clientX + this.dx;
    var ry = document.body.scrollTop + e.clientY + this.dy;

    var elTooltip = this.getTooltipElement();
    elTooltip.style.left = rx;
    elTooltip.style.top = ry;
  }
	this.updatePosition = updatePosition;

  function show(e, content)
  {
    if (!e)
      e = this.event;
    if (!e)
      return;
    this.event = null;

    if (!content)
		  content = this.content;
		this.content = null;

    var elEvent = this.getEventElement(e);
    this.element = elEvent;
    // elEvent.onmouseout = function(e) {tooltip.hideDelayed();};

    if (typeof(content) != "string")
		  return null;
		var elContent;
		if (content.length < 128 && (elContent = document.getElementById(content)))
		  // content contains element ID, take it's innerHTML
		  content = elContent.innerHTML;

    var elTooltip = this.getTooltipElement();
    elTooltip.onmouseover = function(e) {tooltip.cancelHideDelayed();};
    elTooltip.onmouseout = function(e) {tooltip.hideDelayed();};
    elTooltip.innerHTML = content;
		this.updatePosition(e);
    elTooltip.style.display = "";
		// alert(elTooltip.offsetWidth);

    this.oldDocumentOnKeyDown = document.onkeydown;
    document.onkeydown = function(e) {return tooltip.documentKeyDown(e ? e : event);};
    this.oldDocumentOnMouseDown = document.onmousedown;
    // document.onmousedown = function(e) {return tooltip.documentMouseDown(e ? e : event);};

    this.shown = true;
  }
  this.show = show;

  // variables
  this.shown = false;
  this.bindElement = null;
  this.elTooltip = null;

	// options
	this.sticky = false;
	this.showDelay = 600;
	this.hideDelay = 600;
	this.dx = 15;
	this.dy = 10;
	this.tooltipId = "tooltip";
	this.tooltipCssClass = "tooltip";
	this.autoAttachShowOnClick = true;
}

tooltip = new Tooltip();

