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

import ilog.cpl.IlpTable;
import ilog.cpl.model.IlpClass;

import ilog.tgo.IltSystem;
import ilog.tgo.datasource.IltDefaultDataSource;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JPanel;

import shared.AbstractSample;
import shared.ResourceUtils;

/**
 * Rogue Wave JViews TGO table sample.
 * Show instances of custom business classes.
 */
public class Main extends AbstractSample {
  public static final String sampleLoggerName = "samples.table.customClasses";

  // Store the width and height of the main frame for this sample
  public static final int sampleWidth = 750;
  public static final int sampleHeight = 200;

  public static final String sampleAlarmDataSourceFile = "alarms.xml";
  public static final String sampleServiceDataSourceFile = "services.xml";
  public static final String sampleElementDataSourceFile = "elements.xml";
  public static final String sampleUpdateAlarmDataSourceFile = "alarmsUpdate.xml";
  public static final String sampleUpdateServiceDataSourceFile = "servicesUpdate.xml";
  public static final String sampleUpdateElementDataSourceFile = "elementsUpdate.xml";

  protected IltDefaultDataSource dataSource;
  protected IlpTable tableComponent;
  protected Action updateBusinessObjectsAction;

  /**
   * Reload the business objects from the XML files.
   * This method is called from the base class when the user asks to
   * reload the business objects.
   * It clears the data source, then reloads the data file.
   */
  protected void reloadBusinessObjects() {
    dataSource.clear();
    try {
      dataSource.parse(sampleAlarmDataSourceFile);
      dataSource.parse(sampleServiceDataSourceFile);
      dataSource.parse(sampleElementDataSourceFile);
    } catch(Exception e){
      log.log(Level.SEVERE,
              "Exception caught while reloading business objects");
      e.printStackTrace();
    }
  }

  /**
   * Update the business objects using update XML files.
   * This method is called from the base class when the user asks to
   * update the business objects.
   * It doesn't clear the data source: it only loads files containing updates.
   */
  protected void updateBusinessObjects() {
    try {
      dataSource.parse(sampleUpdateAlarmDataSourceFile);
      dataSource.parse(sampleUpdateServiceDataSourceFile);
      dataSource.parse(sampleUpdateElementDataSourceFile);
    } catch (Exception exception) {
      log.log(Level.SEVERE, "Exception caught while updating business objects");
      System.err.println(exception.getMessage());
    }
  }

  /**
   * This method is called when the user asks to reload the CSS styles.
   */
  protected void reloadCSSStyles() {
    String[] css = new String[] { "table.css" };
    try {
      tableComponent.setStyleSheets(css);
    } catch (Exception e) {
      e.printStackTrace();
    }    
  }

  /**
   * Execute the main part of the sample.
   */
  protected void doSample(Container container) {
    try {
      // Initialize JTGO.
      // Read a deployment descriptor file to initialize JTGO services.
      // The deployment descriptor specifies the path to the bitmaps directory 
      // and the custom classes definition.
      if (isApplet()) {
        IltSystem.Init(this, "deploy.xml");
      } else
        IltSystem.Init("deploy.xml");

      // Initialize the context and resources
      initContext(IltSystem.GetDefaultContext());
      
      // Create a datasource
      dataSource = new IltDefaultDataSource();

      // Read multiple XML files into the datasource
      dataSource.parse(sampleAlarmDataSourceFile);
      dataSource.parse(sampleServiceDataSourceFile);
      dataSource.parse(sampleElementDataSourceFile);

      // Create a table component
      tableComponent = new IlpTable();

      // Get the Alarm class
      IlpClass acceptedClass = getContext().getClassManager().getClass("customClasses.Alarm");

      // Set the datasource to the component, and show instances of the Alarm class
      tableComponent.setDataSource(dataSource, acceptedClass);

      // Load styling information
      reloadCSSStyles();

      // Add component to the frame
      configurePanel(container,tableComponent);
    }
    catch(Exception e){
      log.log(Level.SEVERE, "Exception caught while running sample");
      e.printStackTrace();
    }
  }

  /**
   * Configures the sample panel
   */
  protected void configurePanel (Container container, final IlpTable table) {
    // Set layout
    container.setLayout(new BorderLayout());
    // Add table
    container.add(table, BorderLayout.CENTER);

    // Create an action listener to reload the business objects
    // This will invoke a virtual method to be implemented in the subclass
    updateBusinessObjectsAction = new AbstractAction(ResourceUtils.getString("action.updateObjects")){
      public void actionPerformed(ActionEvent e) {
        updateBusinessObjects();
      }
    };
    updateBusinessObjectsAction.putValue(AbstractAction.LONG_DESCRIPTION,
                                         ResourceUtils.getString("desc.updateObjects"));

    // Create a listener for a change of class
    ActionListener classChangedListener = new ActionListener(){
      public void actionPerformed(ActionEvent e) {
        // Access the combo box that contains the classes
        JComboBox combo = (JComboBox)e.getSource();
        // Get the selected class name
        String clzName = (String)combo.getSelectedItem();
        IlpClass clz = getContext().getClassManager().getClass(clzName);
        // Set the selected class as the one displayed in the table
        table.setAcceptedClass(clz);
      }
    };
    // Initialize the combo box to choose the class shown
    initClassCombo(container, classChangedListener);
  }

  /**
   * This method is called from the base class to create the menu bar.
   * Call base class version that also adds an action to reload
   * business objects
   */
  protected void populateMenuBar(JMenuBar menubar) {
    populateMenuBar(menubar, true, true);
    menubar.getMenu(0).insert(updateBusinessObjectsAction,1);
  }

  /**
   * Constructor.
   */
  public Main() {
    super(sampleLoggerName, true);
  }

  /**
   * Application entry point.
   */
  public static void main(String[] args) {
    createAndShowGUI(new Main(), sampleWidth, sampleHeight);
  }

  /**
   * Create a combo box to select the type of class shown in the table
   */
  void initClassCombo(Container container, ActionListener classChangedListener) {
    JPanel menuPanel = new JPanel(new BorderLayout());
    menuPanel.add(new JLabel(ResourceUtils.getString("label.selectClass")), BorderLayout.WEST);
    Object[] classes = {"customClasses.Alarm",
                        "customClasses.Service",
                        "customClasses.Element"};
    final JComboBox combo = new JComboBox(classes);
    combo.addActionListener(classChangedListener);
    menuPanel.add(combo, BorderLayout.CENTER);
    container.add(menuPanel, BorderLayout.NORTH);
  }
}