/*
 * 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 ganttChart;

import java.awt.event.KeyEvent;
import java.util.ResourceBundle;

import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JToolBar;

import ilog.views.gantt.IlvGanttChart;
import ilog.views.gantt.IlvGanttModel;
import ilog.views.gantt.IlvHierarchyChart;
import ilog.views.gantt.IlvHierarchyNode;
import ilog.views.gantt.action.IlvAction;
import ilog.views.gantt.graphic.IlvGanttSheet;
import ilog.views.gantt.model.IlvSimpleActivity;
import ilog.views.gantt.swing.IlvJTable;
import ilog.views.gantt.swing.IlvStringColumn;
import ilog.views.util.IlvResourceUtil;
import shared.AbstractGanttExample;
import shared.GanttCommand;
import shared.data.GeneralActivityFactory;
import shared.data.GeneralResourceFactory;
import shared.data.SimpleEngineeringProject;
import shared.swing.CustomizerPanel;
import shared.swing.DurationFormatCombo;
import shared.swing.ExampleFrame;

/**
 * A Gantt chart example.
 */
public class GanttExample extends AbstractGanttExample {

  /**
   * The various menu and toolbar actions.
   */
  protected IlvAction makeConstraintAction;
  protected IlvAction deleteConstraintAction;

  // =========================================
  // Instance Construction and Initialization
  // =========================================

  /**
   * Creates the Gantt chart.
   *
   * @return The Gantt chart.
   */
  Override
  protected IlvHierarchyChart createChart() {
    return new IlvGanttChart();
  }

  /**
   * Customizes the data model factories and graphic renderers of the Gantt
   * chart.
   */
  Override
  protected void customizeFactories() {
    // Change the default activity and resource factories of the Gantt chart
    // to ones that sequentially number the activities and resources.
    chart.setActivityFactory(new GeneralActivityFactory(chart));
    chart.setResourceFactory(new GeneralResourceFactory(chart));
  }

  /**
   * Customizes the appearance of the Gantt chart.
   */
  Override
  protected void customizeChart() {
    super.customizeChart();

    // Load the resource bundles containing the locale dependent table header
    // labels for the gantt chart.
    ResourceBundle bundle = IlvResourceUtil.getBundle("ganttChart.gantt", getLocale(), getClass().getClassLoader());

    // Default column widths are 75. Resize some of the columns so that the
    // text is not truncated.
    IlvJTable table = chart.getTable();
    table.getColumn("Name").setPreferredWidth(175);
    table.getColumn("Start").setPreferredWidth(90);
    table.getColumn("End").setPreferredWidth(90);

    // Add a duration column after the End column.
    CalendarDurationProperty durationProperty = new CalendarDurationProperty(getDurationFormat());
    IlvStringColumn durationColumn = new IlvStringColumn(bundle.getString("TableColumn.Duration.label"),
        durationProperty, "Duration") {
      Override
      public boolean isEditable(IlvHierarchyNode row) {
        boolean retVal = super.isEditable(row);
        if (retVal && row instanceof IlvSimpleActivity && getGanttModel().getChildCount(row) > 0) {
          if (((IlvSimpleActivity) row).getAutoCalcTimeIntervalFromChildren()) {
            retVal = false;
          }
        }
        return retVal;
      }
    };
    durationColumn.getColumn().setPreferredWidth(90);
    table.addColumn(durationColumn);
    table.moveColumn(durationColumn.getColumnIndex(), 3);

    // Disallow interactive conversion between milestones and activities.
    // Such conversion is not intuitive.
    IlvGanttSheet sheet = chart.getGanttSheet();
    sheet.setMilestoneConversionAllowed(false);
  }

  // =========================================
  // Accessing
  // =========================================

  /**
   * Returns whether any activities are currently selected.
   *
   * @return Whether any activities are selected.
   */
  public boolean isActivitySelected() {
    return chart.getSelectedRows().length > 0;
  }

  /**
   * Returns whether any constraints are currently selected.
   *
   * @return Whether any constraints are selected.
   */
  Override
  public boolean isConstraintSelected() {
    return chart.getSelectedConstraints().length > 0;
  }

  // =========================================
  // Menus
  // =========================================

  /**
   * Initializes the actions for the Edit menu.
   */
  protected void initEditActions() {
    IlvGanttChart chart = (IlvGanttChart) getChart();
    insertRowAction = new GanttCommand.InsertActivityAction(chart);
    insertMilestoneAction = new GanttCommand.InsertMilestoneAction(chart);
    deleteRowAction = new GanttCommand.DeleteSelectedRowsAction(chart);
    makeConstraintAction = new GanttCommand.MakeConstraintAction(chart);
    deleteConstraintAction = new GanttCommand.DeleteSelectedConstraintsAction(chart);
    deleteAllAction = new GanttCommand.DeleteSelectedAction(chart);
    rowExpandCollapseAction = new GanttCommand.RowExpandCollapseAction(chart);
    rowIndentAction = new GanttCommand.RowIndentAction(chart);
    rowOutdentAction = new GanttCommand.RowOutdentAction(chart);
    rowUpAction = new GanttCommand.RowUpAction(chart);
    rowDownAction = new GanttCommand.RowDownAction(chart);
    if (isExitAllowed()) {
      exitAction = new GanttCommand.ExitAction();
    }
  }

  /**
   * Creates the Edit menu.
   *
   * @return The Edit menu.
   */
  Override
  public JMenu createEditMenu() {
    JMenu menu = new JMenu("Edit");
    menu.setMnemonic(KeyEvent.VK_E);
    setHelpID(menu, "Menu.Edit.helpID");
    setStatusText(menu, "Adds, removes, or modifies activities and constraints.");
    initEditActions();

    // Menu item for "Insert new activity".
    int actionCount = 0;
    if (insertRowAction != null) {
      addAction(menu, insertRowAction);
      actionCount++;
    }

    // Menu item for "Insert new milestone".
    if (insertMilestoneAction != null) {
      addAction(menu, insertMilestoneAction);
      actionCount++;
    }

    // Menu item for "Delete selected activity".
    if (deleteRowAction != null) {
      addAction(menu, deleteRowAction);
      actionCount++;
    }

    // Menu item for "Create new constraint".
    if (makeConstraintAction != null) {
      addAction(menu, makeConstraintAction);
      actionCount++;
    }

    // Menu item for "Delete selected constraints".
    if (deleteConstraintAction != null) {
      addAction(menu, deleteConstraintAction);
      actionCount++;
    }

    if (actionCount > 0) {
      menu.addSeparator();
    }

    // Menu item for "Delete all".
    if (deleteAllAction != null) {
      addAction(menu, deleteAllAction);
      menu.addSeparator();
    }

    // Menu item for "Expand/Collapse".
    actionCount = 0;
    if (rowExpandCollapseAction != null) {
      addAction(menu, rowExpandCollapseAction);
      actionCount++;
    }

    // Menu item for "Indent activity".
    if (rowIndentAction != null) {
      addAction(menu, rowIndentAction);
      actionCount++;
    }

    // Menu item for "Outdent activity".
    if (rowOutdentAction != null) {
      addAction(menu, rowOutdentAction);
      actionCount++;
    }

    // Menu item for "Move up".
    if (rowUpAction != null) {
      addAction(menu, rowUpAction);
      actionCount++;
    }

    // Menu item for "Move down".
    if (rowDownAction != null) {
      addAction(menu, rowDownAction);
      actionCount++;
    }

    // Menu item for "Exit".
    if (exitAction != null) {
      if (actionCount > 0) {
        menu.addSeparator();
      }
      addAction(menu, exitAction);
    }

    return menu;
  }

  // =========================================
  // Customizer Panel
  // =========================================

  /**
   * Creates and returns a customizer for view options and formatting.
   *
   * @return The view customizer.
   */
  Override
  protected JComponent createViewCustomizer() {
    CustomizerPanel panel = (CustomizerPanel) super.createViewCustomizer();

    // Add the Duration formatting combination box.
    panel.addSeparator(5);
    panel.addHeading("Duration Format");
    DurationFormatCombo durationCombo = new DurationFormatCombo(this);
    durationCombo.setToolTipText("Select Displayed Duration Format");
    panel.add(durationCombo);

    return panel;
  }

  // =========================================
  // Toolbar
  // =========================================

  /**
   * Populates the toolbar edit actions.
   *
   * @param toolbar
   *          The toolbar.
   */
  Override
  protected void populateToolBarEditActions(JToolBar toolbar) {
    super.populateToolBarEditActions(toolbar);
    addAction(toolbar, makeConstraintAction);
    addAction(toolbar, deleteConstraintAction);
    addAction(toolbar, deleteAllAction);
  }

  // =========================================
  // Data Model
  // =========================================

  /**
   * Creates and returns the Gantt data model.
   *
   * @return The Gantt data model.
   */
  Override
  protected IlvGanttModel createGanttModel() {
    return new SimpleEngineeringProject(chart);
  }

  // =========================================
  // Example Application
  // =========================================

  /**
   * Returns the title of the example.
   *
   * @return The title of the example.
   */
  Override
  public String getTitle() {
    return "Gantt Chart Example";
  }

  /**
   * Application mainline.
   *
   * @param args
   *          The command line arguments.
   */
  public static void main(String[] args) {
    ExampleFrame.createAndShowGUI(GanttExample.class);
  }

}