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

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;

import ilog.views.IlvAccelerator;
import ilog.views.IlvHandlesSelection;
import ilog.views.IlvManager;
import ilog.views.IlvManagerView;
import ilog.views.dxf.IlvDXFReader;
import ilog.views.dxf.IlvDXFReaderConfigurator;
import ilog.views.interactor.IlvSelectInteractor;
import ilog.views.interactor.IlvZoomViewInteractor;
import ilog.views.swing.IlvJManagerViewControlBar;
import ilog.views.swing.IlvJScrollManagerView;
import ilog.views.util.IlvProductUtil;

/**
 * Demonstrates the use of the DXF reader provided by Rogue Wave JViews.
 */ 
SuppressWarnings("serial")
public class IlvDXFReaderDemo
  extends JRootPane
{
  // The default background color.
  private static final Color VIEW_BACKGROUND_COLOR = Color.white;
  
  // The name of the default DXF file
  private static final String DEFAULT_FILE = "namap.dxf";
  
  // The manager view
  private IlvManagerView _mgrview;
  
  // The JFrame showing the demo.
  private JFrame _frame;
  
  // Whether the DXF file to be loaded is a file specified by the
  // user from the local disk (true) or a  predefined file provided
  // with the demo (false).
  private boolean _isExternalFile = false;
  
  // A text field to display messages
  private JTextField _msgLine = new JTextField();
  
  /**
   * Initializes the application.
   */
  public void init()
  {
    showMessage("Initialization...");
 
    // This sample uses JViews Diagrammer features. When deploying an
    // application that includes this code, you need to be in possession
    // of a Rogue Wave JViews Diagrammer Deployment license.
    IlvProductUtil.DeploymentLicenseRequired(
        IlvProductUtil.JViews_Diagrammer_Deployment);

    init(DEFAULT_FILE);
  }
  
  private void init(String fileName)
  {
    final IlvManager _manager = new IlvManager(0); // with no layer
    _mgrview = new IlvManagerView(_manager);
    
    // create the scroll manager view 
    IlvJScrollManagerView scrollManView = new IlvJScrollManagerView(_mgrview);

    // Some settings on the manager view and on the scroll manager view
    _mgrview.setAntialiasing(true);
    _mgrview.setKeepingAspectRatio(true);
    _mgrview.setBackground(VIEW_BACKGROUND_COLOR);
    _mgrview.setForeground(SystemColor.windowText);   
    Color xc = SystemColor.windowText;
    xc = new Color(255-xc.getRed(), 255-xc.getGreen(), 255-xc.getBlue());
    _mgrview.setDefaultXORColor(xc);
    _mgrview.setDefaultGhostColor(SystemColor.windowText);

    // Settings parameters for selection handles
    IlvHandlesSelection.defaultHandleColor = Color.black;
    IlvHandlesSelection.defaultHandleBackgroundColor = Color.white;
    IlvHandlesSelection.defaultHandleShape = IlvHandlesSelection.SQUARE_SHAPE;

    // create the standard control bar
    IlvJManagerViewControlBar controlBar = new IlvJManagerViewControlBar();
    controlBar.setView(_mgrview);

    // modify the interactors such that the demo looks better
    IlvSelectInteractor selInteractor =
      (IlvSelectInteractor)controlBar.getSelectInteractor();
    selInteractor.setOpaqueMove(true);
    selInteractor.setOpaqueResize(true);
    selInteractor.setOpaquePolyPointsEdition(true);
    ((IlvZoomViewInteractor)controlBar.getZoomViewInteractor()).
      setPermanent(true);
    
    // set the initial interactor
    _mgrview.setInteractor(controlBar.getSelectInteractor());

    // accelerator to allow deletion of bends and entire nodes and links
    _manager.addAccelerator(
        new IlvAccelerator(KeyEvent.KEY_PRESSED, KeyEvent.VK_DELETE, 0) {
          Override
          protected boolean handleEvent(IlvManagerView v)
          {
            _manager.deleteSelections(true, true);
            return true;
          }
    });

    // create the top panel with the toolbar and the file selector
    JPanel topPanel = new JPanel();
    topPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
    topPanel.add(controlBar);

    JButton loadButton = new JButton("Load...");
    loadButton.setToolTipText("Loads a DXF File from the Disk");
    loadButton.addActionListener(new ActionListener() {
      Override
      public void actionPerformed(ActionEvent event) {
        String externalFileName = loadFromFile();
        _isExternalFile = false;
        if (externalFileName != null) { 
          _isExternalFile = true;
          try {
            loadDXF(externalFileName, _manager);
          } catch (Throwable th) {
            th.printStackTrace();
          }
        }
      }
    });
    topPanel.add(loadButton);
    
    // create the bottom panel with the layout buttons and the message line
    JPanel bottomPanel = new JPanel();
    bottomPanel.setLayout(new BorderLayout());
    bottomPanel.add(_msgLine, BorderLayout.SOUTH);
    _msgLine.setEditable(false);

    // put manager view, top panel and bottom panel together
    getContentPane().setLayout(new BorderLayout(0, 0));
    getContentPane().add(scrollManView, BorderLayout.CENTER);
    getContentPane().add(topPanel, BorderLayout.NORTH);
    getContentPane().add(bottomPanel, BorderLayout.SOUTH);

    // load a sample DXF file
    loadDXF(fileName, _manager);
    
    // ensure the "fit" is done once the view is realized
    addComponentListener(new ComponentAdapter() {
      Override
      public void componentShown(ComponentEvent e) {
        fit();
      }
    });
  }
 
  private String loadFromFile()
  {
    // create a file dialog
    JFileChooser chooser = new JFileChooser();
    
    FileFilter filter = new FileFilter() {
      Override
      public boolean accept(File f) 
      {
        return f.isDirectory() || f.getName().toLowerCase().endsWith(".dxf");
      }
      
      Override
      public String getDescription() 
      {
        return "DXF File (*.dxf file)";
      }
    };
    chooser.setFileFilter(filter);

    int returnVal = chooser.showOpenDialog(_frame);
    if (returnVal == JFileChooser.APPROVE_OPTION)
      return chooser.getSelectedFile().toString();
    return null;
  }


  /**
   * Displays a message.
   */
  private void showMessage(String message)
  {
    // the message is displayed in the message line
    _msgLine.setText(message);
    _msgLine.paintImmediately(0, 0, _msgLine.getWidth(), _msgLine.getHeight());
  }

  // ================================================================
  
  /**
   * Reads the DXF file.
   */
  private void loadDXF(String dxffilename, 
                       IlvManager manager)
  {
    // By default, the layers defined in the DXF file are added to the 
    // layers already existing in the manager. To start from an empty
    // manager, clean the entire contents of the manager, including its layers:
    manager.deleteAll(false); // this does not remove the layers
    // Delete all layers
    while (manager.getLayersCount() > 0) 
      manager.removeLayer(0, false);

    IlvDXFReaderConfigurator configurator = new IlvDXFReaderConfigurator();
    configurator.setInvertBlackAndWhite(false);
    
    // Create an IlvDXFReader instance
    IlvDXFReader reader = new IlvDXFReader(configurator);
    InputStream stream = null;
    
    try {
      stream = 
        _isExternalFile ?
        new FileInputStream(dxffilename) :
        getClass().getResourceAsStream("/" + dxffilename);
      if (stream == null) {
        showMessage("Could not read /" + dxffilename);
        return;
      }
      reader.read(stream, manager);
    } catch (IOException ex) {
      ex.printStackTrace();
      // Just to leave the window in a clean state
      repaint();
      return;
    } finally {
      if (stream != null) {
        try {
          stream.close();
        } catch (IOException ex2) {}
      }
    }
    
    showMessage("Read file " + dxffilename + ": done.");
    fit();
  }
  
  private void fit()
  {
    if (_mgrview != null) {
      _mgrview.fitTransformerToContent();
      repaint();
    }
  }
  
  // ==============================================================
  
  /**
   * Allows you to run the demo as a standalone application.
   */
  public static void main(final String[] args)
  {
    // This sample uses JViews Diagrammer features. When deploying an
    // application that includes this code, you need to be in possession
    // of a Rogue Wave JViews Diagrammer Deployment license.
    IlvProductUtil.DeploymentLicenseRequired(
        IlvProductUtil.JViews_Diagrammer_Deployment);

    // Sun recommends that to put the entire GUI initialization into the
    // AWT thread
    SwingUtilities.invokeLater(
      new Runnable() {
        Override
        public void run() {
          final IlvDXFReaderDemo app = new IlvDXFReaderDemo();
   
          final JFrame frame = new JFrame("DXF Reader Example");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          app._frame = frame;
    
          if (args != null && args.length == 1)
            app.init(args[0]); // load the file specified in command-line
          else
            app.init(); // load the predefined file
    
          frame.getContentPane().add(app);
          frame.setSize(new Dimension(600, 600));
          frame.setVisible(true);
    
          frame.addWindowListener(new WindowAdapter() {
            Override
            public void windowOpened(WindowEvent e) {
              app.fit();
            }
          });
        }
      });
  }
}