/*
 * 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.
 */

import ilog.views.gantt.IlvGanttChart;
import ilog.views.gantt.IlvGanttModel;
import ilog.views.gantt.IlvHierarchyChart;
import ilog.views.gantt.model.IlvDefaultGanttModel;
import ilog.views.gantt.scale.*;
import ilog.views.util.IlvProductUtil;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.util.Calendar;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


/**
 * Simple Gantt Example sample.
 */
public class CustomVisibilityGantt extends JPanel {

  public IlvHierarchyChart chart;

  public CustomVisibilityGantt(JFrame frame) {
    // Prepare the JPanel's appearance
    setLayout(new BorderLayout());

    IlvGanttChart chart = new IlvGanttChart();

    // Create a new time scale with adjustable visibility
    IlvTimeScale timescale = createAdjustableTimeScale();
    chart.setTimeScale(timescale);

    // Bind the Gantt Chart to the Data Model
    IlvGanttModel model = new IlvDefaultGanttModel();
    chart.setGanttModel(model);

    add(BorderLayout.CENTER, chart);
  }

  /**
   * Creates an adjustable timescale which is controlled by a
   * visibility policy deciding on the number of visible rows based
   * on the zoom level.
   */
  private IlvTimeScale createAdjustableTimeScale() {
    // 1. Create the timescale.

    IlvTimeScale timescale = new IlvTimeScale();

    // 2. Create the needed rows.

    // A customized quarter row
    IlvQuarterTimeScaleRow quarterRow = new IlvQuarterTimeScaleRow();
    quarterRow.setTextColor(new Color( 50, 205, 50));
    quarterRow.setTextFont(new Font("default", Font.PLAIN, 14));
    quarterRow.setTextPosition(IlvBasicTimeScaleRow.CENTER);

    // A customized month row
    IlvMonthTimeScaleRow monthRow = new IlvMonthTimeScaleRow();
    monthRow.setTextColor(Color.blue);
    monthRow.setTextFont(new Font("Serif", Font.ITALIC, 16));
    monthRow.setFormatString("MMMM");
    monthRow.setTextPosition(IlvBasicTimeScaleRow.CENTER);

    // A customized day row
    IlvDayTimeScaleRow dayRow = new IlvDayTimeScaleRow();
    dayRow.setTextColor(new Color(72, 209, 204));
    dayRow.setTextFont(new Font("SansSerif", Font.BOLD, 18));

    // A customized half day row.
    IlvHalfDayTimeScaleRow halfDayRow = new IlvHalfDayTimeScaleRow();
    halfDayRow.setTextColor(Color.red);
    halfDayRow.setTextFont(new Font("Monospaced", Font.PLAIN, 14));

    // 3. Add the rows to the time scale

    timescale.addRow(quarterRow);
    timescale.addRow(monthRow);
    timescale.addRow(dayRow);
    timescale.addRow(halfDayRow);

    // 4. Create the visibility policy

    IlvBasicTimeScaleVisibilityPolicy visibilityPolicy =
        new IlvBasicTimeScaleVisibilityPolicy();

    // 5. Create the list of visibility conditions. Each visibility
    //    condition is characterized by a predicate and the list of visible
    //    rows when this predicate is true.

    // First visibility condition is to have the 4 rows visible when at
    // least 4 characters can be seen for the month.
    // Create the predicate
    IlvTimeWidthVisibilityPredicate cond1 =
        new IlvTimeWidthVisibilityPredicate(
            Calendar.DAY_OF_MONTH,
            IlvTimeWidthVisibilityPredicate.CHARACTER,
            4);
    cond1.setFont(new Font("SansSerif", Font.BOLD, 18));
    // Create the first visibility condition with the predicate
    IlvVisibleTimeScaleRows visCond1 = new IlvVisibleTimeScaleRows(cond1);
    // Add the visible rows.
    visCond1.addRow(quarterRow);
    visCond1.addRow(monthRow);
    visCond1.addRow(dayRow);
    visCond1.addRow(halfDayRow);

    // Second visibility condition is to have the quarter, month and day
    // rows visible when at least 3 characters can be seen for the day.
    // Create the predicate
    IlvTimeWidthVisibilityPredicate cond2 =
        new IlvTimeWidthVisibilityPredicate(
            Calendar.DAY_OF_MONTH,
            IlvTimeWidthVisibilityPredicate.CHARACTER,
            3);
    // Create the second visibility condition with the predicate
    IlvVisibleTimeScaleRows visCond2 = new IlvVisibleTimeScaleRows(cond2);
    // Add the visible rows.
    visCond2.addRow(quarterRow);
    visCond2.addRow(monthRow);
    visCond2.addRow(dayRow);

    // Third visibility condition is to have the quarter, month and a
    // short day rows visible when at least 1 character can be seen for
    // the day.
    // Create the predicate
    IlvTimeWidthVisibilityPredicate cond3 =
        new IlvTimeWidthVisibilityPredicate(
            Calendar.DAY_OF_MONTH,
            IlvTimeWidthVisibilityPredicate.CHARACTER,
            1);
    // Create the third visibility condition with the predicate
    IlvVisibleTimeScaleRows visCond3 = new IlvVisibleTimeScaleRows(cond3);
    // Create a short day row
    IlvDayTimeScaleRow shortDayRow = new IlvDayTimeScaleRow();
    shortDayRow.setTextColor(Color.cyan);
    shortDayRow.setTextFont(new Font("SansSerif", Font.BOLD, 18));
    shortDayRow.setFormatString("dd");
    // Add the visible rows.
    visCond3.addRow(quarterRow);
    visCond3.addRow(monthRow);
    visCond3.addRow(shortDayRow);

    // Fourth visibility condition is to have the quarter and month
    // rows visible when at least 4 characters can be seen for
    // the month.
    // Create the predicate
    IlvTimeWidthVisibilityPredicate cond4 =
        new IlvTimeWidthVisibilityPredicate(
            Calendar.MONTH,
            IlvTimeWidthVisibilityPredicate.CHARACTER,
            4);
    cond4.setFont(new Font("Serif", Font.ITALIC, 16));
    // Create the fourth visibility condition with the predicate
    IlvVisibleTimeScaleRows visCond4 = new IlvVisibleTimeScaleRows(cond4);
    // Add the visible rows.
    visCond4.addRow(quarterRow);
    visCond4.addRow(monthRow);

    // Fifth visibility condition is to have the quarter and a short
    // month rows visible when at least 1 character can be seen for
    // the month.
    // Create the predicate
    IlvTimeWidthVisibilityPredicate cond5 =
        new IlvTimeWidthVisibilityPredicate(
            Calendar.MONTH,
            IlvTimeWidthVisibilityPredicate.CHARACTER,
            1);
    cond5.setFont(new Font("Serif", Font.ITALIC, 16));
    // Create the fifth visibility condition with the predicate
    IlvVisibleTimeScaleRows visCond5 = new IlvVisibleTimeScaleRows(cond5);
    // Create a short month row
    IlvMonthTimeScaleRow shortMonthRow = new IlvMonthTimeScaleRow();
    shortMonthRow.setTextColor(Color.blue);
    shortMonthRow.setTextFont(new Font("Serif", Font.ITALIC, 16));
    shortMonthRow.setFormatString("MM");
    // Add the visible rows.
    visCond5.addRow(quarterRow);
    visCond5.addRow(shortMonthRow);

    // 6. Add these visibility conditions to the visibility policy
    visibilityPolicy.addVisibleTimeScaleRows(visCond1);
    visibilityPolicy.addVisibleTimeScaleRows(visCond2);
    visibilityPolicy.addVisibleTimeScaleRows(visCond3);
    visibilityPolicy.addVisibleTimeScaleRows(visCond4);
    visibilityPolicy.addVisibleTimeScaleRows(visCond5);

    // 7. Set the visibility on the time scale
    timescale.setVisibilityPolicy(visibilityPolicy);

    return timescale;
  }

  public static void main(String[] args) {
    // This sample uses JViews Gantt features. When deploying an
    // application that includes this code, you need to be in possession
    // of a Perforce JViews Gantt Deployment license.
    IlvProductUtil.DeploymentLicenseRequired(
        IlvProductUtil.JViews_Gantt_Deployment);

    SwingUtilities.invokeLater(new Runnable() {
      Override
      public void run() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(10, 400, 700, 400);
        CustomVisibilityGantt example = new CustomVisibilityGantt(frame);
        frame.getContentPane().add(example);
        frame.setVisible(true);
      }
    });
  }

}