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

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Calendar;
import java.util.Date;
import java.util.ResourceBundle;

import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JTabbedPane;

import ganttChart.GanttExample;
import ilog.views.gantt.IlvActivity;
import ilog.views.gantt.IlvDuration;
import ilog.views.gantt.IlvHierarchyChart;
import ilog.views.gantt.IlvTimeUtil;
import ilog.views.gantt.scale.IlvBasicTimeScaleRow;
import ilog.views.gantt.scale.IlvTimeScale;
import ilog.views.util.IlvResourceUtil;
import ilog.views.util.time.IlvCalendarFactory;
import ilog.views.util.time.IlvCalendarUtil;
import shared.swing.CustomizerPanel;
import shared.swing.ExampleFrame;

public class GanttChart extends GanttExample {

  // The resource bundle containing the time scale format strings.
  private ResourceBundle bundle;

  // The relative week row.
  private IlvRelativeWeekTimeScaleRow weekRow;

  // The relative day row.
  private IlvRelativeDayTimeScaleRow dayRow;

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

    // Load the resource bundles containing the locale dependent label for the
    // relative time rows demo.
    bundle = IlvResourceUtil.getBundle("relativeTimeScale.gantt", getLocale(), getClass().getClassLoader());
    IlvHierarchyChart chart = getChart();

    // Create a time scale with relative time scale rows
    IlvTimeScale timescale = new IlvTimeScale();
    weekRow = new IlvRelativeWeekTimeScaleRow();
    dayRow = new IlvRelativeDayTimeScaleRow();

    // Set the relative time scale reference date to be the closest hour.
    Calendar calendar = IlvCalendarFactory.createInstance();
    IlvCalendarUtil.dayFloor(calendar);
    Date referenceDate = calendar.getTime();
    weekRow.setReferenceDate(referenceDate);
    dayRow.setReferenceDate(referenceDate);

    timescale.addRow(weekRow);
    timescale.addRow(dayRow);
    chart.setTimeScale(timescale);

    // Bound the time scrolling.
    IlvActivity root = getGanttModel().getRootActivity();
    Date minTime = IlvTimeUtil.subtract(root.getStartTime(), IlvDuration.ONE_DAY.multiply(5));
    Date maxTime = IlvTimeUtil.add(root.getEndTime(), IlvDuration.ONE_DAY.multiply(5));
    chart.setMinVisibleTime(minTime);
    chart.setMaxVisibleTime(maxTime);

    // Set the initial display to extend for 9 days.
    chart.setVisibleDuration(IlvDuration.ONE_DAY.multiply(9));

    // Limit the zoom-in level to 1 day.
    chart.setMinVisibleDuration(IlvDuration.ONE_DAY);
  }

  public void setRowVisibility(int index, boolean visible) {
    IlvHierarchyChart chart = getChart();
    IlvTimeScale timescale = chart.getTimeScale();
    if (visible) {
      timescale.showRow(timescale.getRow(index));
    } else {
      timescale.hideRow(timescale.getRow(index));
    }
  }

  Override
  protected void addCustomizerTabs(JTabbedPane customizerPanel) {
    customizerPanel.addTab("Header", createHeaderCustomizer());
    super.addCustomizerTabs(customizerPanel);
  }

  protected JComponent createHeaderCustomizer() {
    CustomizerPanel panel = new CustomizerPanel();

    JCheckBox WeekVisibility = createVisibilityButton("Week row visibility", 0);
    panel.add(WeekVisibility);
    panel.addHeading("Week Row Format");
    String[] weekFormats = { bundle.getString("WeekLongFormat"), bundle.getString("WeekShortFormat"), "{0}" };
    RelativeFormatCombo weekCombo = new RelativeFormatCombo(weekRow, weekFormats);
    weekCombo.setToolTipText("Select Displayed Week Format");
    panel.add(weekCombo);
    panel.addHeading("Week Row Text Alignment");
    JComboBox<String> weekAlignmentCombo = createLabelAlignmentCombo(weekRow);
    weekAlignmentCombo.setToolTipText("Select Week Text Alignment");
    panel.add(weekAlignmentCombo);

    panel.addSeparator(5);
    JCheckBox DayVisibility = createVisibilityButton("Day row visibility", 1);
    panel.add(DayVisibility);
    panel.addHeading("Day Row Format");
    String[] dayFormats = { bundle.getString("DayLongFormat"), bundle.getString("DayShortFormat"), "{0}" };
    RelativeFormatCombo dayCombo = new RelativeFormatCombo(dayRow, dayFormats);
    dayCombo.setToolTipText("Select Displayed Day Format");
    // Set the short format for the days.
    dayCombo.setSelectedIndex(1);
    panel.add(dayCombo);
    panel.addHeading("Day Row Text Alignment");
    JComboBox<String> dayAlignmentCombo = createLabelAlignmentCombo(dayRow);
    dayAlignmentCombo.setToolTipText("Select Day Text Alignment");
    panel.add(dayAlignmentCombo);

    return panel;
  }

  private JCheckBox createVisibilityButton(String label, final int index) {
    JCheckBox radioButton = new JCheckBox(label, true);
    radioButton.addItemListener(new ItemListener() {
      Override
      public void itemStateChanged(ItemEvent event) {
        boolean visible = (event.getStateChange() == ItemEvent.SELECTED);
        setRowVisibility(index, visible);
      }
    });
    return radioButton;
  }

  private JComboBox<String> createLabelAlignmentCombo(final IlvBasicTimeScaleRow row) {
    String[] alignmentNames = { "Left", "Right", "Center", "Tick" };
    final int[] alignments = { IlvBasicTimeScaleRow.LEFT, IlvBasicTimeScaleRow.RIGHT, IlvBasicTimeScaleRow.CENTER,
        IlvBasicTimeScaleRow.LEADING_TICK };
    final JComboBox<String> combo = new JComboBox<String>(alignmentNames);
    combo.addActionListener(new ActionListener() {
      Override
      public void actionPerformed(ActionEvent e) {
        int i = combo.getSelectedIndex();
        if (i < 0) {
          return;
        }
        int newAlignment = alignments[i];
        row.setTextPosition(newAlignment);
      }
    });
    combo.setSelectedIndex(0);
    return combo;
  }

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

  public ResourceBundle getBundle() {
    return bundle;
  }

  /**
   * Returns the title of the example.
   *
   * @return The title of the example.
   */
  Override
  public String getTitle() {
    return bundle.getString("Title");
  }

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

  /**
   * <code>RelativeFormatCombo</code> is a Swing combination box that allows the
   * user to select the relative row format.
   */
  class RelativeFormatCombo extends JComboBox<String> {

    // =========================================
    // Constants
    // =========================================

    /**
     * The array of format display names.
     */
    private String[] formatNames = { "Long Format", "Short Format", "None" };

    /**
     * The array of date formats.
     */
    private String[] formats;

    // The row
    private IlvRelativeTimeScaleRow row;

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

    /**
     * Creates a new <code>RelativeFormatCombo</code> that will control the
     * relative row format.
     * 
     * @param row
     *          The row.
     * @param formats
     *          The <code>String</code> formats.
     */
    public RelativeFormatCombo(IlvRelativeTimeScaleRow row, String[] formats) {
      this.row = row;
      this.formats = formats;
      for (String formatName : formatNames) {
        addItem(formatName);
      }
      addActionListener(new SelectionHandler());
    }

    // =========================================
    // Event Handlers
    // =========================================

    /**
     * <code>SelectionHandler</code> handles selection events from the
     * combination box and updates the Gantt demo with the selected date format.
     */
    class SelectionHandler implements ActionListener {
      Override
      public void actionPerformed(ActionEvent e) {
        int i = getSelectedIndex();
        if (i < 0) {
          return;
        }
        String newFormat = formats[i];
        IlvHierarchyChart chart = getChart();
        IlvTimeScale timescale = chart.getTimeScale();
        String oldFormat;
        oldFormat = row.getFormatPattern();
        if (!newFormat.equals(oldFormat)) {
          row.setFormatPattern(newFormat);
          timescale.repaint();
        }
      }
    }

  }
}