/*******************************************************************************
 * Copyright (c) 2014-2015 BSI Business Systems Integration AG.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     BSI Business Systems Integration AG - initial API and implementation
 ******************************************************************************/
scout.Menu = function() {
  scout.Menu.parent.call(this);
  this.childActions = [];
  this._addAdapterProperties('childActions');
  this._addModelProperties('overflow');
  this.popup;
  this.excludedByFilter = false;
  this.subMenuIconVisible = true;

  /**
   * This property is set if this is a subMenu. The property is set when this submenu is rendered.
   */
  this.parentMenu;

  /**
   * This property is true when the menu instance was moved into a overflow-menu
   * when there's not enough space on the screen (see MenuBarLayout.js). When set
   * to true, button style menus must be displayed as regular menus.
   */
  this.overflow = false;

  this.defaultMenu = false;
};
scout.inherits(scout.Menu, scout.Action);

/**
 * @override Widget
 */
scout.Menu.prototype._initKeyStrokeContext = function(keyStrokeContext) {
  scout.Menu.parent.prototype._initKeyStrokeContext.call(this, keyStrokeContext);

  keyStrokeContext.registerKeyStroke(new scout.MenuExecKeyStroke(this));
};

scout.Menu.prototype._render = function($parent) {
  if (this.separator) {
    this._renderSeparator($parent);
  } else {
    this._renderItem($parent);
  }
  this.$container.unfocusable();
  this.htmlComp = new scout.HtmlComponent(this.$container, this.session);
};

scout.Menu.prototype._renderProperties = function() {
  scout.Menu.parent.prototype._renderProperties.call(this);
  this._renderDefaultMenu();
};

scout.Menu.prototype._remove = function() {
  scout.Menu.parent.prototype._remove.call(this);
  this.$submenuIcon = null;
  this.$subMenuBody = null;
};

scout.Menu.prototype._renderSeparator = function($parent) {
  this.$container = $parent.appendDiv('menu-separator');
};

scout.Menu.prototype._renderItem = function($parent) {
  this.$container = $parent.appendDiv('menu-item');
  if (this.uiCssClass) {
    this.$container.addClass(this.uiCssClass);
  }

  var mouseEventHandler = this._onMouseEvent.bind(this);
  this.$container
    .on('mousedown', mouseEventHandler)
    .on('contextmenu', mouseEventHandler)
    .on('click', mouseEventHandler);
  if (this.childActions.length > 0 && this.text && this.subMenuIconVisible) {
    this.$submenuIcon = this.$container.appendSpan('submenu-icon');
  }

  // when menus with button style are displayed in a overflow-menu,
  // render as regular menu, ignore button styles.
  if (this.isButton() && !this.overflow) {
    this.$container.addClass('menu-button');
  }
};

scout.Menu.prototype._renderSelected = function() {
  if (!this._doActionTogglesSubMenu()) {
    scout.Menu.parent.prototype._renderSelected.call(this);
  }
  if (this.selected) {
    if (this._doActionTogglesSubMenu()) {
      this._renderSubMenuItems(this, this.childActions);
    } else if (this._doActionTogglesPopup()) {
      this._openPopup();
    }
  } else {
    if (this._doActionTogglesSubMenu() && this.rendered) {
      this._removeSubMenuItems(this);
    } else {
      this._closePopup();
      this._closeSubMenues();
    }
  }
};

scout.Menu.prototype._closeSubMenues = function() {
  this.childActions.forEach(function(menu) {
    if (menu._doActionTogglesPopup()) {
      menu._closeSubMenues();
      menu.setSelected(false);
    }
  });
};

scout.Menu.prototype._removeSubMenuItems = function(parentMenu) {
  if (this.parent instanceof scout.ContextMenuPopup) {
    this.parent.removeSubMenuItems(parentMenu, true);
  } else if (this.parent instanceof scout.Menu) {
    this.parent._removeSubMenuItems(parentMenu);
  }
};

scout.Menu.prototype._renderSubMenuItems = function(parentMenu, menus) {
  if (this.parent instanceof scout.ContextMenuPopup) {
    this.parent.renderSubMenuItems(parentMenu, menus, true);
  } else if (this.parent instanceof scout.Menu) {
    this.parent._renderSubMenuItems(parentMenu, menus);
  }
};

scout.Menu.prototype._doActionTogglesSubMenu = function() {
  return this.childActions.length > 0 && (this.parent instanceof scout.ContextMenuPopup || this.parent instanceof scout.Menu);
};

scout.Menu.prototype._getSubMenuLevel = function() {
  if (this.parent instanceof scout.ContextMenuPopup) {
    return 0;
  }
  return scout.Menu.parent.prototype._getSubMenuLevel.call(this) + 1;
};

scout.Menu.prototype._onMouseEvent = function(event) {
  if (event.which !== 1) {
    return; // Other button than left mouse button --> nop
  }

  // If menu has childActions, a popup should be rendered on click. To create
  // the impression of a faster UI, open the popup already on 'mousedown', not
  // on 'click'. All other actions are handled on 'click'.
  if (event.type === 'mousedown' && this._doActionTogglesPopup()) {
    this.doAction();
  } else if ((event.type === 'click' || event.type === 'contextmenu') && !this._doActionTogglesPopup()) {
    this.doAction();
  }
};

/**
 * May be overridden if the criteria to open a popup differs
 */
scout.Menu.prototype._doActionTogglesPopup = function() {
  return this.childActions.length > 0;
};

/**
 * Overrides the default render logic in ModelAdapter#onChildAdapterChange.
 * We must only render child actions if the sub-menu popup is opened.
 */
scout.Menu.prototype._renderChildActions = function() {
  if (scout.objects.optProperty(this.popup, 'rendered')) {
    var $popup = this.popup.$container;
    this.childActions.forEach(function(menu) {
      menu.render($popup);
    });
  }
};

scout.Menu.prototype._renderText = function(text) {
  scout.Menu.parent.prototype._renderText.call(this, text);
  // Ensure submenu-icon is the last element in the DOM
  if (this.$submenuIcon) {
    this.$submenuIcon.appendTo(this.$container);
  }
  this._updateIconAndTextStyle();
  this.invalidateLayoutTree();
};

scout.Menu.prototype._renderIconId = function() {
  scout.Menu.parent.prototype._renderIconId.call(this);
  this._updateIconAndTextStyle();
  this.invalidateLayoutTree();
};

scout.Menu.prototype._renderVisible = function() {
  scout.Menu.parent.prototype._renderVisible.call(this);
  this.invalidateLayoutTree();
};

scout.Menu.prototype.isTabTarget = function() {
  return this.rendered && this.enabled && this.visible && !this.separator;
};

scout.Menu.prototype._updateIconAndTextStyle = function() {
  var hasText = scout.strings.hasText(this.text) && this.textVisible;
  var hasTextAndIcon = !!(hasText && this.iconId);
  this.$container.toggleClass('menu-textandicon', hasTextAndIcon);
  this.$container.toggleClass('menu-icononly', !hasText);
};

scout.Menu.prototype._closePopup = function() {
  if (this.popup) {
    this.popup.close();
  }
};

scout.Menu.prototype._openPopup = function() {
  if (this.popup) {
    // already open
    return;
  }
  this.popup = this._createPopup();
  this.popup.open();
  this.popup.on('remove', function(event) {
    this.popup = null;
  }.bind(this));
  // Reason for separating remove and close event:
  // Remove may be called if parent (menubar) gets removed or rebuilt.
  // In that case, we do not want to change the selected state because after rebuilding the popup should still be open
  // In every other case the state of the menu needs to be reseted if the popup closes
  this.popup.on('close', function(event) {
    this.setSelected(false);
  }.bind(this));

  if (this.uiCssClass) {
    this.popup.$container.addClass(this.uiCssClass);
  }
};

scout.Menu.prototype._createPopup = function(event) {
  var options = {
    parent: this,
    menu: this,
    ignoreEvent: event,
    openingDirectionX: this.popupOpeningDirectionX,
    openingDirectionY: this.popupOpeningDirectionY
  };

  if (this.parent._filterMenusHandler) {
    options.menuFilter = function(menus, destination, onlyVisible, enableDisableKeyStroke) {
      return this.parent._filterMenusHandler(menus, scout.MenuDestinations.MENU_BAR, onlyVisible, enableDisableKeyStroke);
    }.bind(this);
  }
  return scout.create('MenuBarPopup', options);
};

scout.Menu.prototype._createActionKeyStroke = function() {
  return new scout.MenuKeyStroke(this);
};

scout.Menu.prototype.isToggleAction = function() {
  return this.childActions.length > 0 || this.toggleAction;
};

scout.Menu.prototype.isButton = function() {
  return scout.Action.ActionStyle.BUTTON === this.actionStyle;
};

scout.Menu.prototype.setSelected = function(selected, notifyServer) {
  if (selected === this.selected) {
    return;
  }
  scout.Menu.parent.prototype.setSelected.call(this, selected, notifyServer);
  if (!this._doActionTogglesSubMenu() && !this._doActionTogglesPopup()) {
    return;
  }
  // If menu toggles a popup and is in an ellipsis menu which is not selected it needs a special treatment
  if (this.overflowMenu && !this.overflowMenu.selected) {
    this._handleSelectedInEllipsis();
  }
};

scout.Menu.prototype._handleSelectedInEllipsis = function() {
  // If the selection toggles a popup, open the ellipsis menu as well, otherwise the popup would not be shown
  if (this.selected) {
    this.overflowMenu.setSelected(true);
  }
};

scout.Menu.prototype.setDefaultMenu = function(defaultMenu) {
  if (this.defaultMenu === defaultMenu) {
    return;
  }
  this._setDefaultMenu(defaultMenu);
  if (this.rendered) {
    this._renderDefaultMenu();
  }
};

scout.Menu.prototype._setDefaultMenu = function(defaultMenu) {
  this.defaultMenu = defaultMenu;
};

scout.Menu.prototype._renderDefaultMenu = function() {
  this.$container.toggleClass('default-menu', this.defaultMenu);
};
