//  File:  AutoPolygons - Automatically draw random Polygons in random colors
//         Demonstrate Polygon creation
//         Demonstrate Random and Math.random()
//         Demonstrate use of a Timer
//         Demonstrate resizing an Applet
//         Based on RanPolygons

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.util.Random;
import javax.swing.Timer;

public class AutoPolygons extends Applet {

    /**
    * Initialize the background; set up the Start/Stop button
    */
    public void init() {
        setBackground(Color.green.darker());
        startButton.addActionListener(new StartButtonHandler());
        add(startButton);
        refreshButton.addActionListener(new RefreshButtonHandler());
        add(refreshButton);
        refreshButton.setEnabled(false);
        delayButton.addActionListener(new DelayButtonHandler());
        add(delayButton);
        timer = new Timer(nDelay, new TimerHandler());
    }

    /**
    * (Re-) paint the screen
    */
    public void paint(Graphics g) {
        color = newColor();
        displayPolygon(g);
    }

    // Create a random Color
    private Color newColor() {
        return new Color(ran256(), ran256(), ran256());
    }

    /**
    * Display a randomly colored Polygon, with a black outline
    */
    private void displayPolygon(Graphics g) {
        if (polygon != null) {
            g.setColor(color);
            g.fillPolygon(polygon);
            g.setColor(Color.black);
            g.drawPolygon(polygon);
        }
    }

    /* Generate an int in the range [0..255] */
    private int ran256() { return (int) (256 * Math.random()); }

    /**
    * Create and return an nNumPoints Polygon, in the 2D area [nMin, nMin]
    */
    private Polygon createPoly(final int nNumPoints, final int nMin) {
        Polygon polygon = new Polygon();
        for (int i = 0; i < nNumPoints; i++) {
            int x = random.nextInt(nMin);
            int y = random.nextInt(nMin);
            polygon.addPoint(x, y);
        }
        return polygon;
    }

    /**
    * Semantics of the "Start/Stop" button
    */
    private class StartButtonHandler implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            if (timer.isRunning()) {
                // Semantics for 'Stop'
                startButton.setLabel("      Start      ");
                refreshButton.setEnabled(true);
                nDelay /= 2;
                timer.stop();
                statusMessage = " Press 'Start' to begin drawing...";
            } else {
                // Semantics for 'Start'
                startButton.setLabel("       Stop       ");
                refreshButton.setEnabled(false);
                timer.setDelay(nDelay);
                timer.start();
                statusMessage = " Press 'Stop' to stop drawing...  ";
                dimension = getSize();
                if (dimension.width <= 1010)
                    dimension.width  += 20;
                if (dimension.height <= 640)
                    dimension.height += 20;
                setSize(dimension.width, dimension.height);
            }
            showStatus(statusMessage + "    Delay=" + nDelay + "ms");
        }
    }

    /**
    * Semantics of the "Refresh" button
    */
    private class RefreshButtonHandler implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            repaint();
        }
    }

    /**
    * Semantics of the "Reset Delay" button
    */
    private class DelayButtonHandler implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            nDelay = DELAY;
            timer.setDelay(nDelay);
            showStatus(statusMessage + "    Delay=" + nDelay + "ms");
        }
    }

    /**
    * Semantics of the Timer
    */
    private class TimerHandler implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            nNumPoints = random.nextInt(8) + 3;
            int nMin = Math.min(getSize().width, getSize().height);
            polygon = createPoly(nNumPoints, nMin);
            repaint();
        }
    }

    private int nNumPoints;         // Number of points in the Polygon
    private Color color;            // The Color handle
    private Polygon polygon;        // The Polygon handle
    private Button startButton   = new Button("      Start      ");
    private Button refreshButton = new Button("    Refresh    ");
    private Button delayButton   = new Button(" Reset Delay ");
    private String statusMessage = "Press 'Start' to start drawing...";
    private Random random = new Random(1234L);
    private final int DELAY = 256;
    private int nDelay = DELAY;
    private Timer timer;
    private Dimension dimension;
}
