/*
 * Licensed Materials - Property of Rogue Wave Software, Inc. 
 * © Copyright Rogue Wave Software, Inc. 2014, 2015 
 * © 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 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;
import ilog.views.util.IlvResourceUtil;

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.JApplet;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.filechooser.FileFilter;

/**
 * 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.
 * all
 * @author ftrible
 * @since JViews 7.0
 */
public class LoadMapDemo extends JApplet {

  static {
    // This applet is designed to run only with default resource bundle
    // and various selected other resource bundles.
    // Setting the available resource suffixes avoids that the applet
    // tries to load resource bundles for other locales over the net,
    // even if the current locale of the browser is different.
    if (IlvResourceUtil.isInApplet())
      IlvResourceUtil.setAvailableResourceSuffixes("", "_ja");  //$NON-NLS-1$//$NON-NLS-2$
  }

  {
    // This sample uses JViews Maps features. When deploying an
    // application that includes this code, you need to be in possession
    // of a Rogue Wave 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() {
    this(true);
  }
  /**
   * Creates a frame containing the different map beans.
   * @param applet true if we are in an applet context.
   */
  public LoadMapDemo(final boolean applet) {
    super();
    // Make sure the swing construction is called in Swing event thread.
    ilog.views.util.swing.IlvSwingUtil.invokeAndWait(new Runnable() { 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$
    if(!applet) {
    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() {
        public boolean accept(File f) {
          return f.isDirectory() || f.getName().endsWith(".ivl"); //$NON-NLS-1$
        }

        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() {
        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() {
        public void run() {
          final JFrame frame = new JFrame();
          // Make sure the application will exit when we close its window. 
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          LoadMapDemo demo = new LoadMapDemo(false);
          frame.getContentPane().add(demo);
          frame.pack();
          frame.setVisible(true);
        }
      }
      );
  }
  //JV-3814
  Override
  public void destroy() { 
    super.destroy(); 
    // This method is intended to workaround memory management issues 
    // in the Sun JRE. Please refer to the method documentation for more 
    // details and a description of the known issues. 
    ilog.views.util.swing.IlvSwingUtil.cleanupApplet(); 
  } 
}