/*
 * Licensed Materials - Property of Perforce Software, Inc. 
 * © Copyright Perforce Software, Inc. 2014, 2021 
 * © Copyright IBM Corp. 2009, 2014
 * © Copyright ILOG 1996, 2009
 * All Rights Reserved.
 *
 * Note to U.S. Government Users Restricted Rights:
 * The Software and Documentation were developed at private expense and
 * are "Commercial Items" as that term is defined at 48 CFR 2.101,
 * consisting of "Commercial Computer Software" and
 * "Commercial Computer Software Documentation", as such terms are
 * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
 * as applicable.
 */
package popup;

import action.AlarmStateHandler;
import ilog.cpl.graph.IlpGraphView;
import ilog.cpl.model.IlpRepresentationObject;
import ilog.tgo.model.IltLed;
import ilog.views.util.IlvResourceUtil;
import ilog.views.util.servlet.IlvMenuFactory;
import ilog.views.util.servlet.event.JavaScriptActionListener;
import ilog.views.util.servlet.model.IlvMenu;
import ilog.views.util.servlet.model.IlvMenuItem;
import ilog.views.util.servlet.model.IlvMenuSeparator;

/**
 * This bean defines a pop-up menu factory for a equipment view JSF component by
 * implementing the <code>IlvMenuFactory</code>, allowing the creation of menu
 * items that trigger server and client actions.
 */
public class PopupMenuFactory implements IlvMenuFactory {

  //////////////////////////////////////////////////////////////////////////////
  // Identifiers used in the menus for the various interactors
  //////////////////////////////////////////////////////////////////////////////
  private static final String PAN_MENU_MODEL_ID = "panInteractorId";

  private static final String ZOOM_MENU_MODEL_ID = "zoomInteractorId";

  private static final String SELECT_MENU_MODEL_ID = "selectInteractorId";

  //////////////////////////////////////////////////////////////////////////////
  // Action listener in charge of handling the alarm server actions.
  //////////////////////////////////////////////////////////////////////////////
  private AlarmStateHandler alarmStateHandler;

  public PopupMenuFactory() {
    alarmStateHandler = new AlarmStateHandler();
  }

  /**
   * Returns the <i>pan</i> menu model identifier.
   */
  public String getPanMenuModelId() {
    return PopupMenuFactory.PAN_MENU_MODEL_ID;
  }

  /**
   * Returns the <i>zoom</i> menu model identifier.
   */
  public String getzoomMenuModelId() {
    return PopupMenuFactory.ZOOM_MENU_MODEL_ID;
  }

  /**
   * Returns the <i>select</i> menu model identifier.
   */
  public String getSelectMenuModelId() {
    return PopupMenuFactory.SELECT_MENU_MODEL_ID;
  }

  /**
   * <p>
   * Generates the pop-up menu.
   *
   * @param graphic
   *          The <code>IlpequipmentView</code> component
   * @param activeObject
   *          The representation object (<code>IlpRepresentationObject</code>)
   *          currently active (right below the mouse pointer)
   * @param menuModelId
   *          The menu model ID
   * @return The root menu.
   */
  Override
  public IlvMenu createMenu(Object graphicComponent, Object activeObject, String menuModelId) {
    // Create the root menu
    IlvMenu root = new IlvMenu("Root");

    // Create the menu items from interactors
    createInteractorMenuItems(root, menuModelId);

    // Create the alarm menu items
    createAlarmMenuItems(root, activeObject, (IlpGraphView) graphicComponent);

    // Remove a potential separator that may have been added needlessly
    trimPopupMenu(root);

    return root;
  }

  /**
   * <p>
   * Create menu items from the interactors.
   *
   * @param root
   *          The root pop-up menu
   * @param menuModelId
   *          The interactor currently selected
   */
  private void createInteractorMenuItems(IlvMenu root, String menuModelId) {

    // Create a menu item that activates (if not already active) the
    // "selectButton" button in the JSP page
    boolean enabled = !SELECT_MENU_MODEL_ID.equals(menuModelId);
    createJSMenuItem(root, IlvResourceUtil.getCurrentLocaleString(PopupMenuFactory.class, "EnableSelectionMenu"),
        "resources/images/popup/arrow.gif", "selectButton.doClick()", enabled);

    // Create a menu item that activates (if not already active) the
    // "panButton" button in the JSP page
    enabled = !PAN_MENU_MODEL_ID.equals(menuModelId);
    createJSMenuItem(root, IlvResourceUtil.getCurrentLocaleString(PopupMenuFactory.class, "EnablePanningMenu"),
        "resources/images/popup/pan.gif", "panButton.doClick()", enabled);

    // Create a menu item that activates (if not already active) the
    // "zoomButton" button in the JSP page
    enabled = !ZOOM_MENU_MODEL_ID.equals(menuModelId);
    createJSMenuItem(root, IlvResourceUtil.getCurrentLocaleString(PopupMenuFactory.class, "EnableZoomingMenu"),
        "resources/images/popup/zoomrect.gif", "zoomButton.doClick()", enabled);

    // Add a menu separator
    root.addChild(new IlvMenuSeparator());

    // Create a menu item that shows all the equipment in the client view
    createJSMenuItem(root, IlvResourceUtil.getCurrentLocaleString(PopupMenuFactory.class, "ShowallMenu"),
        "resources/images/popup/zoomfit.gif", "equipmentView.showAll()", true);

    // Create a menu item that zooms in the client view
    createJSMenuItem(root, IlvResourceUtil.getCurrentLocaleString(PopupMenuFactory.class, "ZoominMenu"),
        "resources/images/popup/zoom.gif", "equipmentView.zoomIn()", true);

    // Create a menu item that zooms out the client view
    createJSMenuItem(root, IlvResourceUtil.getCurrentLocaleString(PopupMenuFactory.class, "ZoomoutMenu"),
        "resources/images/popup/unzoom.gif", "equipmentView.zoomOut()", true);

    // Add a menu separator
    root.addChild(new IlvMenuSeparator());
  }

  /**
   * <p>
   * Create the appropriate alarm menu items
   * 
   * @param root
   *          The root pop-up menu
   * @param activeObj
   *          The object under the pop-up menu
   * @param graphView
   *          The underlying <code>IlpGraphView</code>
   */
  private void createAlarmMenuItems(IlvMenu root, Object activeObj, IlpGraphView graphView) {

    // Only if we have a selected object
    if (isValidActiveObject(activeObj)) {

      //////////////////////////////////////////////////////////////////////////
      // ADD
      //////////////////////////////////////////////////////////////////////////

      // MAJOR
      IlvMenuItem item = new IlvMenuItem(
          IlvResourceUtil.getCurrentLocaleString(PopupMenuFactory.class, "AddMajorAlarmMenu"), alarmStateHandler, null,
          true);
      item.setId(AlarmStateHandler.ADD_MAJOR_ID);
      root.addChild(item);

      // MINOR
      item = new IlvMenuItem(IlvResourceUtil.getCurrentLocaleString(PopupMenuFactory.class, "AddMinorAlarmMenu"),
          alarmStateHandler, null, true);
      item.setId(AlarmStateHandler.ADD_MINOR_ID);
      root.addChild(item);

      // WARNING
      item = new IlvMenuItem(IlvResourceUtil.getCurrentLocaleString(PopupMenuFactory.class, "AddWarningAlarmMenu"),
          alarmStateHandler, null, true);
      item.setId(AlarmStateHandler.ADD_WARNING_ID);
      root.addChild(item);

      // Add a menu separator
      root.addChild(new IlvMenuSeparator());

      //////////////////////////////////////////////////////////////////////////
      // REMOVE
      //////////////////////////////////////////////////////////////////////////

      // MAJOR
      item = new IlvMenuItem(IlvResourceUtil.getCurrentLocaleString(PopupMenuFactory.class, "RemoveMajorAlarmMenu"),
          alarmStateHandler, null, true);
      item.setId(AlarmStateHandler.REMOVE_MAJOR_ID);
      root.addChild(item);

      // MINOR
      item = new IlvMenuItem(IlvResourceUtil.getCurrentLocaleString(PopupMenuFactory.class, "RemoveMinorAlarmMenu"),
          alarmStateHandler, null, true);
      item.setId(AlarmStateHandler.REMOVE_MINOR_ID);
      root.addChild(item);

      // WARNING
      item = new IlvMenuItem(IlvResourceUtil.getCurrentLocaleString(PopupMenuFactory.class, "RemoveWarningAlarmMenu"),
          alarmStateHandler, null, true);
      item.setId(AlarmStateHandler.REMOVE_WARNING_ID);
      root.addChild(item);

      // Add a menu separator
      root.addChild(new IlvMenuSeparator());

      // ALL
      item = new IlvMenuItem(IlvResourceUtil.getCurrentLocaleString(PopupMenuFactory.class, "RemoveAllAlarmsMenu"),
          alarmStateHandler, null, true);
      item.setId(AlarmStateHandler.REMOVE_ALL_ID);
      root.addChild(item);
    }
  }

  /**
   * <p>
   * Create a menu item that triggers a JavaScript action, adding it into a
   * given menu.
   *
   * @param menu
   *          The menu where the item should be added to.
   * @param label
   *          The label of the menu item
   * @param image
   *          The icon of the menu item
   * @param jsAction
   *          The JavaScript action to be triggered
   * @param enabled
   *          Whether the menu item is enabled or not
   */
  private void createJSMenuItem(IlvMenu menu, String label, String image, String jsAction, boolean enabled) {
    JavaScriptActionListener action = new JavaScriptActionListener();
    action.setJsAction(jsAction);
    menu.addChild(new IlvMenuItem(label, action, image, enabled));
  }

  /**
   * Removes any trailing separator.
   */
  private void trimPopupMenu(IlvMenu root) {

    int size = root.getChildren().size();

    if (size > 0) {
      IlvMenuItem item = root.getChild(size - 1);
      if (item instanceof IlvMenuSeparator) {
        root.removeChild(size - 1);
      }
    }
  }

  /**
   * Identifies whether the alarm menu items should be created or not.
   */
  private boolean isValidActiveObject(Object activeObject) {
    if (activeObject instanceof IlpRepresentationObject) {
      return !(((IlpRepresentationObject) activeObject).getAttributeValue("type") instanceof IltLed.Type);
    }
    return false;
  }
}