/*
 * 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 java.awt.BorderLayout;
import java.awt.Container;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;

import ilog.views.chart.IlvChart;
import ilog.views.chart.data.IlvSwingTableDataSource;
import ilog.views.chart.renderer.IlvPolylineChartRenderer;
import ilog.views.util.IlvProductUtil;

/**
 * This sample shows how to bind a <code>javax.swing.TableModel</code> to a
 * chart data source.
 */
public class TableModelConnection extends JFrame {
  /** The table data source referencing the table model. */
  IlvSwingTableDataSource tableDs;

  public TableModelConnection() {
    super("Connection to Swing TableModel");
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    init();
  }

  /**
   * Initializes a new <code>TableModelConnection</code> object.
   **/
  public void init() {
    Container container = getContentPane();
    // Create the chart.
    IlvChart chart = createChart();

    // Create the swing TableModel containing the data.
    AbstractTableModel swingModel;
    try {
      swingModel = createSwingTableModel();
    } catch (ParseException e) {
      swingModel = new DefaultTableModel();
    } catch (NumberFormatException e) {
      swingModel = new DefaultTableModel();
    }

    // Bind an IlvSwingTableDataSource to this swing table model. The series
    // being arranged by column, the data source is of type COLUMN_SERIES.
    // Since a specific column is used for the abscissa (the Year column) for
    // all the series, the index in the table model of the year column
    // is also specified (0).
    IlvSwingTableDataSource tableDs = new IlvSwingTableDataSource(swingModel, IlvSwingTableDataSource.COLUMN_SERIES, 0, // the
                                                                                                                        // column
                                                                                                                        // index
                                                                                                                        // for
                                                                                                                        // the
                                                                                                                        // x-values
        -1); // no datalabels
    // At this time, the data sets corresponding to the table model series
    // have been created.

    // Connect the data source to a polyline chart renderer.
    // The IlvPolylineChartRenderer will create a renderer for each data set
    // of its data source and hold them in an internal list. These sub-
    // renderers are called child renderers and can be parsed using an
    // Iterator (see below).
    IlvPolylineChartRenderer r = new IlvPolylineChartRenderer();
    r.setDataSource(tableDs);
    chart.addRenderer(r);

    container.setLayout(new BorderLayout());
    container.add(chart, BorderLayout.CENTER);
    setSize(500, 440);
  }

  /**
   * Returns an initialized <code>IlvChart</code>.
   */
  protected IlvChart createChart() {
    IlvChart chart = new IlvChart();
    chart.setAntiAliasing(true);
    chart.setBorder(BorderFactory.createEtchedBorder());
    // The x series being years, set the scale as TIME_SCALE.
    chart.getXScale().setTimeUnit(null);
    // Avoid having overlapping labels.
    chart.getXScale().setSkippingLabel(true);
    return chart;
  }

  /**
   * Returns a swing table model filled with the data to bind. The series should
   * be ordered by column, the x series being the first one (index 0).
   */
  protected AbstractTableModel createSwingTableModel() throws ParseException, NumberFormatException {
    String[] names = { "Year", "Air", "Oil Pipeline" };
    SimpleDateFormat format = new SimpleDateFormat("yyyy");
    Object[][] data = { { format.parse("1960"), Double.valueOf(553), Double.valueOf(233000) },
        { format.parse("1965"), Double.valueOf(1353), Double.valueOf(306393) },
        { format.parse("1970"), Double.valueOf(2189), Double.valueOf(431000) },
        { format.parse("1975"), Double.valueOf(3470), Double.valueOf(507000) },
        { format.parse("1980"), Double.valueOf(4528), Double.valueOf(588200) },
        { format.parse("1985"), Double.valueOf(5156), Double.valueOf(564300) },
        { format.parse("1990"), Double.valueOf(9064), Double.valueOf(584100) },
        { format.parse("1991"), Double.valueOf(8858), Double.valueOf(578500) },
        { format.parse("1992"), Double.valueOf(9820), Double.valueOf(588800) },
        { format.parse("1993"), Double.valueOf(10675), Double.valueOf(592900) },
        { format.parse("1994"), Double.valueOf(11688), Double.valueOf(608000) } };

    DefaultTableModel model = new DefaultTableModel(data, names) {
      // The getColumnClass should be overridden to specify the type
      // of our data. Since a data set only contains double values,
      // this method is used by the IlvSwingTableDataSource to
      // find the right converter to use to convert data of a given
      // column into a <code>double</code> value. By default, converters
      // exist for Date and Double. You can specify your own converter
      // by subclassing <code>IlvDataConverter</code> and registering
      // it invoking IlvSwingTableDataSource.setDefaultConverter().
      Override
      public Class<?> getColumnClass(int col) {
        return (col == 0) ? Date.class : Double.class;
      }
    };
    return model;
  }

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

    SwingUtilities.invokeLater(new Runnable() {
      Override
      public void run() {
        TableModelConnection frame = new TableModelConnection();
        frame.setVisible(true);
      }
    });
  }

}