/***************************************************************************
*   Copyright (C) 2006, Paul Lutus                                        *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
*   This program is distributed in the hope that it will be useful,       *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
*   GNU General Public License for more details.                          *
*                                                                         *
*   You should have received a copy of the GNU General Public License     *
*   along with this program; if not, write to the                         *
*   Free Software Foundation, Inc.,                                       *
*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
***************************************************************************/

if (typeof document.attachEvent!='undefined') {
  window.attachEvent('onload',setup);
  document.attachEvent('onmousemove',mouseMove);
}
else {
  window.addEventListener('load',setup,false);
  document.addEventListener('mousemove',mouseMove,false);
}

// set this "true" to perform fade
// else the box just pops into view
var perform_fade = true;

// offset of box from mouse cursor, should not be zero
var offset = 10;
// velocity of fade
var fade_rate = 8.0;
// delays before action
var on_time_delay = 500.0;
var off_time_delay = 500.0;

var floatmaker_opacity = 0.0;
var floatmaker_max = 99.9;

var floatmaker_box;

var box_width = 13; /* in em */
var box_padding = 0.25; /* in em */

function setup() {
  floatmaker_box=document.createElement("div");
  floatmaker_box.style.fontSize='1.0em';
  floatmaker_box.style.background='#ffffc0';
  floatmaker_box.style.color='#404040';
  floatmaker_box.style.position='absolute';
  floatmaker_box.style.visibility='hidden';
  floatmaker_box.style.zIndex='1000';
  floatmaker_box.style.opacity = 0;
  floatmaker_box.style.overflow = 'hidden';
  floatmaker_box.style.filter='alpha(opacity=0)';
  document.body.appendChild(floatmaker_box);
}

var on_target = false;
var floatMakerFadeTimer=null;
var title_hash = new Array;
var id_index = 0;

function set_box_state(s)
{
  if(!floatmaker_box) return;
  if(!perform_fade) {
    floatmaker_box.style.opacity = 1.0;
    floatmaker_box.style.filter='alpha(opacity=100.0)';
  }
  if(s.length > 0) {
    floatmaker_box.style.visibility='visible';
    floatmaker_box.style.width=box_width + 'em';
    floatmaker_box.style.padding=box_padding + 'em';
    floatmaker_box.style.border='1px solid #000000';
    floatmaker_box.style.height='';
    floatmaker_box.innerHTML = s;
  }
  else {
    floatmaker_box.style.visibility='hidden';
    floatmaker_box.style.width='0px';
    floatmaker_box.style.height='0px';
    floatmaker_box.style.padding='0px';
    floatmaker_box.style.border='none';
    floatmaker_box.innerHTML = '';
  }
}

// elements need to specify class="floatmaker"
// and have the desired text in their title field
// the title field text can have HTML tags as: &lt;tag&gt;
// including image tags and styled text
// and they will be rendered correctly

function mouseMove(e)
{
  evt=e?e:event;
  if (evt) {
    target=evt.target?evt.target:evt.srcElement;
    if(!target || !floatmaker_box) return;
    
    var cw,ch; // client width and height
    if (self.innerHeight) // all except Explorer
    {
      cw = self.innerWidth;
      ch = self.innerHeight;
    }
    else if (document.documentElement && document.documentElement.clientHeight)
      // Explorer 6 Strict Mode
    {
      cw = document.documentElement.clientWidth;
      ch = document.documentElement.clientHeight;
    }
    else if (document.body) // other Explorers
    {
      cw = document.body.clientWidth;
      ch = document.body.clientHeight;
    }
    
    var sl,st; // scroll left and top
    if (self.pageYOffset) // all except Explorer
    {
      sl = self.pageXOffset;
      st = self.pageYOffset;
    }
    else if (document.documentElement && document.documentElement.scrollTop)
      // Explorer 6 Strict
    {
      sl = document.documentElement.scrollLeft;
      st = document.documentElement.scrollTop;
    }
    else if (document.body) // all other Explorers
    {
      sl = document.body.scrollLeft;
      st = document.body.scrollTop;
    }
    
    
    bsr = cw - sl;
    mouseX=evt.pageX?evt.pageX-sl:evt.clientX-document.body.clientLeft;
    mouseY=evt.pageY?evt.pageY-st:evt.clientY-document.body.clientTop;
    floatmaker_box.style.marginLeft = 0;
    floatmaker_box.style.marginTop = 0;
    // deal with box exceeding dimensions of window
    if (mouseX >= cw * 0.5) {
      floatmaker_box.style.marginLeft = (-(box_width + box_padding * 2.0 + offset * 0.1)) + "em";
    }
    floatmaker_box.style.left=mouseX+sl+offset+"px";
    floatmaker_box.style.top=mouseY+st+offset+"px";
    on_target = (/\bfloatmaker\b/.test(target.className) && (target.title.length > 0 || title_hash[target.id]));
    if (on_target) {
      // if this entity doesn't have an id, create one,
      // otherwise use existing id
      if(target.id.length == 0) {
        target.id = "floatmaker" + id_index;
        id_index++;
      }
      // to prevent default title display,
      // save the original title, then erase it in the tag
      if(target.title.length > 0) {
        title_hash[target.id] = target.title;
        target.title = "";
      }
      if(perform_fade) {
        set_box_state(title_hash[target.id]);
      }
      if(floatmaker_opacity < 50) {
        // don't fade in all over again if already visible
        if (perform_fade) {
          if(floatMakerFadeTimer == null) {
            floatMakerFadeTimer=setTimeout("setup_fade("+fade_rate+")",on_time_delay);
          }
        }
        else {
          floatmaker_opacity = 100.0;
          clearTimeout(floatMakerFadeTimer);
          floatMakerFadeTimer=setTimeout("set_box_state('" + title_hash[target.id] + "');",on_time_delay);
        }
      }
    }
    else { // not on target
      if(floatmaker_opacity >= 50) {
        if (perform_fade) {
          if(floatMakerFadeTimer == null) {
            floatMakerFadeTimer=setTimeout("setup_fade(-"+fade_rate+")",off_time_delay);
          }
        }
        else {
          floatmaker_opacity = 0;
          clearTimeout(floatMakerFadeTimer);
          floatMakerFadeTimer=setTimeout("set_box_state('');",off_time_delay);
        }
      }
    }
  }
}

function setup_fade(delta) {
  floatmaker_opacity=(delta < 0)?floatmaker_max:0.0;
  do_fade(delta);
}

function do_fade(delta) {
  clearTimeout(floatMakerFadeTimer);
  floatMakerFadeTimer = null;
  if(!floatmaker_box) return;
  floatmaker_opacity=floatmaker_opacity+delta;
  floatmaker_opacity=(floatmaker_opacity>floatmaker_max)?floatmaker_max:floatmaker_opacity;
  floatmaker_opacity=(floatmaker_opacity<0.0)?0.0:floatmaker_opacity;
  // this line is for MSIE
  floatmaker_box.style.filter='alpha(opacity='+floatmaker_opacity+')';
  // this line is for the others
  floatmaker_box.style.opacity=floatmaker_opacity / 100.0;
  if (delta < 0) {
    if(on_target) { // change fade direction
      do_fade(-delta);
      return;
    }
    if(floatmaker_opacity == 0.0) {
      set_box_state('');
      return;
    }
  }
  else { // delta > 0
    if(!on_target) { // change fade direction
      do_fade(-delta);
      return;
    }
    if(floatmaker_opacity == floatmaker_max) {
      return;
    }
  }
  // if we get to here, then carry on fading.
  floatMakerFadeTimer = setTimeout("do_fade("+delta+")",20);
}

