/*
 * Copyright (C) Bob L. Sturm 2002
 * 
 * Copyright (C) Michael Fowler 1998 under Gnu Public License
 * http://www.gnu.org/copyleft/gpl.html
 *
 * BrownianApplet.java
 * Drew Dolgert October 1998
 * This applet shows Brownian Motion in two panels.  One is the view of
 * a dust mote in a microscope.  The other is the microscopic explanation
 * for its motion.
 */
 
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class BrownianApplet extends Applet implements ActionListener
{
	Brownian micro;
	Button stopButton, resetButton, stickyBlueBallButton, 
              stickyRedBallButton, zoomBlueButton, slowBlueButton;
	String sStart, sStop, sReset, sBlueStickYes, sBlueStickNo, 
              sRedStickYes, sRedStickNo, sZoomBlue, sSlowBlue;

	public void init()
	{
		String sParam;
		int nBalls;
		double dMassRatio, dAverageVelocity;

		sStart = "Start";
		sStop =  "Stop";
		sReset = "Reset";
		sBlueStickYes = "Sticky Blue Ball";
		sBlueStickNo = "Non-Sticky Blue Ball";
                sRedStickYes = "Sticky Red Balls";
                sRedStickNo = "Non-Sticky Red Balls";
                sZoomBlue = "Energize";
                sSlowBlue = "Slow";

		// Load parameters needed for creating the two main panels.
		sParam = this.getParameter("nballs");
		if (sParam != null) {
			try {
				nBalls = Integer.parseInt(sParam);
			} catch (NumberFormatException e) {
				nBalls = 40;
				System.out.println("nballs should be an integer number of balls in the box.");
			}
		} else nBalls = 40;
		sParam = this.getParameter("massratio");
		if (sParam != null) {
			try {
				dMassRatio = Double.valueOf(sParam).doubleValue();
			} catch (NumberFormatException e) {
				dMassRatio = 20;
				System.out.println("massratio is the floating point ratio of the mass of "+
								"the big blue ball to the red ones.");
			}
		} else dMassRatio = 20;
		sParam = this.getParameter("averagevelocity");
		if (sParam != null) {
			try {
				dAverageVelocity = Double.valueOf(sParam).doubleValue();
			} catch (NumberFormatException e) {
				dAverageVelocity = 5;
				System.out.println("averagevelocity should be a floating point value.");
			}
		} else dAverageVelocity = 5;

		this.setLayout(new BorderLayout());
	    Panel p1 = new Panel(new GridLayout());
		micro = new Brownian(nBalls,dAverageVelocity,dMassRatio); // ave Velocity, Mass Ratio

		sParam = this.getParameter("threadsleep");
		if (sParam != null) {
			try {
				int threadsleep = Integer.parseInt(sParam);
				System.out.println("sleep "+threadsleep);
				micro.setThreadSleep(threadsleep);
			} catch (NumberFormatException e) {
				System.out.println("Threadsleep should be an integer number of milliseconds to sleep.");
			}
		}
		micro.setBackground(new Color(255,248,210));
		p1.add(micro);
		this.add(p1,"Center");

		Panel p2 = new Panel();
		stopButton = new Button(sStop);
		stopButton.setActionCommand("stop");
		stopButton.addActionListener(this);
		p2.add(stopButton);
		resetButton = new Button(sReset);
		resetButton.setActionCommand("reset");
		resetButton.addActionListener(this);
		p2.add(resetButton);

                stickyBlueBallButton = new Button(sBlueStickYes);
                stickyBlueBallButton.setActionCommand("BlueStickYes");
                stickyBlueBallButton.addActionListener(this);
                p2.add(stickyBlueBallButton);

                stickyRedBallButton = new Button(sRedStickYes);
                stickyRedBallButton.setActionCommand("RedStickYes");
                stickyRedBallButton.addActionListener(this);
                p2.add(stickyRedBallButton);
                
        	zoomBlueButton = new Button(sZoomBlue);
                zoomBlueButton.setActionCommand("ZoomBlue");        
                zoomBlueButton.addActionListener(this);
                p2.add(zoomBlueButton);

                slowBlueButton = new Button(sSlowBlue);
                slowBlueButton.setActionCommand("SlowBlue");
                slowBlueButton.addActionListener(this);
                p2.add(slowBlueButton);

		this.add(p2,"South");
	}

	public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("reset")) {
            micro.reset();
        } else if (e.getActionCommand().equals("stop")) {
            stopButton.setLabel(sStart);
            stopButton.setActionCommand("start");
			stopButton.getParent().invalidate();
			stopButton.getParent().validate();
            micro.stop();
        } else if (e.getActionCommand().equals("start")) {
            stopButton.setLabel(sStop);
            stopButton.setActionCommand("stop");
			stopButton.getParent().invalidate();
			stopButton.getParent().validate();
            micro.start();
        } else if (e.getActionCommand().equals("BlueStickYes")) {
            stickyBlueBallButton.setLabel(sBlueStickNo);
            stickyBlueBallButton.setActionCommand("BlueStickNo");
            stickyBlueBallButton.getParent().invalidate();
            stickyBlueBallButton.getParent().validate();
            micro.setBlueCollisionFactor(0);
        } else if (e.getActionCommand().equals("BlueStickNo")) {
            stickyBlueBallButton.setLabel(sBlueStickYes);
            stickyBlueBallButton.setActionCommand("BlueStickYes");
            stickyBlueBallButton.getParent().invalidate();
            stickyBlueBallButton.getParent().validate();
            micro.setBlueCollisionFactor(1);
        } else if (e.getActionCommand().equals("RedStickYes")) {
            stickyRedBallButton.setLabel(sRedStickNo);
            stickyRedBallButton.setActionCommand("RedStickNo");
            stickyRedBallButton.getParent().invalidate();
            stickyRedBallButton.getParent().validate();
            micro.setRedCollisionFactor(0);
        } else if (e.getActionCommand().equals("RedStickNo")) {
            stickyRedBallButton.setLabel(sRedStickYes);
            stickyRedBallButton.setActionCommand("RedStickYes");
            stickyRedBallButton.getParent().invalidate();
            stickyRedBallButton.getParent().validate();
            micro.setRedCollisionFactor(1);
	} else if (e.getActionCommand().equals("ZoomBlue")) {
            micro.zoomBlueBall(1);
        } else if (e.getActionCommand().equals("SlowBlue")) {
            micro.zoomBlueBall(-1);
        }
        }

	public String getAppletInfo() {
		return "BrownianApplet v. 1.0.  Written by Drew Dolgert for Dr. Michael Fowler.\n"+
		"Copyright (C) Michael Fowler mf1i@virginia.edu 1998\n"+
		"Under Gnu Public License http://www.gnu.org/copyleft/gpl.html" +
                "Copyright (C) Bob L. Sturm sturm@ccrma.stanford.edu";
	}

	static final String[][] parameterInfo = {
			{"nballs","integer [40]","Number of red balls."},
			{"massratio","double [20.0]","Ratio of the mass of the big blue ball to the red ones."},
			{"averagevelocity","double [5.0]","Average velocity of the red balls in pixels per timestep."},
			{"threadsleep","integer [20]","Number of milliseconds the gas thread should sleep."},
		};
		
	public String[][] getParameterInfo() {
		return parameterInfo;
	}

	public void start()
	{
		micro.start();
	}

	public void stop()
	{
		micro.stop();
	}
}
		
