/*
* Copyright (c) 2005, 2006 Eric Wilde.
*
* Tooltips.js contains Javascript functions used for displaying tooltips.
* Tooltips are little boxes of text that pop up when a user moves their mouse
* over a form field, push button, etc.  The text is supposed to help them in
* entering data into the form field, etc.  The tooltip remains visible for a
* few seconds and then disappears.
*
* To use tooltips, include this module somewhere within the body of your Web
* page.  It must be placed within the body because it emits an HTML <div>
* block, used to display the tooltips in, that must appear within the body.
*
* To customize the font used in the tooltips, define a variable "TooltipFont"
* prior to invoking ShowTooltip and assign whatever style attributes you want
* to it.  For example:
*
*   var TooltipFont = "font-family: sans-serif; font-size: 11px;";
*
* The default is a san-serif font at 11 pixels.
*
* To customize the colors used for the background, border and text, define the
* variables "TooltipBackground", "TooltipBorder" and "TooltipText" and assign
* whatever colors you want to them.  For example:
*
*   var TooltipBackground = "#FF9999";
*   var TooltipBorder = "#000000";
*   var TooltipText = "#000000";
*
* The defaults are as shown in the example, a pink background with black border
* and text.
*
* To customize the offsets used to set the tooltip away from the mouse at the
* point where it was clicked, define the variables "TooltipXOffset" and
* "TooltipYOffset", setting them to the desired offsets.  For example:
*
*   var TooltipXOffset = 0;
*   var TooltipYOffset = 20;
*
* The defaults are as shown in the example, directly in line with the mouse and
* below it by 20 pixels.
*
* Defining the tooltip font, colors and offsets this way allows a site-wide
* look and feel to be defined in a configuration file.  Changing the config
* file changes all instances of tool tips in the pages that include the config
* file.
*
* To display a tooltip, use onMouseOver on the object that needs a tooltip, to
* invoke the show function.  For example:
*
*   onMouseOver="ShowTooltip(event,
*     '<b>Tool Tips</b><br>Great for howto information', '6000')"
*
* To hide a tooltip, use onMouseOut on the object.  For example:
*
*   onMouseOut="HideTooltip()"
*
* The complete link for an object, including the show and hide functions might
* look something like this:
*
*   <a href="#" onMouseOver="ShowTooltip(event,
*     'Tool Tips</b><br>Great for howto information', '6000')"
*     onMouseOut="HideTooltip()" style="text-decoration: none;">Tool Tips</a>
*
* If you'd like to use tooltips on form objects (e.g. input boxes), you can
* include them in the event handlers for each field.  You'll probably want to
* be sure to set the onClick event to hide the tooltip so that it won't be
* there annoying the user while they are trying to type into a box they've
* clicked on.  If that's the case, you might define the input box as:
*
*   <input type="text" onMouseOver="ShowTooltip(event,
*     'The street address of the person using tooltips', '6000')"
*     onMouseOut="HideTooltip()" onClick="HideTooltip()"
*     size=26 name="Address" value="123 Any Street">
*
* Tooltips can easily be included on the objects supported by this suite of
* functions through the use of the PHP wrapper routines.  Tooltips on buttons
* are supported by PushButtons.php.  Tooltips on form fields are supported by
* all of the functions in FormFuncs.php
*/

/*****************************************************************************/

/*
* Modifications
* -------------
*
* 2006 Mar 24  E. Wilde       Remove the need to pass the <div> object on
*                             ShowToolTip and HideToolTip.  Add ShowToolTipEx
*                             and HideToolTipEx.
* 2005 Aug 1   E. Wilde       Fix problem with tool tips in small windows (e.g.
*                             popup boxes), whereby the tip is truncated by the
*                             edge of the window.
* 2005 Feb 20  E. Wilde       Initial coding.
*/

/*****************************************************************************/

// Anchor to tooltip timers.  Used to make tooltips appear and disappear after
// a reasonable length of time.
var TooltipPopup = 0;
var TooltipTimer = 0;

// This <div> must be written to the body of the document.  These routines use
// it to render the tooltips.  It will be dynamically moved, resized, etc. to
// the correct location where the tooltip needs to appear.
//
// Since there is only one mouse cursor and tooltips are usually associated
// with it, there is no need for multiple <div> blocks.  However, you can set
// multiple <div> blocks up by duplicating this write for as many <div> blocks
// as you want, in the body of your document, and by passing the names of the
// <div> blocks to ShowTooltipEx and HideTooltipEx.
document.write('<div id=ToolTipSlate style="position: absolute; top: 0px; ' +
  'left: 0px; height: 10px; width: 10px; z-index: 1000;"></div>');

/*****************************************************************************/

function HideTooltip()
/*
* returns                               True if the tooltip was hidden, false
*                                       if it wasn't visible in the first
*                                       place.
*
* This routine hides the tooltip that is currently being displayed in the
* default tooltip slate <div> object.  It is usually invoked by an onMouseOut
* event attached to the document object that displays a tooltip.  For example:
*
*   onMouseOut="HideTooltip();"
*
* To show a tooltip in the default slate, use ShowTooltip.  If you'd like to
* define your own <div> objects to use as tooltip slates and show/hide them,
* see HideTooltipEx and ShowTooltipEx.
*/
{
return HideTooltipEx('ToolTipSlate');
}

/*****************************************************************************/

function HideTooltipEx(DivObject)
/*
* DivObject                             The name of the <div> object to be used
*                                       as a tooltip slate that was defined by
*                                       HTML somewhere in the body of the Web
*                                       page.
*
* returns                               True if the tooltip was hidden, false
*                                       if it wasn't visible in the first
*                                       place.
*
* This hides the tooltip that is currently being displayed by the <div> object
* slate that is passed to it.  It is usually invoked by an onMouseOut event
* attached to the document object that displays a tooltip.  For example:
*
*   onMouseOut="HideTooltipEx('MyToolTip');"
*
* To use this routine, you must define a <div> block to be used as a tooltip
* slate, somewhere within the body of your document.  For example:
*
*   <div id=MyToolTip style="position: absolute; top: 0px; left: 0px;
*     height: 10px; width: 10px; z-index: 1000;"></div>'
*
* To hide a tooltip in the default slate, use HideTooltip.  To show a tooltip
* in your own <div> objects use ShowTooltipEx.
*/
{
// If the popup timer hasn't fired yet, there's nothing to do because the
// tooltip isn't visible yet.  Just blow off the timer.
if (TooltipPopup != 0)
  { window.clearTimeout(TooltipPopup); TooltipPopup = 0; return (false); }

// If there is any remaining tooltip timeout, its because the user moved the
// mouse away from the object that was displaying the tooltip, before the timer
// popped.  That being the case, we should clear the timer and then hide the
// tooltip.  However, if the timer has popped, the tooltip is already hidden so
// there's no need to do it again.
if (TooltipTimer != 0)
  { window.clearTimeout(TooltipTimer); return (HideTooltipInt(DivObject)); }

return (false);
}

function HideTooltipInt(DivObject)
/*
* This is an internal routine that does the work of HideTooltip.
*/
{
var HideObject = document.getElementById(DivObject);

// We don't need the timer anymore.
TooltipTimer = 0;

// If Mr. Browser supports the dynamic HTML, hide the tooltip.
if (typeof(HideObject.innerHTML) != "undefined")
  {
  // Hide the <div> object and put it back in the top/left corner.
  HideObject.style.visibility = "hidden";
  HideObject.style.left = 1; HideObject.style.top = 1;

  return (true);
  }

// We couldn't do anything.
return (false);
}

/*****************************************************************************/

function ShowTooltip(DispEvent, TipContent, DisplayTime)
/*
* DispEvent                             A reference to the event that caused
*                                       the tooltip to be displayed.
*                                       Javascript automatically creates the
*                                       event reference, whenever an event is
*                                       fired.  The event reference is named
*                                       "event" and can be passed by including
*                                       the variable name "event" in the
*                                       parameter list to this function.
*
*                                       The event is needed to determine what
*                                       object fired off the tooltip so that
*                                       its coordinates can be used to locate
*                                       the tooltip next to it.
*
* TipContent                            The text or other content that is to be
*                                       displayed in the tooltip.  It can
*                                       include images and HTML markup.
*
* DisplayTime                           The length of time that the tooltip is
*                                       to be displayed for before it
*                                       automatically closes.  Set this time to
*                                       the number of milliseconds desired.
*
* returns                               The boolean value true, if the tooltip
*                                       was displayed, otherwise false.
*
* This routine is used to display a tooltip near an object, when an event such
* as mouse over occurs.  It displays the tooltip in the default tooltip slate
* <div> object.  To display a tooltip, use onMouseOver on the object that needs
* the tooltip to invoke the show function.  For example:
*
*   onMouseOver="ShowTooltip(event,
*     '<b>Mirror</b><br>Very effective at catching suicidal bugs', '6000');"
*
* To hide a tooltip in the default slate, use HideTooltip.  If you'd like to
* define your own <div> objects to use as tooltip slates and show/hide them,
* see HideTooltipEx and ShowTooltipEx.
*/
{
return ShowTooltipEx('ToolTipSlate', DispEvent, TipContent, DisplayTime);
}

/*****************************************************************************/

function ShowTooltipEx(DivObject, DispEvent, TipContent, DisplayTime)
/*
* DivObject                             The name of the <div> object being used
*                                       as a tooltip slate that was defined by
*                                       HTML somewhere in the body of the Web
*                                       page.
*
* DispEvent                             A reference to the event that caused
*                                       the tooltip to be displayed.
*                                       Javascript automatically creates the
*                                       event reference, whenever an event is
*                                       fired.  The event reference is named
*                                       "event" and can be passed by including
*                                       the variable name "event" in the
*                                       parameter list to this function.
*
*                                       The event is needed to determine what
*                                       object fired off the tooltip so that
*                                       its coordinates can be used to locate
*                                       the tooltip next to it.
*
* TipContent                            The text or other content that is to be
*                                       displayed in the tooltip.  It can
*                                       include images and HTML markup.
*
* DisplayTime                           The length of time that the tooltip is
*                                       to be displayed for before it
*                                       automatically closes.  Set this time to
*                                       the number of milliseconds desired.
*
* returns                               The boolean value true, if the tooltip
*                                       was displayed, otherwise false.
*
* This routine is used to display a tooltip near an object, in the <div> object
* slate that is passed to it, when an event such as mouse over occurs.  To
* display a tooltip, use onMouseOver on the object that needs a tooltip to
* invoke the show function.  For example:
*
*   onMouseOver="ShowTooltipEx('MyToolTip', event,
*     '<b>Mirror</b><br>Very effective at catching suicidal bugs', '6000')"
*
* To use this routine, you must define a <div> block to be used as a tooltip
* slate, somewhere within the body of your document.  For example:
*
*   <div id=MyToolTip style="position: absolute; top: 0px; left: 0px;
*     height: 10px; width: 10px; z-index: 1000;"></div>'
*
* To show a tooltip in the default slate, use ShowTooltip.  To hide a tooltip
* in your own <div> objects use HideTooltipEx.
*/
{
// Get the X/Y coordinates from the event.  We need to do this here, since the
// event will be long gone when the timer pops and runs ShowTooltipInt.
var X = (DispEvent.pageX) ? DispEvent.pageX : DispEvent.clientX
  + GetScrollXInt();
var Y = (DispEvent.pageY) ? DispEvent.pageY : DispEvent.clientY
  + GetScrollYInt();

// We need a little hysteresis to prevent the tooltip from flashing like mad as
// the user moves the cursor over the object with the tooltip.  We'll start a
// timer to fire off the tooltip in one second.  If the mouse moves over and
// off of the object in that time, the timer will get canceled and the tooltip
// will never popup.
TooltipPopup = window.setTimeout("ShowTooltipInt('" + DivObject + "', " +
  X + ", " + Y + ", '" + escape(TipContent) + "', " + DisplayTime + ")", 1000);

return (true);
}

function ShowTooltipInt(DivObject, X, Y, TipContent, DisplayTime)
/*
* This is an internal routine that does the work of ShowTooltip.
*/
{
var ShowObject = document.getElementById(DivObject);

// We don't need the timer anymore.
TooltipPopup = 0;

// Internal versions of optional parameters.
var TooltipFontInt = "font-family: Tahoma, Arial, Helvetica, sans-serif; font-size: 11px;";
var TooltipBackgroundInt = "#FF9999";
var TooltipBorderInt = "#000000";
var TooltipTextInt = "#000000";
var TooltipXOffsetInt = 0;
var TooltipYOffsetInt = 20;

// See if the user has defined global values for the optional parameters.  This
// allows a site-wide look and feel to be set from a config file.
if (typeof(TooltipFont) != "undefined") TooltipFontInt = TooltipFont;
if (typeof(TooltipBackground) != "undefined")
  TooltipBackgroundInt = TooltipBackground;
if (typeof(TooltipBorder) != "undefined") TooltipBorderInt = TooltipBorder;
if (typeof(TooltipText) != "undefined") TooltipTextInt = TooltipText;
if ((typeof(TooltipXOffset) != "undefined") && !isNaN(TooltipXOffset))
  TooltipXOffsetInt = TooltipXOffset;
if ((typeof(TooltipYOffset) != "undefined") && !isNaN(TooltipYOffset))
  TooltipYOffsetInt = TooltipYOffset;

// If Mr. Browser supports the dynamic HTML, display the tooltip.
if (typeof(ShowObject.innerHTML) != "undefined")
  {
  // Set the tooltip style and text.  We do this first so that we can get the
  // size of the rendered tooltip to use in calculating where to position it.
  ShowObject.innerHTML = '<table style="' + TooltipFontInt + ' ' +
    'border: ' + TooltipBorderInt + '; ' +
    'border-style: solid; border-top-width: 1px; border-right-width: 1px; ' +
    'border-bottom-width: 1px; border-left-width: 1px; ' +
    'background-color: ' + TooltipBackgroundInt + ';" ' +
    'width=10 border=0 cellspacing=1 cellpadding=1>' +
    '<tr><td nowrap><font style="' + TooltipFontInt + ' ' +
    'color: ' + TooltipTextInt + ';">' + unescape(TipContent) +
    '</font></td></tr></table>';

  // Figure out if the tooltip should display to the left or right of the
  // object (actually the mouse position) that fired us off.  Note that, if the
  // window width is not enough to permit the tooltip to be right or left of
  // the current mouse position, it is positioned 15 pixels in from the left
  // edge of the window (seemed like a nice, round number, at the time).
  //
  // Note that the size of the rendered tooltip is not the top level object,
  // since this is a <div> block with a fixed width of 10px.  Rather, it is the
  // size of the first child, since this is the <table> within the <div>.
  if ((X + ShowObject.firstChild.offsetWidth + TooltipXOffsetInt)
    > (GetWinWidthInt() + GetScrollXInt()))
    {
    X = X - ShowObject.firstChild.offsetWidth - TooltipXOffsetInt;
    if (X <= 0) X = 15;
    }
  else X += TooltipXOffsetInt;

  ShowObject.style.left = X + "px";

  // Show the tooltip offset from the object (actually the mouse position) that
  // fired us off.
  if ((Y + ShowObject.firstChild.offsetHeight + TooltipYOffsetInt)
    > (GetWinHeightInt() + GetScrollYInt()))
    Y = ((Y - ShowObject.firstChild.offsetHeight - TooltipYOffsetInt)
      > GetScrollYInt())
        ? Y - ShowObject.firstChild.offsetHeight - TooltipYOffsetInt
          : GetWinHeightInt() + GetScrollYInt()
            - ShowObject.firstChild.offsetHeight;
  else Y += TooltipYOffsetInt;

  ShowObject.style.top = Y + "px";

  // Make the tooltip visible.
  ShowObject.style.visibility = "visible";

  // Fire off a timer to hide it after a suitable interval.
  TooltipTimer = window.setTimeout("HideTooltipInt('" + DivObject + "')",
    DisplayTime);

  // Return truth (without beauty).
  return (true);
  }

// Otherwise, we don't do anything.
return (false);
}

/*****************************************************************************/

function GetWinWidthInt()
/*
* Internal function to get the current width of the browser window.
*/
{
if (window.innerWidth) return (window.innerWidth - 18);

if (document.documentElement && document.documentElement.clientWidth) 
  return (document.documentElement.clientWidth);

if (document.body && document.body.clientWidth)
  return(document.body.clientWidth);

return (0);
}

/*****************************************************************************/

function GetWinHeightInt()
/*
* Internal function to get the current height of the browser window.
*/
{
if (window.innerHeight) return (window.innerHeight - 18);

if (document.documentElement && document.documentElement.clientHeight)
  return (document.documentElement.clientHeight);

if (document.body && document.body.clientHeight)
  return (document.body.clientHeight);

return (0);
}

/*****************************************************************************/

function GetScrollXInt()
/*
* Internal function to get the current X scroll offset of the browser window.
*/
{
if (typeof window.pageXOffset == "number") return (window.pageXOffset);

if (document.documentElement && document.documentElement.scrollLeft)
  return (document.documentElement.scrollLeft);

if (document.body && document.body.scrollLeft)
  return (document.body.scrollLeft);

if (window.scrollX) return (window.scrollX);

return (0);
}

/*****************************************************************************/

function GetScrollYInt()
/*
* Internal function to get the current Y scroll offset of the browser window.
*/
{
if (typeof window.pageYOffset == "number") return (window.pageYOffset);

if (document.documentElement && document.documentElement.scrollTop)
  return (document.documentElement.scrollTop);

if (document.body && document.body.scrollTop)
  return (document.body.scrollTop);

if (window.scrollY) return (window.scrollY);

return (0);
}
