/*
 * This variable is needed to avoid two (or more) context-menus to be shown on one right-click
 * in case if one menu assigned to the control and another to one of its owners.
 */
window.__contextMenusAllowed = true;

prepareDocumentOnMouseDownListeners();

function prepareDocumentOnMouseDownListeners() {
  document._addMouseDownListener = _document_addMouseDownListener;
  document._mouseDownListeners = new Array();
  document._addMouseDownListener(document.onmousedown);
  document.onmousedown = _document_dispatchMouseDown;
}

function _document_addMouseDownListener(listener) {
  if (!listener) {
    return;
  }
  this._mouseDownListeners[this._mouseDownListeners.length] = listener;
}

function _document_dispatchMouseDown(event) {
  this._cancelEventDispatch = false;
  for (var i = this._mouseDownListeners.length - 1; i >= 0 ; i--) {
    var listener = this._mouseDownListeners[i];
    if (listener) {
      listener(event);
      if (this._cancelEventDispatch)
        return;
    }
  }
}

function __showContextMenu(menuID, position, minWidth) {
  if (window.__contextMenusAllowed == false)
    return;
  var menu = getControlById(menuID);
  if (menu._isVisible())
    return;
  menu._showAtPosition(position.x, position.y, minWidth);
  window.__contextMenusAllowed = false;
  setTimeout("window.__contextMenusAllowed = true;", 100);
}

function calculateLeft(elt) {
return (elt.x) ? elt.x : getAbsPos(elt,"Left");
}

function calculateTop(elt) { return (elt.y) ? elt.y : getAbsPos(elt,"Top"); }

function getAbsPos(elt,which) {
 iPos = 0;
 while (elt != null) {
  iPos += elt["offset" + which];
  elt = elt.offsetParent;
 }
 return iPos;
}

function initMenuByIDs(menuID, itemIDs, vertical, forceVisible, useAbsolutePosition,
    selectedClassName, autoOpenSubMenusDelay, clickOpenSubMenusAllowed, autoCloseSubMenusDelay, clickCloseSubMenusAllowed) {
  var menu = getControlById(menuID);
  var items = new Array();
  var itemCount = itemIDs.length;
  for (var i = 0; i < itemCount; i++) {
    var itemID = itemIDs[i];
    var item = (itemID   == null) ?  null : (itemID == "notSelectable") ? "notSelectable" : getControlById(itemID);
    items[i] = item;
  }
  initMenu(menu, items, vertical, forceVisible, useAbsolutePosition,
      selectedClassName, autoOpenSubMenusDelay, clickOpenSubMenusAllowed, autoCloseSubMenusDelay, clickCloseSubMenusAllowed);
}

function initMenu(menu, items, vertical, forceVisible, useAbsolutePosition,
    selectedClassName, autoOpenSubMenusDelay, clickOpenSubMenusAllowed, autoCloseSubMenusDelay, clickCloseSubMenusAllowed) {
	menu._useAbsolutePosition = useAbsolutePosition;
  menu._autoOpenSubMenusDelay = autoOpenSubMenusDelay;
  menu._clickOpenSubMenusAllowed = clickOpenSubMenusAllowed;
  menu._autoCloseSubMenusDelay = autoCloseSubMenusDelay;
  menu._clickCloseSubMenusAllowed = clickCloseSubMenusAllowed;
  menu._selectedClassName = selectedClassName;
  menu._rolloverClassName = selectedClassName;
  menu._type = "menu";
  menu._forceVisible = forceVisible;
  menu._mouseInside = false;
  if (!menu._parentMenuItem)
    menu._parentMenuItem = null;
  menu._items = items;
  menu._vertical = vertical;
  menu._selectedItem = null;
  menu._updateMenuItemStyles = _menu_updateMenuItemStyles;

  menu._resetMouseInsideFlagsExceptOf = _menu_resetMouseInsideFlagsExceptOf;
  menu._show = _menu_show;
  menu._showAtPosition = _menu_showAtPosition;
  menu._hide = _menu_hide;
  menu._isMouseInsideAnySubMenu = _menu_isMouseInsideAnySubMenu;
  menu._updateVisibility = _menu_updateVisibility;
  menu._isVisible = _menu_isVisible;
  menu._setVisible = _menu_setVisible;
  menu._setMouseInside = _menu_setMouseInside;
  menu._isMouseInside = _menu_isMouseInside;
  menu._getSelectedItem = _menu_getSelectedItem;
  menu._setSelectedItem = _menu_setSelectedItem;
  menu._resetSelection = _menu_resetSelection;
  menu._addMouseOwner = _menu_addMouseOwner;
  menu._removeMouseOwner = _menu_removeMouseOwner;
  menu.__menuMouseOwners = new Array();
  menu.__menuMouseOwnerCount = 0;
  menu.__lastInactivateRequestNo = 0;
  menu.__currentInactivateRequestNo = -1;
  menu._inactivate = _menu_inactivate;
  menu._handleMouseOwnersChange = _menu_handleMouseOwnersChange;
  menu._getTopMenu = _menu_getTopMenu;
  menu._isChildItem = _menu_isChildItem;
  menu._handleKeyPress = menu_handleKeyPress;

  menu.onmouseover = _menu_mouseOver;
  menu.onmouseout = _menu_mouseOut;

  for (var i = 0; i < items.length; i+=2) {
    var item = items[i];

    var itemParams = items[i + 1];
    var subMenu = (itemParams != "notSelectable") ? itemParams : null;
    var itemSelectable = (itemParams != "notSelectable");

    item._menu = menu;
    item._selectable = itemSelectable;
    initMenuItem(item);

    if (subMenu != null)
      item._setSubMenu(subMenu);
  }

  var code = "getControlById('" + menu.id + "')._updateVisibility()";
  setTimeout(code, 0);

  menu._handleDocumentClick = _menu_handleDocumentClick;
  var mouseDownHandler = __createHandlerFunction(menu, '_handleDocumentClick', null);
  document._addMouseDownListener(mouseDownHandler);


};

function menu_handleKeyPress(evt) {
  clearSelection();
  if (evt)
    event = evt;
}



function _menu_getTopMenu() {
    return (this._parentMenuItem == null) ?
	 this :
	 this._parentMenuItem._getTopMenu();
}

function _menu_addMouseOwner(obj) {
  this.__menuMouseOwners[this.__menuMouseOwnerCount] = obj;
  this.__menuMouseOwnerCount++;

  this._handleMouseOwnersChange();
}

function _menu_removeMouseOwner(obj) {
  var count = this.__menuMouseOwnerCount;
  for (var i = 0; i < count; i++) {
    var item = this.__menuMouseOwners[i];
    if (item == obj) {
      for (j = i + 1; j < count; j++)
        this.__menuMouseOwners[j - 1] = this.__menuMouseOwners[j];

      this.__menuMouseOwnerCount--;
      this._handleMouseOwnersChange();
      break;
    }
  }
}

function _menu_inactivate(requestNo) {
  if (requestNo == this.__currentInactivateRequestNo) {
  	this._resetSelection();
    this.__currentInactivateRequesNo = -1;
  }
}

function _menu_handleMouseOwnersChange() {
  if (this._autoCloseSubMenusDelay != -1) {
    if (this.__menuMouseOwnerCount == 0) {
      this.__lastInactivateRequestNo++;
      this.__currentInactivateRequestNo = this.__lastInactivateRequestNo;
      setTimeout("getControlById('" + this.id + "')._inactivate(" + this.__currentInactivateRequestNo + ")", this._autoCloseSubMenusDelay);
    } else {
      this.__currentInactivateRequestNo = -1;
    }
  }
}


function _menu_isChildItem(menuItem) {
  if (menuItem._type == "menu") {
    menuItem = menuItem._menuItem;
	if (menuItem == null)
	  return false;
    return this._isChildItem(menuItem);
  }
  for (var i = 0; i < this._items.length; i++) {
    var item = this._items[i];
    if (item == menuItem) {
      return true;
    }
    if (!item || !item._subMenu)
    continue;
    if (item._subMenu._isChildItem(menuItem))
      return true;
  }
  return false;
}

function _menu_handleDocumentClick(e) {
  var evt;
  var clickedElement = null;
  if (document.all && event) {
    clickedElement = event.srcElement;
    evt = event;
  } else if (e) {
    clickedElement = e.target.parentNode;
    evt = e;
  }

  var menuItem = getContainingMenuItem(clickedElement);
  var topMenu = this._getTopMenu();
  var alienItem = (menuItem == null) || (menuItem._getTopMenu() != topMenu);//((menuItem != this._parentMenuItem) && (!this._isChildItem(menuItem)));

  if (alienItem && this._clickCloseSubMenusAllowed) {
    this._resetSelection();
    if (!this._forceVisible) {
      if (this._goingToShowMenu)
        this._goingToShowMenu = false;
      else
        this._hide();
    }
  } else if (menuItem != null && this._clickOpenSubMenusAllowed) {
    if (!e)
      e = event;
    if (menuItem._processedEvent == e)
      return;
    menuItem._processedEvent = e;

    var subMenu = menuItem._subMenu;
    if (subMenu != null) {
      if (!subMenu._isVisible()) {
        menuItem._select();
        menuItem._showSubMenu();
      } else {
        if (menuItem._menu == topMenu) {
          menuItem._unselect();
          subMenu._setVisible(false);
        }
      }
    }
  }
}

function getContainingMenuItem(childElement) {
  var element = childElement;
  while (element != null) {
  	if (element._type == "menuItem") {
	  return element;
	}
	element = element.parentNode;
  }
  return element;
}

function initMenuItem(menuItem) {
  menuItem._autoSelect = true;
  menuItem._autoOpenSubMenuDelay = menuItem._menu._autoOpenSubMenusDelay;
  menuItem._type = "menuItem";
  menuItem._mouseInside = false;
  menuItem._borderWidth = 1;
  menuItem._subMenu = null;
  menuItem._selected = false;

  menuItem._setSubMenu = _menuItem_setSubMenu;
  menuItem._setMouseInside = _menuItem_setMouseInside;
  menuItem._isMouseInside = _menuItem_isMouseInside;
  menuItem._select = _menuItem_select;
  menuItem._unselect = _menuItem_unselect;
  menuItem._setSelected = _menuItem_setSelected;
  menuItem._isSelected = _menuItem_isSelected;
  menuItem._updateStyle = _menuItem_updateStyle;
  menuItem._getTopMenu = function() { return this._menu._getTopMenu();}
  menuItem._showSubMenu = _menuItem_showSubMenu;
  menuItem._showSubMenuPauseExpired = _menuItem_showSubMenuPauseExpired;
  menuItem._currentSelectionChangeSession = 0;

  menuItem._itemImage = getControlHelper(menuItem.id, "image");
  menuItem._subMenuImage = getControlHelper(menuItem.id, "subMenuImage");
  menuItem._updateImagesAccordingToState = _menuItem_updateImagesAccordingToState;

  menuItem.onmouseover = _menuItem_mouseOver;
  menuItem.onmouseout = _menuItem_mouseOut;
  menuItem.onmouseout = _menuItem_mouseOut;
  menuItem._prevClickHandler = menuItem.onclick;
  menuItem.onclick = _menuItem_click;

  menuItem._updateStyle();
}

function _menuItem_click(e) {
  if (this._closeOnClick) {
    var topMenu = this._menu._getTopMenu()
    if (topMenu._forceVisible)
      topMenu._resetSelection();
    else
      topMenu._setVisible(false);
  }

  if (this._prevClickHandler)
    this._prevClickHandler(e);
}

function _menuItem_updateImagesAccordingToState() {
  var selected = this._isMouseInside() || this._isSelected();
  if (this._itemImage) {

    if (selected && this._activeImageClassName && (this._activeImageClassName != ""))
      this._itemImage.className = this._activeImageClassName;
    else
      this._itemImage.className = this._imageClassName;
  }
  if (this._subMenuImage) {

    if (selected && this._activeSubMenuImageClassName && (this._activeSubMenuImageClassName != ""))
      this._subMenuImage.className = this._activeSubMenuImageClassName;
    else
      this._subMenuImage.className = this._subMenuImageClassName;
  }
}

function _menuItem_assignUnselectedImages() {
}

function _menu_getSelectedItem() {
  return this._selectedItem;
}

function _menu_setSelectedItem(value) {
  if (this._selectedItem == value)
    return;
  if (this._selectedItem != null)
    this._selectedItem._setSelected(false);

  this._selectedItem = value;

  if (this._selectedItem != null)
    this._selectedItem._setSelected(true);
  if (value == null)
    this._inOpenedState = false;
}

function _menu_resetSelection() {
  this._setSelectedItem(null);
}

function _menu_setMouseInside(value) {
  if (this._mouseeInside == value)
    return;
  if (value);
  else {
    this._getTopMenu()._removeMouseOwner(this);
    for (var i = 0; i < this._items.length; i++) {
      var menuItem = this._items[i];
      this._getTopMenu()._removeMouseOwner(menuItem);
    }
  }
  this._mouseInside = value;
}

function _menu_isMouseInside(value) {
  return this._mouseInside;
}

function _menu_resetMouseInsideFlagsExceptOf(menuItem) {
  for (var i = 0; i < this._items.length; i++) {
    var item = this._items[i];
    if (!item)
      continue;

    if (item != menuItem)
      if (item._mouseInside)
        item._setMouseInside(false);
  }
}

function _menuItem_setMouseInside(value) {
  if (this._mouseeInside == value)
    return;
  if (value) {
    this._getTopMenu()._addMouseOwner(this);
  } else {
    this._getTopMenu()._removeMouseOwner(this);
  }

  this._mouseInside = value;
  if (isOpera())
    this._menu._resetMouseInsideFlagsExceptOf(this);
  this._updateStyle();
  this._updateImagesAccordingToState();

  if (value && this._autoSelect)
    this._select();
  if (!value && this._autoSelect && (this._subMenu == null || !this._subMenu._isVisible()))
    this._unselect();
}

function _menuItem_isMouseInside(value) {
  return this._mouseInside;
}

function _menuItem_select() {
  this._menu._setSelectedItem(this);
}

function _menuItem_unselect() {
  var currentSelectedItem = this._menu._getSelectedItem();
  if (currentSelectedItem == this)
    this._menu._setSelectedItem(null);
}

function _menuItem_setSelected(value) {
  this._selected = value;

  this._updateStyle();

  this._updateImagesAccordingToState();
  this._currentSelectionChangeSession++;

  if (value == true && this._subMenu) {
    var delay = -1;
    if (this._getTopMenu()._inOpenedState)
        delay = 0;
    if (delay == -1) {
      if (this._autoOpenSubMenuDelay != -1)
        delay = this._autoOpenSubMenuDelay;
    }
    if (delay >= 0) {
      if (delay > 0) {
        var code = "getControlById('" + this.id + "')._showSubMenuPauseExpired(" + this._currentSelectionChangeSession + ")";
        setTimeout(code, delay);
      }
      else
        this._showSubMenuPauseExpired(this._currentSelectionChangeSession);
    }
  }

  if (this._subMenu) {
    if (value == false)
      this._subMenu._setVisible(false);
  }

}

function _menuItem_showSubMenuPauseExpired(selectionChangeSession) {
  if (this._currentSelectionChangeSession == selectionChangeSession) {
    if (!this._isMouseInside())
      return;
    this._showSubMenu();
  }
}

function _menuItem_showSubMenu() {
  if (this._subMenu == null || !this._isSelected())
    return;
  this._subMenu._resetSelection();
  this._subMenu._setVisible(true);
  this._getTopMenu()._inOpenedState = true;
}

function _menuItem_isSelected(value) {
  return this._selected;
}

function _menuItem_updateStyle() {
  var clsName = this._baseClassName + " ";
  if (this._selectable)
    clsName += this._mouseInside ? this._menu._rolloverClassName :
                        (this._selected ? this._menu._selectedClassName : "");
  this.className = clsName;
}

function _menuItem_setSubMenu(subMenu) {
  this._subMenu = subMenu;
  if (subMenu != null) {
  	subMenu._parentMenuItem = this;
    var code = "var control = getControlById('" + subMenu.id + "'); if (control._updateVisibility) control._updateVisibility()";
    setTimeout(code, 0);
  }
}

function _menu_updateVisibility() {
  var shouldBeVisible =
    this._forceVisible || this._isMouseInside() || (this._parentMenuItem != null && this._parentMenuItem._isMouseInside()) ||
	this._isMouseInsideAnySubMenu();
  this._setVisible(shouldBeVisible);
}
function _menu_setVisible(value) {
  if (this._isVisible() == value)
    return;
  if (value)
    this._show();
  else
    this._hide();
}

function _menu_isVisible() {
  var result = !(this.style.visibility == "hidden");
  return result;
}

function _menu_isMouseInsideAnySubMenu() {
  var itemCount = this._items;
  for (var i = 0; i < itemCount; i++) {
    var item = this._items[i];
	if (item._isMouseInside())
      return true;
	if (item._subMenu != null && isMouseInsideAnySubMenu(item._subMenu))
	  return true;
  }
  return false;
}

function _menu_mouseOver() {
  this._setMouseInside(true);
}

function _menu_mouseOut() {
  this._setMouseInside(false);
}


window.__lastZIndex = 1000;

function _menu_show() {
  if (this._isVisible())
    return;
  if (this.onShow)
    this.onShow();
  var menuItem = this._parentMenuItem;
  if (menuItem != null) {
    var y = calculateTop(menuItem);
    var x = calculateLeft(menuItem);
    if (menuItem._menu._vertical) {
      x += menuItem.offsetWidth;
  	  y -= menuItem._borderWidth;
      if (x + this.offsetWidth > __getDocumentWidth())
        x = x - menuItem.offsetWidth - this.offsetWidth;
    } else {
      x -= menuItem._borderWidth;
      y += menuItem.offsetHeight;

      if (y + this.offsetHeight > __getDocumentHeight()) {
        y = y - menuItem.offsetHeight - this.offsetHeight;
        }
    }
    this.style.left = x;
    this.style.top = y;
  }
  this.style.visibility = 'visible';
  this.style.zIndex = ++window.__lastZIndex;
  this._updateMenuItemStyles();
}

function _menu_showAtPosition(x, y, minWidth) {
  if (minWidth != null) {
    var menuWidth = __getElementWidth(this);
    if (minWidth > menuWidth)
      this.style.width = minWidth;
    else
      this.style.width = menuWidth;
  }
  if (x + this.offsetWidth > __getDocumentWidth())
    x = x - this.offsetWidth;
  if (y + this.offsetHeight > __getDocumentHeight())

    y = y - this.offsetHeight;
  this.style.left = x;
  this.style.top = y;
  this.style.visibility = 'visible';
  this.style.zIndex = ++window.__lastZIndex;
  this._updateMenuItemStyles();
}

function _menu_updateMenuItemStyles() {
  for (var i = 0; i < this._items.length; i++) {
    var menuItem = this._items[i];
    if (menuItem && menuItem._updateStyle)
      menuItem._updateStyle();
  }
}

function _menu_hide() {
  if (!this._isVisible())
    return;
  this._setSelectedItem(null);
  this.style.visibility = 'hidden';
  if (this.onHide)
    this.onHide();
}
function _menuItem_mouseOver() {
  this._setMouseInside(true);
}
function _menuItem_mouseOut() {
  this._setMouseInside(false);
}