/*
 * 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.
 */
package datasource.explorer;

import java.awt.BorderLayout;
import java.awt.Container;
import java.util.logging.Level;

import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreeSelectionModel;

import ilog.cpl.IlpSystem;
import ilog.cpl.IlpTable;
import ilog.cpl.IlpTree;
import ilog.cpl.datasource.structure.IlpContainer;
import ilog.cpl.model.IlpObject;
import ilog.cpl.util.IlpAttributeComparator;
import ilog.cpl.util.selection.IlpObjectSelectionModel;
import shared.AbstractSample;

/**
 * JTGO data source explorer sample. See
 * <A href="../../../index.html">index.html</A> for a description of this
 * sample.
 */
public class Main extends AbstractSample {
  // Store the name of this sample
  public static final String sampleLoggerName = "samples.datasource.explorer";
  public static final int sampleWidth = 550;
  public static final int sampleHeight = 400;

  JPanel treeArea;
  JPanel tableArea;

  IlpTree treeComponent;
  IlpTable tableComponent;
  FileDataSource dataSource;

  /**
   * Execute the main part of the sample.
   */
  Override
  protected void doSample(Container container) {
    try {
      // Initialize JTGO
      // Read a deployment descriptor file to initialize JTGO services
      IlpSystem.Init("deploy.xml");

      // Initialize the context and resources
      initContext(IlpSystem.GetDefaultContext());

      // Initialize some sub-frames in the main panel
      initGUI(container);

      // Create a datasource
      dataSource = new FileDataSource();

      // Create a tree component
      treeComponent = new IlpTree();

      // Load tree configuration
      try {
        treeComponent.setStyleSheets(new String[] { "tree.css" });
      } catch (Exception e) {
        e.printStackTrace();
      }

      // Create a comparator to sort all the nodes in the tree
      // Use the predefined class IlpAttributeComparator to sort
      // The first sort parameter is directory, so directories appears before
      // files
      // then the 'name' attribute
      // then the 'path' attribute, as name is is sometimes null (for roots)
      IlpAttributeComparator sorter = new IlpAttributeComparator(dataSource.fileClass.getAttribute("directory"), false);
      sorter.setDirectionAndOrder(dataSource.fileClass.getAttribute("name"), 2, true);
      sorter.setDirectionAndOrder(dataSource.fileClass.getAttribute("path"), 3, true);

      // Set the sorter to the tree component
      treeComponent.setSortComparator(sorter);

      // Set the datasource to the component
      treeComponent.setDataSource(dataSource);

      // Add the tree component to the frame
      treeArea.add(treeComponent);

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

      // Load table configuration
      try {
        tableComponent.setStyleSheets(new String[] { "table.css" });
      } catch (Exception e) {
        e.printStackTrace();
      }

      // Connect it to the data source, and show only instances of the
      // specified class
      tableComponent.setDataSource(dataSource, dataSource.fileClass);

      // Filter the contents to show only what is displayed in the network
      // At startup, there is no origin so the table shows only root objects
      tableComponent.setFilter(new OriginFilter(dataSource, null, false));

      // We must change the filter whenever a drill down occurs,
      // so that the contents of the table will be updated
      TreeSelectionModel treeSelectionModel = treeComponent.getSelectionModel();
      treeSelectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
      treeSelectionModel.addTreeSelectionListener(new TreeSelectionListener() {
        Override
        public void valueChanged(TreeSelectionEvent e) {
          IlpObjectSelectionModel selectionModel = (IlpObjectSelectionModel) e.getSource();
          IlpObject selectedObject = selectionModel.getSelectedObject();
          // force loading of the children
          IlpContainer containerInterface = dataSource.getContainerInterface(selectedObject);
          if (containerInterface != null) {
            containerInterface.getChildren(selectedObject);
          }
          tableComponent.setFilter(new OriginFilter(dataSource, selectedObject, false));
        }
      });

      tableArea.add(tableComponent);
    } catch (Exception e) {
      log.log(Level.SEVERE, "Exception caught while running sample");
      e.printStackTrace();
    }
  }

  /**
   * Constructor. Create sample with only a menubar.
   */
  public Main() {
    super(sampleLoggerName, true);
  }

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

  /**
   * Create a number of sub-frames, separated by splitters.
   */
  public void initGUI(Container container) {
    container.setLayout(new BorderLayout());

    // Create panels for the JTGO graphic components
    treeArea = new JPanel(new BorderLayout());
    tableArea = new JPanel(new BorderLayout());

    // Split the main frame into two areas, one for the tree, and one to be
    // shared by the network and the equipment component with their associated
    // tables
    JSplitPane rootSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, treeArea, tableArea);
    rootSplitPane.setDividerLocation(150);
    rootSplitPane.setOneTouchExpandable(true);

    // Add divided frames to main panel
    container.add(rootSplitPane, BorderLayout.CENTER);
  }

}