package etomica.graphics;
import java.util.Iterator;
import java.util.LinkedList;

import etomica.Default;
import etomica.Integrator;
import etomica.Phase;
import etomica.Simulation;
import etomica.SimulationContainer;

/**
 * The main class that organizes the elements of a molecular simulation.
 * Holds a single space object that is referenced in
 * many places to obtain spatial elements such as vectors and boundaries.  Also
 * holds an object that specifies the unit system used to default all I/O.  A single
 * instance of Simulation is held as a static field, and which forms the default
 * Simulation class needed in the constructor of all simulation elements.
 *
 * @author David Kofke
 */
 
 /* History of changes
  * 08/26/02 (DAK) modified makeAndDisplayFrame method to return the frame
  * 09/13/02 (DAK) added blockDefaultLayout method.
  * 10/21/02 (DAK) added static method to set EtomicaTheme
  * 09/02/03 (DAK) setting Default.DO_SLEEP in constructor
  */
public class SimulationGraphic implements SimulationContainer {
    
    static {
        try {
            javax.swing.plaf.metal.MetalLookAndFeel.setCurrentTheme(new EtomicaTheme());
//            javax.swing.plaf.metal.MetalLookAndFeel.setCurrentTheme(new BlueRoseTheme());
            javax.swing.UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
//            javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());
        } catch(Exception e) {}
    }
    
    private SimulationPanel simulationPanel;
    
    public SimulationGraphic(Simulation simulation) {
        this.simulation = simulation;
        DeviceTrioControllerButton controlPanel = new DeviceTrioControllerButton(simulation);
        add(controlPanel);
        setupDisplayPhase();
    }
    
    public Simulation getSimulation() {return simulation;}
    
    public final LinkedList displayList() { return displayList;}
    public final LinkedList deviceList() { return deviceList; }
                  
    /**
     * A visual display of the simulation via a JPanel.
     */
     public SimulationPanel panel() {
        if(simulationPanel == null) simulationPanel = new SimulationPanel(this);
        return simulationPanel;
     }
     
     private void setupDisplayPhase() {
         LinkedList integratorList = simulation.getIntegratorList();
         
         //TODO find another way to update display
         Integrator integrator = null;
         if(integratorList.size() > 0) integrator = (Integrator)integratorList.getFirst();
         
         LinkedList phaseList = simulation.getPhaseList();
         Iterator iterator = phaseList.iterator();
         while (iterator.hasNext()) {
             Phase phase = (Phase)iterator.next();
             Display display = new DisplayPhase(phase);
             add(display);
             if(integrator != null) integrator.addIntervalListener(display);
         }
         
     }

     public void add(Display display) {
         final java.awt.Component component = display.graphic(null);
         if(component == null) return; //display is not graphic
//         if(display instanceof DisplayBox) {
         if(false) {
             final java.awt.GridBagConstraints gbcBox = new java.awt.GridBagConstraints();
             gbcBox.gridx = 0;
             panel().displayBoxPanel.add(component, gbcBox);
         }
         else {
             panel().displayPanel.add(display.getLabel(),component);
             //add a listener to update the tab label if the name of the display changes
             display.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
                 public void propertyChange(java.beans.PropertyChangeEvent evt) {
                     if(evt.getPropertyName().equals("label")) {
                         int idx = panel().displayPanel.indexOfComponent(component);
                         panel().displayPanel.setTitleAt(idx,evt.getNewValue().toString());
                     }
                 }
             });
         }
         displayList.add(display);
     }

     /**
      * Adds displays graphic to the simulation display pane
      */
     public void add(Device device) {
         java.awt.Component component = device.graphic(null);
         if(device instanceof DeviceTable) {
             panel().displayPanel.add(component);
         }
         else {
             final java.awt.GridBagConstraints gbc = new java.awt.GridBagConstraints();
             gbc.gridx = 0;
             panel().devicePanel.add(component,gbc);
         }
         deviceList.add(device);
     }
     
    public final javax.swing.JFrame makeAndDisplayFrame() {
        javax.swing.JFrame f = new javax.swing.JFrame();
        f.setSize(700,500);
        f.getContentPane().add(panel());
        f.pack();
        f.show();
        f.addWindowListener(SimulationGraphic.WINDOW_CLOSER);
        return f;
    }
    
    public static final java.awt.event.WindowAdapter WINDOW_CLOSER 
        = new java.awt.event.WindowAdapter() {   //anonymous class to handle window closing
            public void windowClosing(java.awt.event.WindowEvent e) {System.exit(0);}
        };
        
        
    private final Simulation simulation;
    private final LinkedList displayList = new LinkedList();
    private final LinkedList deviceList = new LinkedList();

    /**
     * Demonstrates how this class is implemented.
     */
    public static void main(String[] args) {
        Default.DO_SLEEP = false;
//        etomica.simulations.SwMd2D sim = new etomica.simulations.SwMd2D();
//        etomica.simulations.LjMd2D sim = new etomica.simulations.LjMd2D();
//        etomica.simulations.HsMc2d sim = new etomica.simulations.HsMc2d();
//          etomica.simulations.SWMD3D sim = new etomica.simulations.SWMD3D();
      etomica.simulations.HSMD3D sim = new etomica.simulations.HSMD3D();
//        etomica.simulations.HSMD2D sim = new etomica.simulations.HSMD2D();
//        etomica.simulations.GEMCWithRotation sim = new etomica.simulations.GEMCWithRotation();
        SimulationGraphic simGraphic = new SimulationGraphic(sim);
        DeviceNSelector nSelector = new DeviceNSelector(sim,sim.phase.getAgent(sim.species));
        simGraphic.add(nSelector);
        simGraphic.makeAndDisplayFrame();
        ColorSchemeByType.setColor(sim.species, java.awt.Color.red);
//        ColorSchemeByType.setColor(sim.species2, java.awt.Color.blue);
        simGraphic.panel().setBackground(java.awt.Color.yellow);
    }//end of main
    
}



@@ -76,16 +76,71 @@
 dList;%0A%0A
+import javax.swing.JFrame;%0Aimport javax.swing.JPanel;%0A%0A
 import e
@@ -155,16 +155,16 @@
 efault;%0A
-
 import e
@@ -279,429 +279,79 @@
 %0A * 
-The main class that organizes the elements of a molecular simulation.%0A * Holds a single space object that is referenced in%0A * many places to obtain spatial elements such as vectors and boundaries.  Also%0A * holds an object that specifies the unit system used to default all I/O.  A single%0A * instance of Simulation is held as a static field, and which forms the default%0A * Simulation class needed in the constructor of all
+General class for graphical presentation of the elements of a molecular
  sim
@@ -357,25 +357,16 @@
 mulation
- elements
 .%0A *%0A * 
@@ -1883,20 +1883,16 @@
 onPanel(
-this
 );%0A     
@@ -4308,28 +4308,121 @@
 c final 
-javax.swing.
+JFrame makeAndDisplayFrame() %7B%0A        return makeAndDisplayFrame(panel());%0A    %7D%0A    %0A    public static 
 JFrame m
@@ -4432,32 +4432,44 @@
 AndDisplayFrame(
+JPanel panel
 ) %7B%0A        java
@@ -4464,28 +4464,16 @@
         
-javax.swing.
 JFrame f
@@ -4479,28 +4479,16 @@
 f = new 
-javax.swing.
 JFrame()
@@ -4549,26 +4549,24 @@
 ().add(panel
-()
 );%0A        f

Update for recent changes