
//
// Interface for creating a horizontal menu
// by Nick Santos, 12/04 
//

var MENUBAR_STYLE = "menubar";
var MENU_STYLE = "menu";
var MENU_ON_STYLE = "menuOn";
var MENU_OVER_STYLE = "menuOver";
var MENUITEM_STYLE = "menuItem";
var SPEED = 8;
var mnuCount = 0;
var itemCount = 0;

//createMenuBar(place):
// Creates the beginnings of a menubar,
// and makes it a child of the node 'place'
function createMenuBar(place, w, h) {
  var menubar = document.createElement("span");
  menubar.unselectable = "on";
  menubar.className = MENUBAR_STYLE;
  menubar.menuHeight = h;
  menubar.menuWidth = w;

  place.appendChild(menubar);

  return menubar;
}

//addMenu(mbar, name, link):
// Add a menu to the bar 'mbar':
//  Give it the head 'name' and make it link to 'link'
function addMenu(mbar, name) {
  var mnu = document.createElement("span");
  mnu.className = MENU_STYLE;
  mnu.setAttribute("onmouseenter","expandMenu(this);");
  
  //figure out where to put this item
  var mnuOrder = mbar.childNodes.length;
  mnu.style.position = "absolute";
  mnu.style.width = mbar.menuWidth + "px";
  mnu.style.height = mbar.menuHeight + "px";
  mnu.style.top = "0px";
  mnu.style.left = (mbar.menuWidth*mnuOrder + 5) + "px";

  //create a parameter called 'open' that tells
  // us if the menu is open
  mnu.opened = false;
  mnu.inMenu = false;

  //create variables to store process IDs
  mnu.openingId = 0;
  mnu.closingId = 0;
  mnu.waitingId = 0;

  //add event listeners
  mnu.id = "mnu" + (mnuCount);
  mnuCount = mnuCount + 1;
  
  mnu.onmouseover = new Function("overMenu('"+mnu.id+"');");
  mnu.onmouseout = new Function("outMenu('"+mnu.id+"');");
  mnu.onclick = new Function("clickMenu('"+mnu.id+"');");
  
  //add the text
  var l = document.createTextNode(name);
  mnu.appendChild(l);
  mbar.appendChild(mnu);

  return mnu;
}

//addMenuItem(menu, item, link)
// Add an item to menu 'menu'
// Give it name 'item' and link 'link' 
function addMenuItem(menu, item, link) {
  var i = document.createElement("span");
  i.className = MENUITEM_STYLE;

  var txt = document.createTextNode(item);
  i.appendChild(txt);

  i.setAttribute("href", link);
  i.style.visibility = "hidden";

  //figure out where to put this item
  i.style.top = "0px";
  i.style.left = "-3px";
  i.style.width = parseInt(menu.style.width)*1.25 + "px";
  i.style.height = menu.style.height;

  //if this is not the first menu item,
  // delete the top border of this menu
  // and the bottom border of the last one
  
  if (menu.childNodes.length >= 2) {
    i.style.borderTopWidth = "1px";
    menu.lastItem.style.borderBottomWidth = "1px";
  }
  
  menu.lastItem = i; //set a pointer to the new last item
  
  //add event listeners
  i.id = "item" + (itemCount);
  itemCount++;
  
  var temp = "document.getElementById('";
  i.onclick = new Function("document.location = \""+link+"\";");
  i.onmouseout = new Function(temp+i.id+"').className = 'menuItem';");
  i.onmouseover = new Function(temp+i.id+"').className = 'menuItemOver';");

  menu.appendChild(i);

  return i;
}

//overMenu(menuId)
// changes the style, and records the fact that we're in the
//  menu
function overMenu(menuId) {

  var menu = document.getElementById(menuId);

  if (!menu.opened) {
    menu.className = MENU_OVER_STYLE;
  }
  menu.inMenu = true;

}

//outMenu(menuId)
// Waits a moment, then asks the menu to close
// (waiting a moment gives the user a chance to move
//   the mouse back)
function outMenu(menuId) {

  var menu = document.getElementById(menuId);

  //if we never opened the menu, don't close it
  if (!menu.opened) {
    menu.className = MENU_STYLE;
    return;
  }

  menu.inMenu = false;
  
  setTimeout("closeMenu('"+menuId+"')", 200);

}

//clickMenu(menuId)
// When the menu is clicked, open it
function clickMenu(menuId) {
  var menu = document.getElementById(menuId);
  
  //if it has no children, do nothing
  if (menu.childNodes.length == 1) {
    return;
  }

  //if the menu is already open, do nothing
  if (menu.opened) {
    return;
  }

  menu.opened = true;
  expandMenu(menuId);
}

//expandMenu(menuId)
// An event listener that opens the menu

function expandMenu(menuId) {

  var menu = document.getElementById(menuId);

  menu.className = MENU_ON_STYLE;

  //REMARK: keep in mind that we must IGNORE
  // the first node, which is the text of the menu
  var num_items = menu.childNodes.length - 1;

  var h = parseInt(menu.childNodes[1].style.height);
  var x = 0;
  //on each j-iteration, shift a different menu item
  for (var j = 1; j <= num_items; j = j+1) {
    menu.childNodes[j].style.top = (h*j) + "px";
    
    //on the first step, make them visible
    menu.childNodes[j].style.visibility = "visible";
  }
  
  menu.opened = true;
}

//closeMenu(menuId)
// An event listener that closes the menu when the
//  mouse leaves it

function closeMenu(menuId) {

  var menu = document.getElementById(menuId);

  if (menu.inMenu) return;

  //REMARK: keep in mind that we must IGNORE
  // the first node, which is the text of the menu
  var num_items = menu.childNodes.length - 1;

  var h = parseInt(menu.childNodes[1].style.height);
  var x = 0;
  //on each j-iteration, shift a different menu item
  for (var j = num_items; j >= 1; j = j-1) {
    //on the first step, make them visible
    menu.childNodes[j].style.visibility = "hidden";

    menu.childNodes[j].style.top = "0px";    
  }

  menu.className = MENU_STYLE;
  menu.opened = false;
}

