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

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.net.URL;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JRootPane;
import javax.swing.filechooser.FileFilter;

import ilog.views.IlvManagerView;
import ilog.views.maps.IlvCoordinateSystemProperty;
import ilog.views.maps.IlvMapInputStream;
import ilog.views.maps.beans.IlvJMapsManagerViewControlBar;
import ilog.views.maps.beans.IlvJMouseCoordinateViewer;
import ilog.views.maps.beans.IlvMapLegend;
import ilog.views.maps.format.IlvDefaultDataPathResolver;
import ilog.views.maps.format.IlvMapDataPathManager;
import ilog.views.maps.graphic.IlvMapSelectionFactory;
import ilog.views.maps.srs.coordsys.IlvGeographicCoordinateSystem;
import ilog.views.swing.IlvJScrollManagerView;
import ilog.views.util.IlvProductUtil;

/**
 * This sample is a very simple mapping application that displays a "read only"
 * map stored in an IVL file. Such a file can be built either using the "Map
 * Builder" or the map building JViews 7.0 API.
 * 
 * @proofreadall
 * @author ftrible
 * @since JViews 7.0
 */
SuppressWarnings("serial")
public class LoadMapDemo extends JRootPane {

  static {
    // This sample uses JViews Maps features. When deploying an
    // application that includes this code, you need to be in possession
    // of a Perforce JViews Maps Deployment license.
    IlvProductUtil.DeploymentLicenseRequired(IlvProductUtil.JViews_Maps_Deployment);
  }

  // main map view
  IlvManagerView view = new IlvManagerView();
  // scroll around the map view
  IlvJScrollManagerView viewScroll = new IlvJScrollManagerView(view);
  // zoom & selection toolbar
  IlvJMapsManagerViewControlBar viewToolbar = new IlvJMapsManagerViewControlBar();
  // mouse coordinate information bean
  IlvJMouseCoordinateViewer locator = new IlvJMouseCoordinateViewer();
  // Map legend bean
  IlvMapLegend legend = new IlvMapLegend();

  /**
   * Creates a frame containing the different map beans.
   */
  public LoadMapDemo() {
    super();
    // Make sure the swing construction is called in Swing event thread.
    ilog.views.util.swing.IlvSwingUtil.invokeAndWait(new Runnable() {
      Override
      public void run() {

        // Setup the beans
        viewToolbar.setView(view);
        locator.setView(view);
        legend.setView(view);

        view.setSize(new Dimension(900, 450));
        view.setKeepingAspectRatio(true);
        viewScroll.setPreferredSize(view.getSize());
        // geo reference the view
        view.getManager().setNamedProperty(new IlvCoordinateSystemProperty(IlvGeographicCoordinateSystem.WGS84));
        // limit the zoom to correct scales.
        // IlvMapScaleLimiter limiter = new IlvMapScaleLimiter((float) (1 /
        // 1E7), (float) (1 / 1E9));
        // limiter.setView(view);

        // arrange the main window
        getContentPane().add(viewToolbar, BorderLayout.NORTH);
        getContentPane().add(viewScroll, BorderLayout.CENTER);
        getContentPane().add(locator, BorderLayout.SOUTH);
        getContentPane().add(legend, BorderLayout.LINE_START);
        /* to load the initial file */
        loadFile("/data/county.ivl"); //$NON-NLS-1$
        try {
          /* --- Load map GUI --- */
          // Create a "load" button.
          JButton loadFileButton = new JButton("Load..."); //$NON-NLS-1$
          // Create a File chooser to select a file
          final JFileChooser fc = new JFileChooser("./data"); //$NON-NLS-1$
          // setup the file chooser to display only "*.ivl" files.
          fc.setFileFilter(new FileFilter() {
            Override
            public boolean accept(File f) {
              return f.isDirectory() || f.getName().endsWith(".ivl"); //$NON-NLS-1$
            }

            Override
            public String getDescription() {
              return "JViews Files (*.ivl)"; //$NON-NLS-1$
            }

          });
          fc.setAcceptAllFileFilterUsed(false);
          // This button will display an ".ivl" file selection box.
          loadFileButton.addActionListener(new ActionListener() {
            Override
            public void actionPerformed(ActionEvent e) {
              // show the file dialog
              if (fc.showOpenDialog(LoadMapDemo.this) == JFileChooser.APPROVE_OPTION) {
                // Load the ivl file
                loadFile(fc.getSelectedFile().getPath());
              }
            }
          });
          // add the load button to the
          viewToolbar.add(loadFileButton);
          /* --- End of Load map GUI --- */

        } catch (SecurityException e) {
          // applet => No fileselector
        }
        
      }
    });// event thread runnable
  }

  // manage relative file names (if any)
  IlvDefaultDataPathResolver dpr = null;

  /**
   * Load a file into the view's manager.
   * 
   * @param ivlFile
   *          prebuilt file to read.
   */
  public void loadFile(String ivlFile) {
    try {
      URL url = findURL(ivlFile);
      if (url == null) {
        return;
      }
      // open input stream
      String ivlFilename = url.toExternalForm();
      IlvMapInputStream mapInput = new IlvMapInputStream(ivlFilename);
      // Clear current manager
      view.getManager().deleteAll(false);

      try {
        File f = new File(url.toURI());
        // remove previous path resolver
        if (dpr != null) {
          IlvMapDataPathManager.RemoveDataPathResolver(dpr);
        }
        dpr = new IlvDefaultDataPathResolver(f.getParent());
        IlvMapDataPathManager.AddDataPathResolver(dpr);
      } catch (Exception e) {
        // impossible to transform into a file.
      }
      // Load the map
      mapInput.read(view.getManager());
      // JV-4075, prevent from being able to resize countries around.
      view.getManager().setSelectionFactory(new IlvMapSelectionFactory());
      // fit the view to its new content
      view.fitTransformerToContent();
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  private static URL findURL(String resource) {
    URL rtnURL = null;
    boolean exists = false;
    try {
      exists = new File(resource).exists();
    } catch (SecurityException e) {
      // applet
    }
    if (exists) {
      try {
        rtnURL = new File(resource).toURI().toURL();
      } catch (Exception e) {
        e.printStackTrace();
      }
    } else {
      rtnURL = LoadMapDemo.class.getResource(resource);
    }
    return rtnURL;
  }

  /**
   * Main method
   * 
   * @param args
   *          (ignored)
   */
  public static void main(String[] args) {
    // Sun recommends that to put the entire GUI initialization into the
    // AWT thread
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      Override
      public void run() {
        final JFrame frame = new JFrame("Load Map sample");
        // Make sure the application will exit when we close its window.
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        LoadMapDemo demo = new LoadMapDemo();
        frame.getContentPane().add(demo);
        frame.pack();
        frame.setVisible(true);
      }
    });
  }

}