// Copyright 2009 John Heminghous
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//
// Menu - HTML menus
//
// To use place all menu elements inside of menuContainerID, make links (a tag)
// with class name menuItemClass which will show menu on mouse over, set the
// name attribute of a link to be the id of a div (the menu) minus menuSuffix
// (which will be appended to the link name to get the div id)
//
function Menu(menuContainerID, menuItemClass, menuSuffix, useParent)
{
  // Check parameters
  if (!menuContainerID || !menuItemClass || !menuSuffix)
  {
    return;
  }
  
  if (!useParent)
  {
    useParent = false;
  }
  
  //
  // Private variables
  //
  var _cancelHideMenu = false;
  var _menuId = "";
  var _hideMenuTimeout = 350;
  var _initialized = false;
  
  // Initialize object
  initialize(true);
  addEventHandler(window, "resize", function() { initialize(false); });
  
  //
  // Public functions
  //
  this.initialized = function() { return _initialized; }
  
  this.load = function() { initialize(false); }
  
  //
  // Private functions
  //
  function initialize(setCallbacks)
  {
    var menuContainer = document.getElementById(menuContainerID);
    if (!menuContainer)
    {
      return;
    }
    
    var links = menuContainer.getElementsByTagName("a");
    for (var i = 0; i < links.length; ++i)
    {
      if (links[i].className == menuItemClass)
      { 
        var menu = document.getElementById(links[i].name+menuSuffix);
        if (menu)
        {
          // Set up menu positions
          var position = null;
          if (useParent && links[i].parentNode)
          {
            position = getElementPosition(links[i].parentNode);
            // Assuming 1 pixel left and right border
            menu.style.width = (links[i].parentNode.offsetWidth - 2)+"px";
            menu.style.top = position.y+links[i].parentNode.offsetHeight+"px";
          }
          else
          {
            position = getElementPosition(links[i]);
            menu.style.top = position.y+links[i].offsetHeight+"px";
          }
          menu.style.left = position.x+"px";
          
          // Hook up callbacks
          if (setCallbacks)
          {
            links[i].onmouseover = showMenu;
            links[i].onmouseout = hideMenu;
            menu.onmouseover = showMenu;
            menu.onmouseout = hideMenu;
            
            var menuLinks = menu.getElementsByTagName("a");
            for (var j = 0; j < menuLinks.length; ++j)
            {
              menuLinks[j].onmouseover = activateMenuItem;
              menuLinks[j].onmouseout = inactivateMenuItem;
            }
          }
        }
      }
    }
  }
  
  function showMenu(e)
  {
    var link = getActivatedObject(e);
    
    if (link.className == "menuLink")
    {
      var menu = document.getElementById(link.name+menuSuffix);
      if (!menu)
      {
        return;
      }

      if (_menuId != menu.id)
      {
        // Close other open menu and show this one
        if (_menuId != "")
        {
          _cancelHideMenu = false;
          hideMenuCallback();
          _cancelHideMenu = true;
        }
        menu.style.visibility = "visible";
        _menuId = menu.id;
      }
      else
      {
        _cancelHideMenu = true;
      }
    }
    else
    {
      _cancelHideMenu = true;
    }
  }

  function hideMenu(e)
  {
    // Keep menus up for _hideMenuTimeout after hide action
    _cancelHideMenu = false;
    setTimeout(hideMenuCallback, _hideMenuTimeout);
  }

  function hideMenuCallback()
  {
    // Hide menu unless some action was taken to cancel
    if (_cancelHideMenu || _menuId == "")
    {
      return;
    }
    
    var menu = document.getElementById(_menuId);
    if (!menu)
    {
      return;
    }
    menu.style.visibility = "hidden";

    _menuId = "";
    _cancelHideMenu = false;
  }

  function activateMenuItem(e)
  {
    var menuItem = getActivatedObject(getEvent(e));
    menuItem.parentNode.className = "active";
  }

  function inactivateMenuItem(e)
  {
    var menuItem = getActivatedObject(getEvent(e));
    menuItem.parentNode.className = "";
  }
}
