/**
 * XUL version
 */

function displayMenu(menu)
{
  assert(menu instanceof Menu, "Need a Menu as param");
  removeChildren(E("menucontent"));
  setTitle(menu.title);
  for (var i = 0; i < menu.items.length; i++)
    createMenuItemElement(menu.items[i]);
  if (menu.selectedItem)
    updateSelectionDisplay(null, menu.selectedItem);
}

function updateSelectionDisplay(oldSelectedItem, newSelectedItem)
{
  if (oldSelectedItem)
    oldSelectedItem.element.removeAttribute("selected");
  newSelectedItem.element.setAttribute("selected", "true");

  scrollToItem(newSelectedItem);  
}

function createMenuItemElement(menuitem)
{
  var e = document.createElement("description");
  e.setAttribute("class", "menuitem");
  e.textContent = menuitem.title;
  E("menucontent").appendChild(e); 
  menuitem.element = e;
  return e;
}

function setTitle(title)
{
  debug("Screen " + title);
  E("svg-background").contentDocument
      .getElementById("title").firstChild.nodeValue = title;
}

function scrollToItem(menuitem)
{
  try {
    /*
    TODO fails with NS_ERROR_FAILURE, even without <stack>
    E("menucontent").boxObject.QueryInterface(CI.nsIScrollBoxObject)
        .ensureElementIsVisible(menuitem.element);
    */

    var itemE = menuitem.element;
    var containerE = E("menucontent");
    var itemRect = itemE.getBoundingClientRect();
    var containerRect = containerE.getBoundingClientRect();
    var scrollX = {value: null};
    var scrollY = {value: null};
    containerE.boxObject.QueryInterface(CI.nsIScrollBoxObject)
      .getPosition(scrollX, scrollY);
    var itemRelPosX = Math.round(itemRect.left - containerRect.left + scrollX.value);
    var itemRelPosY = Math.round(itemRect.top - containerRect.top + scrollY.value);
    const leeway = itemRect.height;
    /*
    debug("scroll pos: x=" + scrollX.value + ", y=" + scrollY.value);
    debug("item " + menuitem.title);
    debug("item pys rect: x=" + itemRect.left + ", y=" + itemRect.top + ", height=" + itemRect.height + ", width=" + itemRect.width);
    debug("container rect: x=" + containerRect.left + ", y=" + containerRect.top + ", height=" + containerRect.height + ", width=" + containerRect.width);
    debug("itemE scrollTop: " + itemE.scrollTop);
    debug("itemE height: " + itemE.clientHeight);
    debug("itemE pos: x=" + itemE.clientLeft + ", y=" + itemE.clientTop); // always 0
    debug("itemE ofset: x=" + itemE.offsetLeft + ", y=" + itemE.offsetTop); // not implemented
    debug("containerE.height: " + containerE.clientHeight);
    debug("item rel rect: x=" + itemRelPosX + ", y=" + itemRelPosY);
    debug("new pos: " + (containerE.clientHeight - itemE.clientHeight - leeway));
    //if (itemE.scrollTop > containerE.clientHeight - itemE.clientHeight)
    //  itemE.scrollTop = containerE.clientHeight - itemE.clientHeight - leeway;
    */

    // If the selected item is leeway (one item) from the bottom,
    // scroll one whole page down, but so that leeway (one item)
    // above the selected item is still visible.
    // Same vise versa when going up. 
    if (itemRelPosY + itemRect.height + leeway > containerRect.height + scrollY.value)
      containerE.boxObject.QueryInterface(CI.nsIScrollBoxObject)
          .scrollTo(0, itemRelPosY - leeway)
    else if (itemRect.top - leeway < containerRect.top)
      containerE.boxObject.QueryInterface(CI.nsIScrollBoxObject)
          .scrollTo(0, itemRelPosY - containerRect.height + itemRect.height + leeway)
  } catch (e) { errorNonCritical(e); }
}

function keyHandler(aEvent)
{
  try {
    var keyCode = aEvent.keyCode;
    // <https://developer.mozilla.org/en/XUL_Tutorial/Keyboard_Shortcuts#Keycode_attribute>
    if (keyCode == CI.nsIDOMKeyEvent.DOM_VK_DOWN)
      actionDown(1);
    else if (keyCode == CI.nsIDOMKeyEvent.DOM_VK_UP)
      actionUp(1);
    else if (keyCode == CI.nsIDOMKeyEvent.DOM_VK_PAGE_DOWN)
      actionDown(gPageItems);
    else if (keyCode == CI.nsIDOMKeyEvent.DOM_VK_PAGE_UP)
      actionUp(gPageItems);
    else if (keyCode == CI.nsIDOMKeyEvent.DOM_VK_HOME)
      actionFirst();
    else if (keyCode == CI.nsIDOMKeyEvent.DOM_VK_END)
      actionLast();
    else if (keyCode == CI.nsIDOMKeyEvent.DOM_VK_ESCAPE ||
             keyCode == CI.nsIDOMKeyEvent.DOM_VK_LEFT)
      actionBack();
    else if (keyCode == CI.nsIDOMKeyEvent.DOM_VK_RETURN ||
             keyCode == CI.nsIDOMKeyEvent.DOM_VK_ENTER ||
             keyCode == CI.nsIDOMKeyEvent.DOM_VK_SPACE)
      actionLaunch();
  } catch (e) {
    errorCritical(e);
  }
}
