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

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Iterator;

import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JRootPane;
import javax.swing.JTextField;

import ilog.views.diagrammer.IlvDiagrammer;
import ilog.views.graphlayout.IlvGraphLayoutException;
import ilog.views.graphlayout.hierarchical.IlvHierarchicalLayout;
import ilog.views.sdm.IlvSDMModel;
import ilog.views.sdm.model.IlvDefaultSDMModel;
import ilog.views.swing.IlvJManagerViewControlBar;
import ilog.views.util.IlvProductUtil;

/**
 * A diagrammer demo that shows how to manage a diagram without CSS.
 * 
 * @since JViews 8.5
 */
public class DiagrammerGUI extends JRootPane {

  private final static int NODE_COUNT = 15;

  /**
   * Entry point.
   * 
   * @param args
   */
  // entry point
  public static void main(final String[] args) {
    // be sure to be in EDT thread
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      Override
      public void run() {
        // A Swing Frame to display
        final JFrame frame = new JFrame("Random Diagram");
        new DiagrammerGUI().init(frame.getContentPane());
        // and show it.
        frame.setSize(450, 450);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
      }
    });
  }

  public void init(Container container) {
    // This sample uses JViews Diagrammer features. When deploying an
    // application that includes this code, you need to be in possession
    // of a Perforce JViews Diagrammer Deployment license.
    IlvProductUtil.DeploymentLicenseRequired(IlvProductUtil.JViews_Diagrammer_Deployment);

    // Create the diagrammer component
    final IlvDiagrammer diagrammer = new IlvDiagrammer();

    // Customize diagrammer behavior.
    diagrammer.setSelectMode(true);
    diagrammer.setScrollable(false);
    diagrammer.setEditingAllowed(false);
    diagrammer.getView().setBackground(Color.white);
    diagrammer.getView().setForeground(SystemColor.windowText);

    // populate diagrammer model
    diagrammer.getEngine().setModel(createModel(), false);
    // add our custom renderer
    diagrammer.getEngine().setRenderer(new SimpleDiagrammerRenderer());

    // apply a node layout
    IlvHierarchicalLayout layout = new IlvHierarchicalLayout();
    layout.setBacktrackCrossingReductionEnabled(true);
    layout.setGlobalLinkStyle(IlvHierarchicalLayout.ORTHOGONAL_STYLE);
    layout.attach(diagrammer.getEngine().getGrapher());
    try {
      layout.performLayout();
    } catch (IlvGraphLayoutException e1) {
      e1.printStackTrace();
    }

    // fit to content when view is ready
    diagrammer.getView().fitTransformerToContent(true);

    // select first object
    Object node1 = diagrammer.getObject("pebble1");
    diagrammer.setSelected(node1, true);

    // Create a control bar
    IlvJManagerViewControlBar controlBar = new IlvJManagerViewControlBar();
    controlBar.setView(diagrammer.getView());
    // as we configured diagrammer selectInteractor, be sure it's the same in
    // the toolbar.
    controlBar.setSelectInteractor(diagrammer.getSelectInteractor());
    container.add(controlBar, BorderLayout.NORTH);

    // Put the manager view inside the Swing Frame
    container.add(diagrammer, BorderLayout.CENTER);

    // add the texfield below to change node color
    Box box = Box.createHorizontalBox();
    box.add(new JLabel("Enter color for selected node(s): "));
    final JTextField colorTextField = new JTextField("orange");
    box.add(colorTextField);
    container.add(box, BorderLayout.SOUTH);

    // add textfield callback that modifies the model
    colorTextField.addActionListener(new ActionListener() {
      Override
      public void actionPerformed(ActionEvent e) {
        // get current text
        String text = colorTextField.getText();
        // set new color name to all selected objects
        Iterator<?> it = diagrammer.getSelectedObjects();
        while (it.hasNext()) {
          diagrammer.getEngine().getModel().setObjectProperty(it.next(), "color", text);
        }
      }
    });
  }

  /**
   * Creates a random model.
   */
  private IlvSDMModel createModel() {
    IlvDefaultSDMModel result = new IlvDefaultSDMModel();

    // let's create plenty of objects
    float pos = Float.valueOf(100);
    Object[] array = new Object[NODE_COUNT];
    for (int i = 0; i < array.length; i++) {
      Object n = result.createNode("pebble");
      result.setObjectProperty(n, "x", pos);
      result.setObjectProperty(n, "y", pos);
      result.setObjectProperty(n, "color", makeRandomColor());
      result.addObject(n, null, null);
      array[i] = n;
    }
    // set an ID for the first object
    result.setID(array[0], "pebble1");
    // now some random links
    for (int i = 0; i < array.length * 1.5; i++) {
      Object link = result.createLink("distance");
      result.setFrom(link, array[(int) (array.length * Math.random())]);
      result.setTo(link, array[(int) (array.length * Math.random())]);
      result.addObject(link, null, null);
    }
    return result;
  }

  /**
   * Returns a random color string.
   * 
   */
  private String makeRandomColor() {
    final String[] colorTable = { "tan", "peachpuff", "lightcoral", "lavender", "lightseagreen", "powderblue", "plum",
        "lightpink", "lightsteelblue", "lightgoldenrodyellow" };
    return colorTable[(int) (Math.random() * colorTable.length)];
  }

}