var showTimer;
var timerActive = false;
var showing = null;

var frameDelay  = 20;
var pctChange   = 10;
var displayTime = 3000;

/***************************************************************************
 * DivInfo object, holds information about a div that is being displayed
 * or hidden.
 **************************************************************************/
function DivInfo(id, divObj, clipPct, reveal)
{
  this.id      = id;
  this.divObj  = divObj;
  this.clipPct = clipPct;
  this.reveal  = reveal;
  this.waiting = false;
  this.showTime = 0;
}

/***************************************************************************
 * Show a div that appears when the mouse hovers over an image
 *
 *   elem   - The element below which to display the div
 *   id     - The id of the div to show
 **************************************************************************/
function showDiv(elem, id)
{
  showDivOff(elem, id, 0, 0);
}

function showDivOff(elem, id, xOff, yOff)
{
  var d;

  // ignore bogus ids
  var div = document.getElementById(id);
  if (!div)
    return;

  // it is ignored if it's already showing or being shown
  if ((showing) && (showing.id == id))
  {
    showing.waiting = false;
    return;
  }

  // hide anything else that's showing
  if (showing)
    hideDiv(showing.id);

  // prep the new object for revealing
  showing = new DivInfo(id, div, 0, true);

  // initially, fully clipped
  div.style.top  = getElemBottomOff(elem, yOff);
  div.style.left = getElemLeftOff(elem, xOff);
  div.style.clip = "rect(auto auto 0px auto)";
  div.style.visibility = "visible";

  // schedule an update
  setTimer();
}

/***************************************************************************
 * Hide a div that appears when the mouse hovers over an image
 * (and disappears when the mouse exits)
 *
 *   id     - The id of the div to hide
 **************************************************************************/
function hideDiv(id)
{
  if ((showing) && (showing.id == id))
  {
    showing.divObj.style.visibility = "hidden";
    showing = null;
  }
}

/***************************************************************************
 * Hide any div being displayed that appears when the mouse hovers
 * over an image (and disappears when the mouse exits)
 **************************************************************************/
function hideAnyDiv(id)
{
  if (showing)
  {
    showing.divObj.style.visibility = "hidden";
    showing = null;
  }
}

/***************************************************************************
 * Start the clock ticking for a div.  When the clock expires, the div
 * is hidden.
 *
 *   id     - The id of the div to clock
 **************************************************************************/
function clockDiv(id)
{
  if ((showing) && (showing.id == id))
  {
    showing.waiting = true;
    setTimer();
  }
}

/***************************************************************************
 * Reset the clock for a div.  When the clock expires, the div is hidden.
 *
 *   id     - The id of the div to clock
 **************************************************************************/
function resetDivClock(id)
{
  if ((showing) && (showing.id == id))
  {
    showing.waiting = true;
    showing.showTime = 0;
    setTimer();
  }
}

/***************************************************************************
 * Sets the timer for div reavealing
 **************************************************************************/
function setTimer()
{
  // see if it's already in progress
  if (!timerActive)
  {
    showTimer = window.setTimeout("revealDiv()", frameDelay);
    timerActive = true;
  }
}

/***************************************************************************
 * Reveal a portion of the divs being scrolled in or out of view
 **************************************************************************/
function revealDiv()
{
  timerActive = false;

  // nothing to do unless something is being shown
  if (!showing)
    return;

  // two possibilities we care about:
  // 1. The div is being revealed
  if (showing.reveal)
  {
    if (clipDiv(showing))
      setTimer();
  }

  // 2. The div is waiting to time out
  else if (showing.waiting)
  {
    // increment time shown
    showing.showTime += frameDelay;

    // see if it can be hidden
    if (showing.showTime >= displayTime)
      hideDiv(showing.id);
    else
      setTimer();
  }

}

/***************************************************************************
 * Set the clipping mask for a div being scrolled in or out of view
 **************************************************************************/
function clipDiv(d)
{
  // set the clip on the div
  var part = d.divObj.offsetHeight * d.clipPct / 100;
  d.divObj.style.clip = "rect(auto auto " + part + "px auto)";

  // calculate the next value for the div and set a timer accordingly
  d.clipPct += pctChange;

  // handle reveals that finish
  if (d.clipPct > 100)
  {
    d.divObj.style.clip = "rect(auto auto auto auto)";
    d.reveal = false;
    d.showTime = 0;
    d.waiting = true;
  }

  return true;
}

/***************************************************************************
 * Return the bottom coordinate for an element
 **************************************************************************/
function getElemBottom(elem)
{
  return(getElemBottomOff(elem, 0));
}

function getElemBottomOff(elem, yOff)
{
  var total = elem.offsetHeight;

  while (elem)
  {
    total += elem.offsetTop;
    elem = elem.offsetParent;
  }

  return (total + yOff + 'px');
}

/***************************************************************************
 * Return the left coordinate for an element
 **************************************************************************/
function getElemLeft(elem)
{
  return(getElemLeftOff(elem, 0));
}

function getElemLeftOff(elem, xOff)
{
  var total = 0;

  while (elem)
  {
    total += elem.offsetLeft;
    elem = elem.offsetParent;
  }

  return (total + xOff + 'px');
}

