// ComPhys File: HitOrMiss.java

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import comphys.*;

public class HitOrMiss extends Applet implements ActionListener, ItemListener, Runnable {

    int ns;
    int n;
    boolean clear;
    double xStone;
    double yStone;
    boolean splash;
    boolean order;

    void throwStone () {

        xStone = Math.random();
        yStone = Math.random();

        if (order) {

            if (xStone < yStone) {

                double swap = xStone;
                xStone = yStone;
                yStone = swap;

            }

        }

        if (yStone < Math.sqrt(1 - xStone * xStone)) {

                ns++;
                splash = true;
                
        } else splash = false;
          
        n++;

    }

    class Picture extends Canvas {

        int pixels = 400;

        Picture () {

            setSize(pixels, pixels);
            setBackground(new Color(255, 250, 240));

        }

        public void paint (Graphics g) {

            update(g);
            
        }

        public void update (Graphics g) {

            if (clear) {
                
                g.clearRect(0, 0, pixels, pixels);
                clear = false;

            }

            if (splash)
                g.setColor(Color.blue);
            else
                g.setColor(Color.green);
            
            int ix = (int) (xStone * pixels);
            int iy = (int) (pixels * (1 - yStone));
            g.fillOval(ix, iy, 2, 2);

            nLabel.setText("" + n);
            double Fn = 4 * ns / (double) n;
            iLabel.setText("" + CP.format(Fn, 6));
            double e = Fn - Math.PI;
            eLabel.setText("" + CP.format(e, 6));
        }

    }

    Picture picture;
    Label nLabel;
    Label iLabel;
    Label eLabel;
    TextField skipTextField;
    int skip;
    Checkbox orderCheckbox;
    Button runButton;
    Button resetButton;

    public void init () {

        add(picture = new Picture());

        Panel p = new Panel();
        p.setLayout(new GridLayout(6, 2));

        p.add(new Label("No. of points = "));
        p.add(nLabel = new Label("          "));
        
        p.add(new Label("Integral = "));
        p.add(iLabel = new Label("          "));
        
        p.add(new Label("Error = "));
        p.add(eLabel = new Label("          "));

        p.add(new Label("Points to skip = "));
        p.add(skipTextField = new TextField("" + skip));
        skipTextField.addActionListener(this);

        p.add(new Label("Order randoms "));
        p.add(orderCheckbox = new Checkbox("x > y"));
        orderCheckbox.addItemListener(this);
                
        p.add(runButton = new Button("Start"));
        runButton.addActionListener(this);

        p.add(resetButton = new Button("Reset"));
        resetButton.addActionListener(this);

        add(p);

    }

    Thread runThread;
    boolean running;

    public void actionPerformed (ActionEvent event) {

        if (event.getSource() == skipTextField) {

            try {

                skip = Integer.parseInt(event.getActionCommand());

            } catch (NumberFormatException nfe) { }

            skipTextField.setText("" + skip);

        } else if (event.getSource() == runButton) {

            if (running) {

                running = false;
                runButton.setLabel("Start");

            } else {

                running = true;
                runThread = new Thread(this);
                runThread.start();
                runButton.setLabel("Stop");

            }

        } else if (event.getSource() == resetButton) {

            if (running) {

                running = false;

            }

            clear = true;
            ns = n = 0;
            picture.repaint();
            runButton.setLabel("Start");

        }

    }

    public void itemStateChanged (ItemEvent ie) {

        order = orderCheckbox.getState();

    }

    public void run () {

        runThread.setPriority(Thread.MIN_PRIORITY);

        while (running) {

            throwStone();
            picture.repaint();

            for (int s = 0; s < skip; s++)
                throwStone();
            
            try {
                runThread.sleep(10);
            } catch (InterruptedException ie) { }

        }

        runThread = null;

    }

    public static void main (String[] args) {

        HitOrMiss hitOrMiss = new HitOrMiss();
        CPFrame aFrame = new CPFrame("Hit or Miss");
        
        aFrame.add(hitOrMiss);
        hitOrMiss.init();
        aFrame.setSize(700, 450);
        aFrame.setLocation(50, 50);
        aFrame.setVisible(true);

    }

}
