
/*----------------------------------------------------------------------------

  Multi-layered menuscript
  Written 12/2004 Kristof Elst

----------------------------------------------------------------------------*/

// global definitions

// Maximum number of layers - should be set using PHP
var intMaxMenuLevel = 3
// Last Menu Level displayed - default = 1
var intLastMenuLevel = 1
// Array to keep hide-timers for all levels
var aIntMenuLevelTimer = new Array
// Array to keep names of last shown menu for each level
var aStrMenuLevelName = new Array
// Is the menu in debug mode?
var hasDebugMode = false
// 29/06/2005 -- MZ: Hide the menu after an onclick
document.onclick = hideMenuLayers;

// initialise all timers to 0 (no timer set) and all names to '' (no menu set)
for (var intI=1; intI <= intMaxMenuLevel; intI++)
{
  aIntMenuLevelTimer[intI] = 0
  aStrMenuLevelName[intI] = ''
}

  function initialise(fStrLayerId)
  {
    // debug mode does not work on IE.
    // skip debug mode if no 'debug' div defined.
    if (document.getElementById('debug') && !document.all)
    {
      hasDebugMode = true;
    }
  }


  /*---------------------------------------------------------------------------
  !
  ! Activate a menu - mouse has been moved over a certain item so its
  ! child menu has to be activated
  !
  ! fStrMenuName                : ID of div to be activated (child menu)
  ! fIntMenuLevel               : How deep is the child menu?
  ! fIntTopOffset               : At which height will we set the menu?
  !                             : This is only a multiplier and not
  !                             : the actual offset. The actual offset
  !                             : is calculcated later on.
  ---------------------------------------------------------------------------*/

  function setMenuActive(fStrMenuName, fIntMenuLevel, fIntTopOffset)
  {
    // What menus need to be hidden (if any at all)
    // If we activate a menu, then fIntMenuLevel holds the NEXT menu level
    var intHideMenuLevel = fIntMenuLevel - 1
    // make var local so we can work with it while retaining the original value
    var intMenuLevel = fIntMenuLevel
    // default Top Offset.
    var intMenuTopOffset = 19
    var intMenuLeftOffset = 0

    // Adjust Top offset for IE browsers.
    if (document.all)
    {
      intMenuTopOffset--
    }


    // Start hiding all layers if we moved the mouse from one menu item to
    // another menu item in the same menu level. This will occur if we
    // moved the mouse from item 1 in level 1 to item 2 in level 2. We need
    // to immediately hide the child menu's of item 1 in level 1.

    if (intLastMenuLevel > intHideMenuLevel)
    {
      while (intHideMenuLevel <= intLastMenuLevel)
      {
        intHideMenuLevel++
        clearTimer(aIntMenuLevelTimer[intHideMenuLevel]);
        hideLayer(aStrMenuLevelName[intHideMenuLevel]);
      }
    }

    // the Last Menu Level is incremented to reflect, well, reality.
    intLastMenuLevel = intMenuLevel++

    // clear all timers for the current menulevel. Otherwise, the menu
    // we are trying to view will disappear.
    while (intMenuLevel > 0)
    {
      clearTimer (intMenuLevel)
      intMenuLevel--
    }

    // remember the current menu level so we can hide it later on.
    aStrMenuLevelName[fIntMenuLevel] = fStrMenuName
    // relocate the menu so it gets shown in the right place.
    // This version has a 'set' top (which we fiddle with to get
    // the child items right, but we don't need to calculate the top
    // since it's not dynamic
    // We do need to calculate the left offset using hardcoded parameters
    // The 'left' for the first layer is always correct. It is set using
    // the style sheet. However, the width of the layer varies between
    // firefox and IE so we need to accomodate for that.

//    if (document.all)
//    {
//      intMenuLevel = fIntMenuLevel
//      if (intMenuLevel == 2)
//      {
//        intMenuLeftOffset = 282
//      }
//      else
//      {
//        if (intMenuLevel > 2)
//        {
//          intMenuLeftOffset = 282 + ((intMenuLevel-2) * 199)
//        }
//      }
//    }
    // else, do nothing. The left offsets for Firefox are OK

    // 26/07/2005 -- MZ: Check if the layer exists before showing it
    if (document.getElementById(fStrMenuName)) {
	    relocateMenuDropBox(fStrMenuName, fIntTopOffset * (intMenuTopOffset), intMenuLeftOffset)

	    // now, the good stuff: make the menu visible.
	    document.getElementById(fStrMenuName).style.visibility = 'visible'
    }
  }


  /*---------------------------------------------------------------------------
	! MZ: The following function will reset all menu layer hiding timers
  ---------------------------------------------------------------------------*/
	function hideMenuLayers() {
	 	var intMenuLevel = intMaxMenuLevel;
		while (intMenuLevel > 0)
	    {
			hideLayer(aStrMenuLevelName[intMenuLevel]);
			intMenuLevel--
		}
	}

  /*---------------------------------------------------------------------------
  ! This will make sure we hide the menu. A timeout of 500 ms (0.5 seconds) has
  ! been set so the menu stays active for a short while after the user exits the
  ! menu. This has two purposes: usability and technical. If the user has bad
  ! mouse control, then he can reposition the mouse within 0.5 seconds so the
  ! menu does not disappear. On the other hand, it allows for enough time for
  ! the activation of a new menu to trigger so we can cancel the hide. This
  ! eliminates 'flickering' of the menu.
  !
  ! fIntMenuLevel:  Which level do we need to hide?
  ---------------------------------------------------------------------------*/
  function setMenuInActive(fIntMenuLevel)
  {

    // Initialise to the max level - we will work backwards to the current level
    // to make sure we hide all menus that need to be hidden.
    var intMenuHideLevel = intMaxMenuLevel
    // Assign to a local variable so we can change the value and retain the
    // original value.
    var intMenuLevel = fIntMenuLevel

    // Hide the level above this one, except if this is the maximum level

    if (intMenuLevel <intMaxMenuLevel)
    {
      intMenuLevel ++
    }

    // hide all levels, starting from the highest - level 0 is a fixed menu so
    // little need to hide that, Watson.
    while (intMenuLevel > 0)
    {
      // aIntMenuLevelTimer[intMenuLevel] = setTimeout ("hideLayer(aStrMenuLevelName[" + intMenuLevel + "]," + fIntMenuLevel + ")", 500)
      intMenuLevel--
    }
  }

  /*---------------------------------------------------------------------------
  ! This one actually hides a layer. *gasp*
  !
  ! fStrLayerId               : ID of layer to be hidden
  ! fIntMenuLevel             : what level is this menu at?
  !                           : Not used but included for possible tinkering.
  ---------------------------------------------------------------------------*/

  function hideLayer(fStrLayerId, fIntMenuLevel)
  {

    // hide a layer if the string is not empty - guard against errors
    if (fStrLayerId != '')
    {
      // debug
      debug ('Hiding ' + fStrLayerId)
      // does the layer exist? This is implemented this way so
      // you don't have to bother when coding a loop in your
      // html page. You can just set an activation method
      // and then 'forget' to include the child menu.
      // Everything will continue to work just fine.
      if (document.getElementById(fStrLayerId))
      {
        document.getElementById(fStrLayerId).style.visibility = 'hidden';
      }
    }

  }

  /*---------------------------------------------------------------------------
  ! This clears a timer. It has been made into a separate function for
  ! reusability and if you want to add more stuff later on.
  !
  ! fIntMenuLevel             : what level is this menu at?
  ---------------------------------------------------------------------------*/

  function clearTimer(fIntMenuLevel)
  {
  	if (aIntMenuLevelTimer[fIntMenuLevel]) {
	    clearTimeout(aIntMenuLevelTimer[fIntMenuLevel])
    }
  }

  /*---------------------------------------------------------------------------
  ! This relocates the dropboxes. It allows for cross-browser functionality.
  ! It calculates the top and left offsets for different browsers.
  ! This, alas, is not reusable.
  !
  ! fStrMenuId                : ID of layer to be repositioned.
  ! fIntTopOffset             : Offset of layer according to standard position
  ! fIntLeftOffset            : Offset of layer according to standard position
  ---------------------------------------------------------------------------*/

  function relocateMenuDropBox(fStrMenuId, fIntTopOffset, fIntLeftOffset)
  {
    // standard position of first menu
    var intTop = 93
    var intLeft = fIntLeftOffset
    // is fIntTopOffset > 0? If so, add it to intTop, else add nothing.
    intTop += (fIntTopOffset>0)?fIntTopOffset:0;

    // adjust for difference in positioning between IE and Mozilla
    if (document.all)
    {
      var intTop = intTop + 3;
    }
    // adjust position
	document.getElementById(fStrMenuId).style.top = intTop + 'px'
	if (fIntLeftOffset > 0)
	{
	  document.getElementById(fStrMenuId).style.left = intLeft + 'px'
	}
  }

  // guess what this does ...

  function debug(fStrDebugMessage)
  {
    if (hasDebugMode)
    {
      document.getElementById('debug').innerHTML = document.getElementById('debug').innerHTML + '<BR>' + fStrDebugMessage;
    }
  }