/*
 * Licensed Materials - Property of Rogue Wave Software, Inc. 
 * © Copyright Rogue Wave Software, Inc. 2014, 2017 
 * © 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 resourceLoadChart;

import ilog.views.chart.IlvLegend;
import ilog.views.chart.IlvLegendLayout;
import ilog.views.gantt.IlvScheduleChart;
import ilog.views.gantt.action.IlvAction;
import ilog.views.gantt.print.IlvGanttPrintableDocument;
import ilog.views.gantt.print.IlvGanttPrintingController;
import ilog.views.schedule.IlvResourceDataChart;
import ilog.views.schedule.interactor.IlvScheduleInfoViewInteractor;
import ilog.views.util.print.IlvPrintPreviewPanel;
import ilog.views.util.print.IlvPrintingController;
import ilog.views.util.swing.layout.IlvGridFlowLayout;
import shared.swing.ExampleFrame;
import xml.XMLScheduleExample;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.print.PageFormat;
import java.awt.print.PrinterException;
import javax.swing.*;


/**
 * This example illustrates how to use an <code>IlvResourceDataChart</code> to
 * show the loads of resources selected in an <code>IlvScheduleChart</code>. The
 * main frame of the example contains an <code>IlvSheduleChart</code> at the top
 * with an <code>IlvResourceDataChart</code> below it. When resources are
 * selected in the Schedule chart, the loads of the selected resources are
 * presented by the <code>IlvResourceDataChart</code>. The loads of the selcted
 * resources are calculated by the default <code>IlvReservationLoadData</code>
 * policy that is set on the chart.
 *
 * <p>This example also shows how to synchronize the horizontal time scrolling of
 * the <code>IlvSheduleChart</code> and the <code>IlvResourceDataChart</code>.</p>
 */
public class LoadChartExample extends XMLScheduleExample {

  /**
   * The chart used to show the loads of the selected resources.
   */
  protected IlvResourceDataChart loadChart;

  /**
   * The various menu and toolbar actions.
   */
  protected IlvAction printAction;
  protected IlvAction printSetupAction;
  protected IlvAction printPreviewAction;

  /**
   * The printing controller used to print the Gantt chart.
   */
  protected IlvPrintingController printController;

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

  /**
   * Constructs a new <code>LoadChartExample</code>.
   */
  public LoadChartExample() {
  }

  /**
   * Initializes the user interface of the example in the specified container. This
   * will be the contentPane of the JApplet or the JFrame, depending on how
   * the example is run.
   * @param container The code>contentPane</code> of the JFrame or the JApplet.
   */
  Override
  public void init(Container container) {
    loadChart = new IlvResourceDataChart();
    setHelpID(loadChart, "LoadChart.helpID");

    // Call super.init() to initialize the Schedule chart and invoke
    // customizeChart().
    super.init(container);

    // Remove the Schedule chart and then add it to the top of a
    // vertical split pane. The Resource Data chart will be added to the
    // bottom of the split pane later.
    container.remove(chart);
    JSplitPane splitPane;
    splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
    splitPane.setOneTouchExpandable(true);
    splitPane.setResizeWeight(0.75);
    container.add(splitPane, BorderLayout.CENTER);
    splitPane.setTopComponent(chart);

    // If the example is running as an applet, the container will have a defined
    // fixed height already. In this case, we set the divider location to the
    // approximate mid-point, not counting the menu bar, toolbar, or status bar
    // components. If the example is running as an application, the container
    // will not have a defined size yet. In this case, the preferred sizes of
    // the schedule and load charts will be respected when the frame is packed.
    int containerHeight = container.getHeight();
    if (containerHeight > 0) {
      splitPane.setDividerLocation(containerHeight / 2);
    }

    // By default, the Resource Load chart's legend is docked to its left side. This is
    // fine when the chart is displayed independently in an application. However, here
    // the size of the Resource Load chart is synchronized to the size of the
    // Gantt sheet. Therefore, there is the potential that the Resource Load chart could
    // be resized big enough conflict with its legend. We avoid this by creating a new
    // legend for the Resource Load chart and adding it as a separate gui component
    // below the chart.
    loadChart.setLegendVisible(false);
    IlvLegend legend = new IlvLegend();
    legend.setLayout(new IlvLegendLayout(legend) {
      Override
      protected LayoutManager createDefaultLayout() {
        return new IlvGridFlowLayout(SwingConstants.HORIZONTAL, 3, 3);
      }
    });
    loadChart.setLegend(legend);

    // Add the Resource Load chart and its legend to the bottom of the vertical split pane.
    JPanel loadChartPane = new JPanel(new BorderLayout());
    loadChartPane.add(loadChart, BorderLayout.CENTER);
    loadChartPane.add(legend, BorderLayout.SOUTH);
    splitPane.setBottomComponent(loadChartPane);

    // Add a highlight interactor that displays the load of a resource in a
    // tooltip
    IlvScheduleInfoViewInteractor interactor =
        new IlvScheduleInfoViewInteractor();
    loadChart.addInteractor(interactor);

    // Select some resources of the Schedule chart.
    chart.selectRow(2, true);
    chart.selectRow(3, true);
    chart.selectRow(4, true);
    chart.selectRow(5, true);
  }

  /**
   * Customizes the appearance of the Schedule and Load charts.
   */
  Override
  protected void customizeChart() {
    super.customizeChart();
    IlvScheduleChart ganttChart = (IlvScheduleChart) getChart();

    // Prevent the user from moving the Gantt splitter too far in either direction,
    // in which case the Resource Load chart becomes badly displayed.
    ganttChart.setMinimumTableWidth(25);
    ganttChart.setMinimumGanttSheetWidth(50);
    ganttChart.setDividerOneTouchExpandable(false);
    ganttChart.setDividerSize(3);

    // Synchronize the data models of the charts. Resources selected in the
    // in the Schedule chart will be displayed in the Resource Data chart.
    IlvResourceDataChart loadChart = getLoadChart();
    loadChart.syncGanttModel(ganttChart,
                             IlvResourceDataChart.DISPLAY_SELECTED_LEAVES);

    // Synchronize horizontal scrolling of the charts.
    loadChart.syncXAxis(ganttChart);

    loadChart.setForeground(Color.black);
    loadChart.setFont(new Font("SansSerif", Font.PLAIN, 12));
    loadChart.setMinimumSize(new Dimension(50, 50));
  }

  /**
   * Creates the "File" menu.
   *
   * @return The File menu.
   */
  Override
  public JMenu createFileMenu() {
    JMenu menu = super.createFileMenu();

    // Temporarily remove the "Exit" item.
    int last = menu.getItemCount() - 1;
    JMenuItem exitItem = menu.getItem(last);
    if (isExitAllowed()) {
      menu.remove(exitItem);
    }

    if (isPrintingConfigured()) {
      // Menu item for "Print".
      printAction = new IlvAction("Print...",
                                  null,
                                  KeyStroke.getKeyStroke(KeyEvent.VK_P,
                                                         KeyEvent.CTRL_MASK),
                                  "Print",
                                  "Prints the chart.") {
        Override
        public void actionPerformed(ActionEvent event) {
          initPrintingController();
          try {
            printController.print(true);
          } catch (PrinterException e) {
          }
        }
      };
      printAction.setIcon(LoadChartExample.class, "images/printer.gif");
      addAction(menu, printAction);

      // Menu item for "Print Setup...".
      printSetupAction = new IlvAction("Page Setup...",
                                       null,
                                       KeyStroke.getKeyStroke(KeyEvent.VK_U,
                                                              KeyEvent.CTRL_MASK),
                                       "Page Setup",
                                       "Brings the Page Setup dialog box.") {
        Override
        public void actionPerformed(ActionEvent event) {
          initPrintingController();
          printController.setupDialog(JOptionPane.getFrameForComponent(chart),
                                      true,
                                      true);


        }
      };
      printSetupAction.setIcon(LoadChartExample.class, "images/page-setup.gif");
      addAction(menu, printSetupAction);

      // Menu item for "Preview...".
      printPreviewAction = new IlvAction("Print Preview...",
                                         null,
                                         KeyStroke.getKeyStroke(KeyEvent.VK_V,
                                                                KeyEvent.CTRL_MASK),
                                         "Print Preview",
                                         "Brings up the Print Preview box.") {
        Override
        public void actionPerformed(ActionEvent event) {
          initPrintingController();
          printController.printPreview(JOptionPane.getFrameForComponent(chart));
        }
      };
      printPreviewAction.setIcon(LoadChartExample.class, "images/preview.gif");
      addAction(menu, printPreviewAction);

      menu.addSeparator();
    }

    // Append the "Exit" item, if allowed.
    if (isExitAllowed()) {
      menu.add(exitItem);
    }

    return menu;
  }

  /**
   * Populates the toolbar file actions.
   */
  Override
  protected void populateToolBarFileActions(JToolBar toolbar) {
    int initialActionCount = toolbar.getComponentCount();
    super.populateToolBarFileActions(toolbar);
    int fileActions = toolbar.getComponentCount() - initialActionCount;

    if (isPrintingConfigured()) {
      if (fileActions > 0) {
        toolbar.addSeparator();
      }
      addAction(toolbar, printAction);
      addAction(toolbar, printSetupAction);
      addAction(toolbar, printPreviewAction);
    }
  }

  /**
   * Returns the Load chart.
   */
  protected IlvResourceDataChart getLoadChart() {
    return loadChart;
  }

  /**
   * Initializes the printing controller to print the load chart.
   * The printing controller is based on an <code>IlvGanttPrintingController</code> for all
   * the controls. It initializes a <code>LoadChartDocument</code> to be able to print the
   * load chart, composed of the Schedule chart and the Resource Data chart.
   * By default, it is initialized for printing in landscape, with three table
   * columns, two pages wide.
   */
  protected void initPrintingController() {
    if (printController == null) {
      IlvGanttPrintableDocument loadChartDocument =
          new LoadChartDocument("LoadChart Example", chart, loadChart, 3,
                                true, .3, 2, PageFormat.LANDSCAPE, null);
      printController = new IlvGanttPrintingController(loadChartDocument);
      printController.setPreviewMode(IlvPrintPreviewPanel.CONTINUOUS_MODE);
    }
  }
  

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

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

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

}