import java.awt.Button;
import java.awt.Color;
import java.awt.Event;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Panel;
import java.util.Random;

public class Memory extends java.applet.Applet implements Runnable {

	Thread mainThread;
	Panel blue_panel; // panels for the various colors
	Panel red_panel;
	Panel yellow_panel;
	Panel green_panel;
	int max_length = 1000; // maximum number of moves by computer
	int computer[]; // to hold the computer's move
	int current_length = 0; // the current length of the computer's move
	Random num_gen = new Random(); // random number generator
	int color_flag = 5; // tells which color to have highlited
	boolean player_move = false; // is it the player's move?
	int player_pos = 0; // the player's position in his move
	boolean game_over = true; // flag for the game being over
	boolean player_action = false; // did the player do something
	int last_move = 0; // the player's last move

	int last_score = 0;

	public void init() {
		computer = new int[max_length]; // make the array for computer

		resize(450, 300);
		blue_panel = new Panel(); // create the new panels for each color
		red_panel = new Panel();
		yellow_panel = new Panel();
		green_panel = new Panel();

		blue_panel.add("North", new Button("Blue"));// put on the buttons
		red_panel.add("South", new Button("Red"));
		yellow_panel.add("West", new Button("Yellow"));
		green_panel.add("East", new Button("Green"));
		add("Center", blue_panel);// add the panels and their buttons to the
									// screen
		add("Center", red_panel);
		add("Center", yellow_panel);
		add("Center", green_panel);
		setLayout(new GridLayout(2, 2, 200, 200)); // set the layout to a grid
	}

	public void computer_move() { // the routiene for computer to make move
		int i;
		if (game_over)
			return;
		if (player_move) // don't do anything if it is the player's move
			return;

		current_length++; // increase the current sequence length
		computer[current_length] = num_gen.nextInt() % 4;// get a random
															// number
		if (computer[current_length] < 0)
			computer[current_length] *= -1;

		for (i = 1; i <= current_length; i++) { // display the proper moves
			color_flag = computer[i]; // set the flag
			repaint(); // redraw everything

			try { // pause to let it sink in
				mainThread.sleep(500);
			} catch (InterruptedException e) {
			}
			color_flag = 5; // set the color flag to 5, which will repaint

			repaint(); // recursivley repaint to redraw
			if (i == current_length) // don't pause at end
				break;
			try { // pause to allow distinction of moves
				mainThread.sleep(500);
			} catch (InterruptedException e) {
			}
		}
		player_move = true; // make it the player's move, allow input
	}

	public void start() {
		if (mainThread == null) {
			mainThread = new Thread(this, "main");
			mainThread.start();
		}
	}

	public void run() {
		int i;
		repaint();
		player_pos = 0;
		for (;;) {
			while (game_over) {
				mainThread.suspend(); // will come to life with a button hit
				game_over = false;
				color_flag = 5;
				repaint();
				player_move = false;
				current_length = 0;
				player_pos = 0;
				try { // pause to let it sink in
					mainThread.sleep(500);
				} catch (InterruptedException e) {
				}
				break;
			}
			computer_move(); // the computer makes a move

			mainThread.suspend(); // wait for player
			// assume that button has been pressed,color set

			repaint(); // redraw everything, blink the color

			try { // pause to let it sink in
				mainThread.sleep(500);
			} catch (InterruptedException e) {
			}
			color_flag = 5; // set the color flag to 5, which will repaint

			repaint(); // redraw with no colors
			player_move = true;
			// test the square
			if (last_move != computer[player_pos]) { // didn't hit the right
														// square
				game_over = true;
				last_score = player_pos; // save this score
				player_pos = 0;
				current_length = 0; // reset the current_length
				player_move = false; // no longer the player's move
				repaint();
				continue;
			}
			if (player_pos == current_length) {// if made all the moves
				player_pos = 0;
				player_move = false;// no longer the player's move
				try { // pause to let it sink in
					mainThread.sleep(1000);
				} catch (InterruptedException e) {
				}
			}
		}
	}

	public void update(Graphics g) {
		if (game_over) { // if the game has ended
			g.setColor(Color.black);
			g.drawString("Game Over", 190, 140);// just draw game over
			g.drawString("Click any button to start", 150, 180);
			return; // do no more drawing
		}
		g.setColor(Color.lightGray);
		g.fillRect(0, 0, 449, 299);
		g.setColor(Color.black); // draw the rectangle outlines
		g.drawLine(0, 150, 449, 150);
		g.drawLine(225, 0, 225, 299);
		if (color_flag == 5) // don't do other stuff on a five
			return;

		if (color_flag == 0) { // draw blue square
			g.setColor(Color.blue);
			g.fillRect(0, 0, 225, 150);
		} else if (color_flag == 1) { // draw red square
			g.setColor(Color.red);
			g.fillRect(226, 0, 223, 150);
		} else if (color_flag == 2) { // draw yellow square
			g.setColor(Color.yellow);
			g.fillRect(0, 152, 224, 147);
		} else if (color_flag == 3) { // draw green square
			g.setColor(Color.green);
			g.fillRect(226, 151, 223, 148);
		}

	}

	public void paint(Graphics g) {

		update(g); // don't erase the whole screen all the time
	}

	public boolean action(Event evt, Object arg) { // allow input
		mainThread.resume();
		if (game_over) {
			game_over = false;
			color_flag = 5; // redraw the screen
			return true;
		}
		if (player_move == false) // don't do anything if not player's move
			return true;
		player_move = false; // don't allow more actions for now
		String label = (String) arg;

		if (label.equals("Blue")) { // if the blue button was hit
			color_flag = 0; // light the appropriate color
			player_pos++;
		} else if (label.equals("Red")) {// red button hit
			color_flag = 1;
			player_pos++;
		} else if (label.equals("Yellow")) {// yellow button hit
			color_flag = 2;
			player_pos++;
		} else if (label.equals("Green")) {// green button hit
			color_flag = 3;
			player_pos++;
		}

		last_move = color_flag; // record the last move;

		player_action = true; // flag that the player has made a move
		// player_move = true;
		return true;
	}

	public void stop() {
		mainThread.stop();
		mainThread = null;
	}
}

