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

package main;

import ilog.views.IlvGrapher;
import ilog.views.IlvManagerView;
import ilog.views.IlvPoint;
import ilog.views.IlvTransformer;
import ilog.views.maps.IlvCoordinate;
import ilog.views.maps.IlvCoordinateSystemProperty;
import ilog.views.maps.IlvMapLayerTreeProperty;
import ilog.views.maps.IlvMapScaleLimiter;
import ilog.views.maps.IlvMapUtil;
import ilog.views.maps.IlvSDMHierarchyExpandManager;
import ilog.views.maps.beans.IlvJAdvancedZoomControl;
import ilog.views.maps.beans.IlvJMapScaleControl;
import ilog.views.maps.beans.IlvJMapsManagerViewControlBar;
import ilog.views.maps.beans.IlvJMouseCoordinateViewer;
import ilog.views.maps.beans.IlvMapLayerTreeModel;
import ilog.views.maps.datasource.IlvMapDataSourceModel;
import ilog.views.maps.datasource.IlvMapDataSourceProperty;
import ilog.views.maps.datasource.IlvShapeDataSource;
import ilog.views.maps.defense.symbology.app6a.IlvApp6aSymbologyTreeViewActions;
import ilog.views.maps.srs.coordsys.IlvCoordinateSystem;
import ilog.views.maps.srs.coordsys.IlvGeographicCoordinateSystem;
import ilog.views.maps.srs.coordtrans.IlvCoordinateTransformation;
import ilog.views.maps.srs.coordtrans.IlvCoordinateTransformationException;
import ilog.views.maps.symbology.swing.IlvSymbologyTreeView;
import ilog.views.sdm.IlvSDMEngine;
import ilog.views.sdm.IlvSDMException;
import ilog.views.swing.IlvJManagerViewPanel;
import ilog.views.util.IlvProductUtil;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;

/**
 * This demo shows how to use the collapse/expand symbol feature.
 * 
 * @since JViews 7.5
 */
public class CollapseDemo extends JPanel {
  /**
   * Creates a new <code>CollapseDemo</code>.
   */
  public CollapseDemo() {
    // This sample uses JViews Maps for Defense features. When deploying an
    // application that includes this code, you need to be in possession
    // of a Rogue Wave JViews Maps for Defense Deployment license.
    IlvProductUtil.DeploymentLicenseRequired(
        IlvProductUtil.JViews_Maps_for_Defense_Deployment);

    setLayout(new BorderLayout());
    IlvManagerView view = new IlvManagerView();
    view.setManager(new IlvGrapher());
    IlvJManagerViewPanel viewScroll = new IlvJManagerViewPanel(view);
    IlvJMapsManagerViewControlBar viewToolbar = new IlvJMapsManagerViewControlBar();
    viewToolbar.setView(view);
    
    IlvJMouseCoordinateViewer locator = new IlvJMouseCoordinateViewer();
    locator.setView(view);
    viewToolbar.add(locator);
    
    IlvJMapScaleControl scaleBar = new IlvJMapScaleControl();
    scaleBar.setView(view);
    scaleBar.setAllowScaleEdition(false);
    viewToolbar.add(scaleBar);
    
    IlvJAdvancedZoomControl azc=new IlvJAdvancedZoomControl();
    azc.setView(view);
    azc.setOrientation(SwingConstants.HORIZONTAL);   
    viewToolbar.add(azc);
    
    view.setKeepingAspectRatio(true);
    view.setBackground(new Color(80, 180, 240));
    view.setAntialiasing(false);
    view.setSize(new Dimension(600, 600));
    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(1f / 1000f, (float) (1 / 1E9));
    limiter.setView(view);

    // create and setup a symbology
    IlvSDMEngine engine = new IlvSDMEngine();
    try {
      engine.setReferenceView(view);
      URL u = getClass().getResource("app6WithGroups.css"); //$NON-NLS-1$
      engine.setGrapher((IlvGrapher) view.getManager());
      engine.setStyleSheets(new String[] { u.toString() });
    } catch (IlvSDMException e) {
      e.printStackTrace();
    }
    //load shape data
    loadShapeData(view);
    // setup model
    setupSDMModel(engine);
    IlvApp6aSymbologyTreeViewActions actions = new IlvApp6aSymbologyTreeViewActions();
    IlvSymbologyTreeView tv = new IlvSymbologyTreeView(engine);
    tv.setSymbologyTreeViewActions(actions);
    add(tv, BorderLayout.WEST);
    add(viewToolbar, BorderLayout.NORTH);
    add(viewScroll, BorderLayout.CENTER);
    view.setTransformer(new IlvTransformer());
    view.fitTransformerToContent();
    // set the scale to 35 000 000 around point at coordinates 50\u00B0N, 2\u00B0E.
    IlvCoordinate targetCenter = new IlvCoordinate(Math.toRadians(2), -Math.toRadians(55));
    double curScale = IlvMapUtil.computeViewScale(view);
    double targetScale = 35000000;
    double ratio = curScale / targetScale;// ratio to apply to curent zoom
                                          // factor.
    // compute the manager (KERNEL) coordinates of the point
    IlvCoordinateSystem system = IlvCoordinateSystemProperty.GetCoordinateSystem(view.getManager());
    IlvCoordinateTransformation tr = IlvCoordinateTransformation.CreateTransformation(IlvGeographicCoordinateSystem.KERNEL, system);
    try {
      tr.transform(targetCenter,targetCenter);
    } catch (IlvCoordinateTransformationException e) {
      e.printStackTrace();
    }
    // transform the point in view coordinates and zoom to the correct scale.
    IlvPoint c = new IlvPoint((float) targetCenter.x, (float) targetCenter.y);
    IlvTransformer t = view.getTransformer();
    t.apply(c);
    view.zoom(c, ratio, ratio, true);
  }

  /**
   * Main entry.
   * @param args unused
   */
  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();
          frame.setContentPane(new CollapseDemo());
          // change the frame title
          frame.setTitle("Collapse/Expand Demo");//$NON-NLS-1$
          // Manage application exit when we close its window.
          frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
          frame.pack();
          frame.setVisible(true);
        }
      }
      );
  }
  /**
   * Creates a map. All map creation steps are performed here.
   * @throws MalformedURLException 
   */
  private void loadShapeData(IlvManagerView view)  {
    final URL shpFile = getClass().getResource("World_Countries.shp"); //$NON-NLS-1$
    try {
      // create a data source for the shape file
      IlvShapeDataSource shpDataSource = new IlvShapeDataSource(shpFile);
      shpDataSource.setCoordinateSystem(IlvGeographicCoordinateSystem.WGS84);
      shpDataSource.setManager(view.getManager());
      // insert it in the manager's data source tree 
      IlvMapDataSourceModel dataSourceModel = IlvMapDataSourceProperty.GetMapDataSourceModel(view.getManager());
      dataSourceModel.insert(shpDataSource);
      // start reading
      //dataSourceModel.start();
      // insert shape maplayer on the manager's map layer tree
      IlvMapLayerTreeModel ltm = IlvMapLayerTreeProperty.GetMapLayerTreeModel(view.getManager());
      ltm.addChild(null, shpDataSource.getInsertionLayer());
    } catch (Exception e1) {
      e1.printStackTrace();
    }
  }

  void setupSDMModel(IlvSDMEngine engine) {
    // Create a battle field model
    engine.setModel(new BattleField());
    // setup the expand/collapse manager.
    IlvSDMHierarchyExpandManager em = new IlvSDMHierarchyExpandManager(engine);
    em.addHierarchyLevelExpansionScale(0, 20000000);
    em.addHierarchyLevelExpansionScale(1, 10000000);
    em.addHierarchyLevelExpansionScale(2, 5000000);
    em.addHierarchyLevelExpansionScale(3, 2500000);
    em.setAutoComputeGroupLocation(true);
    engine.getReferenceView().addTransformerListener(em);
  }
}