/*
 * Todo:
 * Add a restart button
 * Set up each "button" in the grid as its own container and figure out how
 *  to make them work with each other.  At least, I think that'll be a better
 *  model of how to operate
 */
import java.applet.*;
import java.awt.*;
import java.util.Random;
import java.awt.event.*;

public class MagicSquare extends Applet {
    private Grid board;
    private Button bn;

    private class Grid extends Panel {
	Color	lightred, red, darkred;
	boolean	grid[][] = new boolean[3][3];

	public void newgrid() {
	    int		i, j;
	    Random	rand = new Random();
	    
	    for(i=0; i<3; ++i) {
		for(j=0; j<3; ++j) {
		    grid[i][j] = (rand.nextInt() < 0) ? true : false;
		}
	    }
	}

	public Grid() {
	    lightred = Color.red;
	    darkred = new Color(127, 0, 0);
	    red = new Color(191, 0, 0);
	    this.addMouseListener(new MouseAdapter() {
		    public void mouseClicked(MouseEvent e) {
			int x, y;

			x = e.getX();
			y = e.getY();
			Graphics g = getGraphics();
			int i = x / 100;
			int j = y / 100;
			switch(3*i+j) {
			case 0:	/* i = 0, j = 0 */
			    grid[0][0] = !grid[0][0];
			    grid[0][1] = !grid[0][1];
			    grid[1][0] = !grid[1][0];
			    grid[1][1] = !grid[1][1];
			    paintcircle(g, grid[0][0], 0, 0);
			    paintcircle(g, grid[0][1], 0, 1);
			    paintcircle(g, grid[1][0], 1, 0);
			    paintcircle(g, grid[1][1], 1, 1);
			    break;

			case 1:	/* i = 0, j = 1 */
			    grid[0][0] = !grid[0][0];
			    grid[0][1] = !grid[0][1];
			    grid[0][2] = !grid[0][2];
			    paintcircle(g, grid[0][0], 0, 0);
			    paintcircle(g, grid[0][1], 0, 1);
			    paintcircle(g, grid[0][2], 0, 2);
			    break;

			case 2:	/* i = 0, j = 2 */
			    grid[0][1] = !grid[0][1];
			    grid[0][2] = !grid[0][2];
			    grid[1][1] = !grid[1][1];
			    grid[1][2] = !grid[1][2];
			    paintcircle(g, grid[0][1], 0, 1);
			    paintcircle(g, grid[0][2], 0, 2);
			    paintcircle(g, grid[1][1], 1, 1);
			    paintcircle(g, grid[1][2], 1, 2);
			    break;

			case 3:	/* i = 1, j = 0 */
			    grid[0][0] = !grid[0][0];
			    grid[1][0] = !grid[1][0];
			    grid[2][0] = !grid[2][0];
			    paintcircle(g, grid[0][0], 0, 0);
			    paintcircle(g, grid[1][0], 1, 0);
			    paintcircle(g, grid[2][0], 2, 0);
			    break;

			case 4:	/* i = 1, j = 1 */
			    grid[0][1] = !grid[0][1];
			    grid[1][0] = !grid[1][0];
			    grid[1][1] = !grid[1][1];
			    grid[1][2] = !grid[1][2];
			    grid[2][1] = !grid[2][1];
			    paintcircle(g, grid[0][1], 0, 1);
			    paintcircle(g, grid[1][0], 1, 0);
			    paintcircle(g, grid[1][1], 1, 1);
			    paintcircle(g, grid[1][2], 1, 2);
			    paintcircle(g, grid[2][1], 2, 1);
			    break;

			case 5:	/* i = 1, j = 2 */
			    grid[0][2] = !grid[0][2];
			    grid[1][2] = !grid[1][2];
			    grid[2][2] = !grid[2][2];
			    paintcircle(g, grid[0][2], 0, 2);
			    paintcircle(g, grid[1][2], 1, 2);
			    paintcircle(g, grid[2][2], 2, 2);
			    break;

			case 6:	/* i = 2, j = 0 */
			    grid[1][0] = !grid[1][0];
			    grid[1][1] = !grid[1][1];
			    grid[2][0] = !grid[2][0];
			    grid[2][1] = !grid[2][1];
			    paintcircle(g, grid[1][0], 1, 0);
			    paintcircle(g, grid[1][1], 1, 1);
			    paintcircle(g, grid[2][0], 2, 0);
			    paintcircle(g, grid[2][1], 2, 1);
			    break;

			case 7:	/* i = 2, j = 1 */
			    grid[2][0] = !grid[2][0];
			    grid[2][1] = !grid[2][1];
			    grid[2][2] = !grid[2][2];
			    paintcircle(g, grid[2][0], 2, 0);
			    paintcircle(g, grid[2][1], 2, 1);
			    paintcircle(g, grid[2][2], 2, 2);
			    break;

			case 8:	/* i = 2, j = 2 */
			    grid[1][1] = !grid[1][1];
			    grid[1][2] = !grid[1][2];
			    grid[2][1] = !grid[2][1];
			    grid[2][2] = !grid[2][2];
			    paintcircle(g, grid[1][1], 1, 1);
			    paintcircle(g, grid[1][2], 1, 2);
			    paintcircle(g, grid[2][1], 2, 1);
			    paintcircle(g, grid[2][2], 2, 2);
			    break;
			}
		    }
		});
	    newgrid();
	}

	public void paint(Graphics g) {
	    int	xs[] = new int[3], ys[] = new int[3];
	    Polygon	upper, lower;

	    g.setColor(lightred);
	    Rectangle r = this.getBounds();
	    g.fillRect(r.x, r.y, r.width, r.height);
	    for(int i = 0; i<3; ++i) {
		for(int j = 0; j<3; ++j) {
		    xs[0] = 100 + 100 * i;
		    xs[1] = xs[0] + 100;
		    xs[2] = xs[0];
		    ys[0] = 50 + 100 * j;
		    ys[1] = ys[0];
		    ys[2] = ys[0] + 100;
		    upper = new Polygon(xs, ys, 3);
		    xs[0] = 200 + 100 * i;
		    xs[1] = xs[0] - 100;
		    xs[2] = xs[0];
		    ys[0] = 150 + 100 * j;
		    ys[1] = ys[0];
		    ys[2] = ys[0] - 100;
		    lower = new Polygon(xs, ys, 3);
		    g.setColor(red);
		    g.fillPolygon(lower);
		    g.setColor(darkred);
		    g.fillPolygon(upper);
		    g.setColor(Color.black);
		    g.drawLine(100 + 100 * i, 50 + 100 * j,
			       150 + 100 * i, 100 + 100 * j);
		    g.drawLine(150 + 100 * i, 100 + 100 * j,
			       200 + 100 * i, 150 + 100 * j);
		    g.fillOval(135 + 100 * i, 85 + 100 * j, 30, 30);
		    if(grid[i][j]) {
			g.setColor(lightred);
			g.fillOval(143 + 100 * i, 93 + 100 * j, 14, 14);
		    }
		}
	    }
	}

	private void paintcircle(Graphics g, boolean b, int i, int j) {
	    if(b) {
		g.setColor(lightred);
		g.fillOval(143 + 100 * i, 93 + 100 * j, 14, 14);
	    }
	    else {
		g.setColor(Color.black);
		g.fillOval(135 + 100 * i, 85 + 100 * j, 30, 30);
	    }
	}

	public Dimension getMinimumSize() {
	    return new Dimension(500, 500);
	}

	public Dimension getMaximumSize() {
	    return new Dimension(500, 500);
	}

	public Dimension getPreferredSize() {
	    return new Dimension(300, 300);
	}
    }

    public void init() {
	setLayout(new FlowLayout(FlowLayout.CENTER));
	board = new Grid();
	board.setVisible(true);
	// add(board, "Center");
	add(board, "South");

	bn = new Button("Start Over");
	bn.addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent e) {
		    board.newgrid();
		    Graphics g = board.getGraphics();
		    board.paint(g);
		}
	    });
	add(bn, "North");
    }
}
