/*
 *  Tooltip display code © 2007-2011, Horus Web Engineering Ltd
 *
 *  $Id: tooltip.js,v 1.47 2011-11-14 15:50:12 horus Exp $
 *
 *  licensed under the terms of the GNU Lesser General Public License:
 *    http://www.opensource.org/licenses/lgpl-license.php
 *
 *  needs horus.js, dom.js, call.js
 *
 */

horus.script.load('dom', 'call');


horus.tooltip=
  function ( event, text, tag ) {
    if (!horus.tooltip.initialised) return;
    if (horus.iewin && window.event) horus.iefix.tooltip();
    var tooltip=horus.tooltip.div;
    var empty=!arguments.length;
    if (!empty) event=horus.event(event);

    if (tooltip.$locked) {
      if (!empty) tooltip.$pending=[ event, text, tag ];
      return;
    }

    tooltip.$locked=false;
    tooltip.$pending=false;

    if (!empty) {
      var node=event.control(':onmouseover');
      if (node==tooltip.$node && text==tooltip.$text) return;
      tooltip.$node=node;
      tooltip.$tag=tag;
      tooltip.$text=text;
      tooltip.$event=event;
      tooltip.$inpopover=horus.parentTag(node, 'div.popover');
      tooltip.$refresher=null;
      horus.removeContents(tooltip);
      text=typeof text=='number' ? horus.tooltip.text(text) : horus.tooltip.check(text);

      if (horus.callable(text)) {
	tooltip.$refresher=text;
	text=horus.call(text, event, false);

	if (horus.hasValue(text))
	  horus.appendChild(tooltip, text, true);
	else
	  empty=true;

      } else
	if (text instanceof Array && !(horus.brokenDOM && text[1]==null))
	  horus.appendChild(tooltip, text, true);
	else if (!horus.isString(text))
	  horus.appendChild(tooltip, text);
	else if (/</.test(text))
	  horus.replaceHTML(tooltip, text);
	else if (text=='')
	  empty=true;
	else {
	  text=text.split('\n');
	  horus.appendChild(tooltip, text.shift());
	  while (text.length) horus.appendChild(tooltip, horus.BR, text.shift());
	}

      if (!empty && !node.onmouseout) node.onmouseout=horus.tooltip.hide;
    }

    horus.tooltip.$visibility(!empty);
    return '';
  };


horus.tooltip.data=[];
horus.tooltip.hide=function () { horus.tooltip() };


horus.tooltip.$visibility=
  function ( show ) {
    var tooltip=horus.tooltip.div;

    if (show) {
      if (!tooltip.$active) {
	tooltip.$active=true;
	tooltip.style.display='block';
	if (tooltip.$inpopover) tooltip.style.zIndex=50000;
      }

      horus.tooltip.move(tooltip.$event);
    } else if (tooltip.$active) {
      tooltip.style.zIndex='';
      tooltip.style.display='none';
      tooltip.$active=false;

      if (tooltip.$locked) {
	tooltip.$node.onmouseout=tooltip.$locked;
	tooltip.$locked=false;
      }

      horus.hash.remove(tooltip, '$node', '$text', '$event', '$inpopover', '$refresher');
      if (tooltip.$pending) horus.tooltip.apply(tooltip.$pending);
    }
  };


horus.tooltip.check=
  function ( tooltip ) {
    if (arguments.length>1 ||
	tooltip instanceof Array && !horus.callable(tooltip) ||
	horus.isString(tooltip) && /\n/.test(tooltip)) {
      tooltip=[].breakList(arguments, -1);
      if (tooltip.length==1 && horus.isString(tooltip[0])) tooltip=tooltip[0];
    } else if (typeof tooltip=='string')
      tooltip=new String(tooltip);

    tooltip.$checked=true;
    return tooltip;
  };


horus.tooltip.text=
  function ( id ) {
    var tooltip=horus.tooltip.data[id];
    if (!tooltip.$checked) horus.tooltip.data[id]=tooltip=horus.tooltip.check(tooltip);
    return tooltip;
  };


horus.tooltip.action=
  function ( tooltip ) {
    return function () { horus.tooltip(arguments, tooltip) };
  };


horus.tooltip.find=
  function ( tooltip ) {
    var id;

    if (arguments.length==1 && typeof tooltip=='number')
      horus.tooltip.text(id=tooltip);
    else {
      var count=horus.tooltip.data.length;
      tooltip=horus.tooltip.check.apply(arguments);
      for (id=0; id<count && !horus.isEqual(horus.tooltip.text(id), tooltip); id++);
      if (id==count) horus.tooltip.data.push(tooltip);
    }

    return id;
  };


horus.tooltip.show=
  function () {
    var id=horus.tooltip.find.apply(arguments);
    var tooltip=horus.tooltip.text(id);
    handler=tooltip.$tooltip;
    if (!handler) tooltip.$tooltip=handler=function () { horus.tooltip(arguments, id) };
    return handler;
  };


horus.tooltip.lock=
  function ( tag ) {
    var tooltip=horus.tooltip.div;

    if (tooltip.$locked) {
      tooltip.$node.onmouseout=tooltip.$locked;

      if (tag==tooltip.$tag)
	tooltip.$locked=false;
      else
	horus.tooltip.$visibility(false);

    } else if (tag==tooltip.$tag) {
      tooltip.$locked=tooltip.$node.onmouseout;
      tooltip.$node.onmouseout="";
    }
  };


horus.tooltip.pending=
  function () {
    if (!horus.tooltip.$pending)
      horus.tooltip.$pending=horus.createElement
	('div', null,
	 [ 'img', { src: '/common/resources/loading.gif', alt: 'loading' } ]);

    return horus.tooltip.$pending;
  };


horus.tooltip.refresh=
  function ( tag ) {
    var tooltip=horus.tooltip.div;

    if (tooltip.$refresher && tag==tooltip.$tag) {
      var text=horus.call(tooltip.$refresher, tooltip.$event, true);
      var empty=!horus.hasValue(text);
      if (!empty) horus.replaceContent(tooltip, text);
      horus.tooltip.$visibility(!empty);
    }
  };


horus.tooltip.move=
  function () {
    var tooltip=horus.tooltip.div;

    if (tooltip.$active && !tooltip.$locked) {
      var event=horus.event(arguments);
      var windowpos=horus.windowPos();
      var top=event.y+10;
      var left=event.x;

      if (top+tooltip.offsetHeight>windowpos.bottom)
	top=windowpos.bottom-tooltip.offsetHeight;

      if (left+8+tooltip.offsetWidth>windowpos.right)
	left-=tooltip.offsetWidth+8;
      else
	left+=8;

      tooltip.style.top=top+'px';
      tooltip.style.left=left+'px';
    }
  };


horus.tooltip.contentdata=
  function ( substitute, store ) {
    var tips=this.selectSingleNode('tooltip', store);

    if (tips) {
      tips=this.selectNodes('item', tips);

      for (var i=0; i<tips.length; i++) {
	var index=this.getAttribute(tips[i], '_index');
	var tip=this.getAttribute(tips[i], '_value', null, 'eval');
	substitute[index]=horus.tooltip.find(tip);
      }
    }
  };


horus.tooltip.init=
  function () {
    horus.tooltip.div=document.getElementById('tooltipdiv');

    if (!horus.tooltip.div) {
      if (!document.body) document.body=document.getElementsByTagName('body')[0];
      horus.tooltip.div=document.createElement('div');
      horus.tooltip.div.id='tooltipdiv';
      document.body.appendChild(horus.tooltip.div);
    }

    horus.tooltip.initialised=true;
    horus.eventListener(document, 'mousemove', horus.tooltip.move);
  };


if (horus.iewin)
  horus.iefix.tooltip=
    function () {
      var node=window.event.srcElement;

      if (node.alt) {
	node.$alt=node.alt;
	node.alt='';
      } else if (node.$alt)
	node.alt=node.$alt;

    };


horus.onLoad(horus.tooltip.init);
horus.script.loaded('tooltip');

