/*
 * 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.IlvManager;
import ilog.views.diagrammer.IlvDiagrammer;
import ilog.views.diagrammer.application.IlvDiagrammerToolBar;
import ilog.views.graphic.IlvIcon;
import ilog.views.util.IlvProductUtil;
import ilog.views.util.swing.IlvSwingUtil;

import java.applet.AudioClip;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.net.URL;

import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JFrame;
import javax.swing.JSlider;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 * This is a simple application based on a diagram component,
 * {@link ilog.views.diagrammer.IlvDiagrammer}. 
 * It shows little objects turning around a central object, and changing
 * some of their properties according to their position or status.
 */
public class CustomGraphics extends JApplet {
  
    /**
    * Controls whether using CSS version or not. Default is true. Note that the 
    * application produces the same result whatever the value. 
    */
    public final static boolean USE_CSS = true;
  
    /**
     * The width of the view in the diagrammer.
     */
    public static final int VIEW_WIDTH = 800;
    /**
     * The height of the view in the diagrammer.
     */
    public static final int VIEW_HEIGHT = 600;
    
    /**
     * The instance of the diagrammer.
     */
    private IlvDiagrammer diagrammer;
    
    /**
     * The instance of the simulator.
     */
    private Simulator simulator;
    
    
    
    /**
     * Create the main frame.
     *
     * @throws Exception if an error occurs for any reason.
     */
    public void init(Container contentPane) throws Exception {
        // 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);

        // Create the IlvDiagrammer instance.
        diagrammer = new IlvDiagrammer();
        diagrammer.setPreferredSize(new Dimension(VIEW_WIDTH, VIEW_HEIGHT));
        
        // Disallow selection.
        diagrammer.setSelectMode(false);
        
        // Add the IlvDiagrammer instance to the frame.
        contentPane.setLayout(new BorderLayout());
        contentPane.add(diagrammer, BorderLayout.CENTER);
        
        // Create the actions to start and stop the simulator.
        Action resetSimulator = new ResetSimulatorAction();
        Action startSimulator = new PlaySimulatorAction();
        Action stopSimulator = new PauseSimulatorAction();
        
        
        // These are the actions that will go in the toolbar.
        Action[] actions = {
                resetSimulator,
                startSimulator,
                stopSimulator
        };
        
        // Create the simulator. If 2nd parameter is 
        //  - true: use CSS
        //  - false: don't use CSS
        simulator = new Simulator(diagrammer, USE_CSS);
        
        // Set triple buffering for the background in layer 1.
        diagrammer.getView().setTripleBufferedLayerCount(1);
        
        // set background graphic
        final IlvManager manager = diagrammer.getView().getManager(); 
        manager.read( getClass().getResource("zones.ivl") );
        
        
        // Add a toolbar for controlling the application at the north of the frame.
        // this toolbar is a little bit customized to get a nicer look ;-)
        IlvDiagrammerToolBar toolbar = 
          new IlvDiagrammerToolBar(actions, SwingConstants.HORIZONTAL) {

            private GradientPaint paint = null;
            private Insets insets = new Insets(0,0,0,0);
            
            public AbstractButton addAction(Action action){
                AbstractButton b = super.addAction(action);
                b.setContentAreaFilled(false);
                b.setBorderPainted(false);
                b.setMargin(insets);
                b.setOpaque(false);   
                
                URL iconUpURL=null,iconDownURL=null;
                
                if(action instanceof PlaySimulatorAction){
                    iconUpURL = this.getClass().getResource("play_up.gif");
                    iconDownURL = this.getClass().getResource("play_down.gif");
                }else if(action instanceof PauseSimulatorAction){
                    iconUpURL = this.getClass().getResource("pause_up.gif");
                    iconDownURL = this.getClass().getResource("pause_down.gif");
                }else if(action instanceof ResetSimulatorAction){
                    iconUpURL = this.getClass().getResource("reset_up.gif");
                    iconDownURL = this.getClass().getResource("reset_down.gif");
                }
                if(iconUpURL!=null) {
                    b.setIcon(new ImageIcon(iconUpURL));
                }
                if(iconDownURL!=null) {
                    b.setPressedIcon(new ImageIcon(iconDownURL));
                }
                
                return b;
            }
            
            public void paintComponent(Graphics g)
            {
                if(paint==null) paint = new GradientPaint(0, 0, new Color(34,34,34), 0, getHeight(), new Color(83,83,83));
                Graphics2D g2 = (Graphics2D) g;
                g2.setPaint(paint);
                g2.fillRect(0, 0, getWidth(), getHeight());

            }
        };
        toolbar.setFloatable(false);
        contentPane.add(toolbar, BorderLayout.NORTH);

        // Add a slider in the toolbar to change animation speed of the simulator
        final JSlider slider = new JSlider(1,10);
        slider.setOpaque(false);
        slider.setValue(1);
        slider.addChangeListener(new ChangeListener(){
            public void stateChanged(ChangeEvent e) {
                simulator.setSpeedAccelerator(slider.getValue());
            }
        });
        toolbar.add(slider);
        
        
        // Fill the view with a random model once everything has been realized.
        SwingUtilities.invokeLater(new Runnable() {
            /**
             * Create a random model.
             */
            public final void run() {
                manager.setFillOn(true);
                manager.setBackground(Color.black);
                
                // create the model that will be simulated and animated
                simulator.createRandomModel();
            }
        });
    }
    
    
    /**
     * The initialization method of the applet.
     */
    public void init()
    {
        try {
            init(getContentPane());
        } catch (Exception e) {
            e.printStackTrace(System.err);
        }
    }

    public void stop() {
        super.stop();
        // Stop simulator
        System.out.println("stopping simulator...");
        simulator.stop();
    }
    
  /**
   * Called when the applet is destroyed.
   */ 
  public void destroy()
  {
    // This method is intended to work around memory management issues
    // in the Sun JRE. Please refer to the method documentation for more
    // details and a description of the known issues.
    IlvSwingUtil.cleanupApplet();
  }
    
    /**
     * The main method of the application.
     *
     * @param args the command line arguments for the application
     *             (these arguments are ignored by this application).
     */
    public static void main(final String[] args) {
      javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          // Create an instance of the application, and show it.
          try {
              CustomGraphics app = new CustomGraphics();
              JFrame frame = new JFrame("Creating Custom Graphics using the SDK");
              app.init(frame.getContentPane());
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.setLocation(100, 100);
              frame.pack();
              frame.setVisible(true);
          } catch (Exception e) {
              e.printStackTrace(System.err);
          }
        }
      });
    }
    
    /**
     * This is the action to start the simulator.
     */
    private final class PlaySimulatorAction extends AbstractAction {
        /**
         * Create an instance of the action to start the simulator.
         */
        public PlaySimulatorAction() {
            super("Start");
            setEnabled(true);
            putValue(Action.SHORT_DESCRIPTION, "Start the simulator");
        }
        
        /**
         * Stop the simulator.
         *
         * @param e the {@link ActionEvent ActionEvent} for this action.
         */
        public void actionPerformed(final ActionEvent e) {
            simulator.start();
        }
    }
    
    /**
     * This is the action to stop the simulator.
     */
    private final class PauseSimulatorAction extends AbstractAction {
        /**
         * Create an instance of the action to stop the simulator.
         */
        public PauseSimulatorAction() {
            super("Stop");
            putValue(Action.SHORT_DESCRIPTION, "Stop the simulator");
        }
        
        /**
         * Stop the simulator.
         *
         * @param e the {@link ActionEvent ActionEvent} for this action.
         */
        public void actionPerformed(final ActionEvent e) {
            simulator.stop();
        }
    }
    
    /**
     * This is the action to stop the simulator.
     */
    private final class ResetSimulatorAction extends AbstractAction {
        /**
         * Create an instance of the action to stop the simulator.
         */
        public ResetSimulatorAction() {
            super("Reset");
            putValue(Action.SHORT_DESCRIPTION, "Reset simulator");
        }
        
        /**
         * Stop the simulator.
         *
         * @param e the {@link ActionEvent ActionEvent} for this action.
         */
        public void actionPerformed(final ActionEvent e) {
            simulator.reset();
        }
    }
}