import javax.swing.JFrame;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;

class MouseHandler implements MouseListener {
    /*@non_null@*/ private GridDisplay grid;

    public MouseHandler (/*@non_null@*/ GridDisplay display) {
        super ();
        grid = display;
    }

    public void mousePressed(MouseEvent e) { ; }
    public void mouseReleased(MouseEvent e) { ; }
    public void mouseEntered(MouseEvent e) { ; }
    public void mouseExited(MouseEvent e) { ; }

    public void mouseClicked(MouseEvent e) {
	//@assume e != null;
        grid.setObjectAt (e.getX (), e.getY ());
    }
}

public class Simulator extends JPanel implements ActionListener {
    /*@non_null@*/ GridDisplay display;
    /*@non_null@*/ SimObjectChooser simObjChooser;
    /*@non_null@*/ private JButton startButton, stopButton;

    private int width;
    private int height;
    
    //@requires width > 0
    //@requires height > 0
    public Simulator (int width, int height, /*@non_null@*/ Grid grid) {
	this.width = width;
	this.height = height;
	
        setLayout (new BoxLayout (this, BoxLayout.Y_AXIS));

	simObjChooser = new SimObjectChooser ();

	display = new GridDisplay (grid, simObjChooser);
        display.setPreferredSize (new Dimension (width, height));
        display.setMinimumSize (new Dimension (width, height));
        display.addMouseListener (new MouseHandler (display));
        add (display);

        JPanel panel1 = new JPanel();

	panel1.add (new JLabel ("Place Object: "));
	panel1.add (simObjChooser);

        startButton = new JButton ("Start");
        // place button at center, left position
        startButton.setVerticalTextPosition (AbstractButton.CENTER);
        startButton.setHorizontalTextPosition (AbstractButton.LEFT);
        startButton.setMnemonic (KeyEvent.VK_D);
        startButton.setActionCommand ("start");

        stopButton = new JButton ("Stop");
        // Use the default button position of CENTER, RIGHT.
        stopButton.setMnemonic (KeyEvent.VK_E);
        stopButton.setActionCommand ("stop");
        stopButton.setEnabled (false);
	
        // Listen for actions on the Start and Stop buttons.
        startButton.addActionListener (this);
        stopButton.addActionListener (this);
        
        // Add the start and stop buttons, and the table, to the
        // container, using the default layout.
	panel1.add (simObjChooser);

        panel1.add (startButton);
        panel1.add (stopButton);

        add (panel1);
    }

    public void addClass (String s) {
	try {
	    simObjChooser.addClass (s);
	} catch (ClassNotFoundException e) {
	    System.err.println ("Error loading simulated object class " + s + ": " + e);
	}
    }
        
    public void actionPerformed (ActionEvent e) 
    {
	//@assume e != null;
	String command = e.getActionCommand ();

	if (command != null) {
	    if (command.equals ("start")) {
		startButton.setEnabled (false);
		stopButton.setEnabled (true);
		display.startObjects();
	    } else if (command.equals ("stop")) { 
		startButton.setEnabled (true);
		stopButton.setEnabled (false);
		display.pauseObjects();
	    }
	} else {
	    System.err.println ("Null command: " + e);
	}
    }
}