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

/**
 * This examples shows a number of diagrams to illustrate some typical
 * uses of Perforce JViews Diagrammer.
 */
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;
import java.util.StringTokenizer;

import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextField;

import ilog.views.diagrammer.IlvDiagrammer;
import ilog.views.diagrammer.application.IlvDiagrammerAction;
import ilog.views.diagrammer.application.IlvDiagrammerFrame;
import ilog.views.diagrammer.application.IlvDiagrammerMenu;
import ilog.views.diagrammer.application.IlvDiagrammerMenuBar;
import ilog.views.diagrammer.project.IlvDiagrammerProject;
import ilog.views.sdm.renderer.IlvRendererUtil;
import ilog.views.util.IlvProductUtil;
import ilog.views.util.swing.IlvJStreamTextArea;

public class DiagramGallery extends IlvDiagrammerFrame {
  private ResourceBundle bundle;
  IlvDiagrammerProject[] diagrams;
  private JComboBox<IlvDiagrammerProject> combo;
  private JTextField descriptionField;
  private JFrame messageWindow;
  private IlvJStreamTextArea messageArea;

  public static void main(final String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      Override
      public void run() {
        new DiagramGallery().init(args);
      }
    });
  }

  public DiagramGallery() {
    super(new String[] { "-simple" });
  }

  /**
   * This method is overridden to change the size of the frame.
   */
  Override
  public void initFrame() {
    super.initFrame();
    setSize(800, 400);
  }

  /**
   * Initializes the GUI.
   * 
   * @param contentPane
   *          The container of the application.
   */
  Override
  public void init(Container contentPane) {
    // 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);

    bundle = ResourceBundle.getBundle("gallery");

    diagrams = readDiagrams();
    descriptionField = new JTextField();

    super.init(contentPane);

    // Create the combo box that lets the user choose a diagram.
    //
    JPanel topPanel = new JPanel(new GridBagLayout());
    contentPane.add(topPanel, BorderLayout.NORTH);

    GridBagConstraints c = new GridBagConstraints();
    c.gridy = 0;
    c.insets = new Insets(5, 5, 5, 5);
    c.weightx = 0;
    c.fill = GridBagConstraints.NONE;

    JLabel label = new JLabel(bundle.getString("DiagramGallery.ChooseDiagram"));
    c.gridx = 0;
    topPanel.add(label, c);

    combo = new JComboBox<IlvDiagrammerProject>(diagrams);
    combo.setRenderer(new DefaultListCellRenderer() {
      Override
      public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected,
          boolean cellHasFocus) {
        JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        label.setText(getProperty((IlvDiagrammerProject) value, "ShortDescription"));
        return label;
      }
    });
    combo.addItemListener(new ItemListener() {
      Override
      public void itemStateChanged(ItemEvent e) {
        if (e.getStateChange() == ItemEvent.SELECTED) {
          loadDiagram((IlvDiagrammerProject) combo.getSelectedItem());
        }
      }
    });
    c.gridx = 1;
    topPanel.add(combo, c);

    descriptionField.setEditable(false);
    c.weightx = 1;
    c.gridx = 2;
    c.fill = GridBagConstraints.HORIZONTAL;
    topPanel.add(descriptionField, c);

    // create a message window
    messageArea = new IlvJStreamTextArea();
    messageWindow = new JFrame();
    messageWindow.getContentPane().add(messageArea);
    messageWindow.pack();
    messageWindow.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);

    // enhance the file menu with the tracing facility
    IlvDiagrammerMenuBar menuBar = (IlvDiagrammerMenuBar) getJMenuBar();
    IlvDiagrammerMenu fileMenu = menuBar.getFileMenu();
    final IlvDiagrammerAction.ToggleAction traceAction = new IlvDiagrammerAction.ToggleAction(
        "DiagramGallery.EnableTracing", bundle) {

      Override
      protected boolean isEnabled(IlvDiagrammer diagrammer) throws Exception {
        return true;
      }

      Override
      protected boolean isSelected(IlvDiagrammer diagrammer) throws Exception {
        return IlvRendererUtil.isTracingEnabled();
      }

      Override
      protected void setSelected(IlvDiagrammer diagrammer, boolean selected) throws Exception {
        if (selected) {
          // enable tracing for various rendering methods.
          // Nearly all methods of IlvSDMRenderer can be traced.
          messageWindow.setVisible(true);
          IlvRendererUtil.setTraceStream(messageArea.getPrintStream());
          // to trace ALL methods:
          // IlvRendererUtil.setTracingEnabled(true);
          // to trace specific methods:
          IlvRendererUtil.setTracingEnabled("renderingDone", "createNodeGraphic", "createLinkGraphic");
          // Can restrict tracing to certain renderers:
          // IlvRendererUtil.setTraceRenderers("GraphLayout", "LinkLayout");
          diagrammer.refresh();
        } else {
          if (IlvRendererUtil.isTracingEnabled()) {
            // disable tracing
            IlvRendererUtil.setTracingEnabled(false);
            diagrammer.refresh();
            messageWindow.setVisible(false);
          }
        }
      }
    };
    fileMenu.insertAction(traceAction, 1);

    messageWindow.addWindowListener(new WindowAdapter() {
      Override
      public void windowClosing(WindowEvent e) {
        if (IlvRendererUtil.isTracingEnabled()) {
          try {
            traceAction.perform(null, getCurrentDiagrammer());
          } catch (Exception ex) {
          }
        }
      }
    });
  }

  /**
   * Loads the first diagram.
   */
  Override
  protected void ready() {
    super.ready();
    loadDiagram(diagrams[0]);
  }

  /**
   * Loads a diagram.
   * 
   * @param project
   *          The diagram project to load.
   */
  private void loadDiagram(IlvDiagrammerProject project) {
    try {
      getCurrentDiagrammer().setProject(project);
      if (project.getProjectURL().toString().contains("classdiag"))
        getCurrentDiagrammer().resetZoom();
      else
        getCurrentDiagrammer().fitToContents();
      descriptionField.setText(getProperty(project, "LongDescription"));
    } catch (Exception e1) {
      IlvDiagrammerAction.error(getApplicationContentPane(), bundle, "DiagramGallery.ErrorWhileLoadingProject",
          new Object[] { project.getProjectURL() }, e1);
    }
  }

  /**
   * Reads the list of diagrams from the property file.
   */
  private IlvDiagrammerProject[] readDiagrams() {
    ArrayList<IlvDiagrammerProject> l = new ArrayList<IlvDiagrammerProject>();
    try {
      URL documentBase = new URL("file:./");
      String list = bundle.getString("DiagramGallery.DiagramList");
      StringTokenizer tok = new StringTokenizer(list, " ,");
      while (tok.hasMoreTokens()) {
        String name = tok.nextToken();
        IlvDiagrammerProject project = new IlvDiagrammerProject(new URL(documentBase, "data/" + name + ".idpr"));
        l.add(project);
      }
    } catch (Exception ex) {
      IlvDiagrammerAction.error(getApplicationContentPane(), bundle, "DiagramGallery.ErrorWhileListingProjects", null,
          ex);
    }
    return (IlvDiagrammerProject[]) l.toArray(new IlvDiagrammerProject[0]);
  }

  private String getProperty(IlvDiagrammerProject project, String property) {
    String key = project.getProjectURL().toExternalForm();
    key = key.substring(key.lastIndexOf('/') + 1);
    key = key.substring(0, key.lastIndexOf('.'));
    return bundle.getString("DiagramGallery." + key + "." + property);
  }
}