//package pacman;

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.util.Random;

public class Spill extends Applet {
	int numThings; 
	int maxX;
	int maxY;
	int maxThings;
	Thingy[][] thingyGrid;
	final int inedibles = 5;
	Random xRand = new Random();
	Random yRand = new Random();
	GameGrid screen = new GameGrid(20,10); // DS The PacMan panel.
	PacMan PacMan1 = new PacMan("P1");  // DS A simple PacMan object
	PacMan PacMan2 = new PacMan("P2");  // DS A simple PacMan object 
	PacScore statPac1 = new PacScore(PacMan1);
	PacScore statPac2 = new PacScore(PacMan2);
	Panel sidebar = new Panel();
	Breeder SBreeder;
	Breeder FBreeder;
	Breeder TBreeder;
	Fodder fodder;
	Label numall = new Label("Things: " + String.valueOf(inedibles));

	public void init() {
		int x, y;
		//boolean isStandalone = false;

		x = y = 0;
		setLayout(new BorderLayout());
		add("West", sidebar);
		add("Center", screen);
		sidebar.setLayout(new GridLayout(0,1));
		sidebar.add(statPac1);
		sidebar.add(statPac2);
		sidebar.add(numall);
		sidebar.add(new Panel());
		sidebar.add(new Panel());
		sidebar.add(new Panel());

		screen.setBackground(Color.darkGray);
		//screen.GameGrid(); // DS Must be called to create the cells.

		maxX = screen.getXSize();
		maxY = screen.getYSize();
		numThings = inedibles;
		maxThings = maxX * maxY;

		SBreeder = new Breeder("S", 30);
		FBreeder = new Breeder("F", 40);
		TBreeder = new Breeder("T", 50);

		thingyGrid = new Thingy[maxX][maxY];
		
		for (x = 0; x < maxX; x++) {
			for (y = 0; y < maxY; y++) {
				thingyGrid[x][y] = null;
			}
		}

		try {
			jbInit();
		}
		catch (Exception e) {
		e.printStackTrace();
		}
	}

	private void jbInit() throws Exception {
		int x, y;
		this.setEnabled(true);
				
		screen.addKeyListener(new KeyAdapter() {
			public void keyTyped(KeyEvent e) {
				keytyped(e);
			}
		});
		
		addKeyListener(new KeyAdapter() {
			public void keyTyped(KeyEvent e) {
				keytyped(e);
			}
		});

		PacMan1.setView(screen); // DS Connect the PacMan to its view.
		setRandPosition(PacMan1);
		PacMan1.makeVisible();
	 	PacMan2.setView(screen);
		setRandPosition(PacMan2);
		PacMan2.makeVisible();
		SBreeder.setView(screen);
		setRandPosition(SBreeder);
		SBreeder.makeVisible();
		FBreeder.setView(screen);
		setRandPosition(FBreeder);
		FBreeder.makeVisible();
		TBreeder.setView(screen);
		setRandPosition(TBreeder);
		TBreeder.makeVisible();

		Thread SBthread = new BreederThread(SBreeder);
		SBthread.start();
		Thread FBthread = new BreederThread(FBreeder);
		FBthread.start();
		Thread TBthread = new BreederThread(TBreeder);
		TBthread.start();
	}
	
	public class BreederThread extends Thread {
		Breeder theBreeder;
		int when;

		public BreederThread(Breeder breeder) {
			theBreeder = breeder;
			when = (int) Math.round(theBreeder.hasWorth() / 3);
		}

		public void run() {
			int realmax = maxThings - inedibles; 

			while (numThings < realmax) { 
				fodder = theBreeder.makeFood();
				fodder.setView(screen);
				setRandPosition(fodder);
				numThings++;
				numall.setText("Things: " + String.valueOf(numThings));
				try {
					sleep(when * 1000 + (int) Math.random());
				} catch (InterruptedException e) {}
			}
		}
	}

	// Returns true if a position is taken, or is a wall
	public boolean checkPosition(int x, int y) {
		if ((x > -1 && y > -1) && (x < maxX && y < maxY)) {
			if (thingyGrid[x][y] == null) { return false; } 
			else { return true; }
		} return true;
	}
	
	public void setRandPosition(Thingy thing) {
		int x, y;

		x = y = -1;
		while (checkPosition(x, y)) {
			x = xRand.nextInt() % maxX;
			y = yRand.nextInt() % maxY;
		}
		thing.moveTo(x,y);
		thing.makeVisible();
		thingyGrid[x][y] = thing;
	}

	public boolean changePosition(PacMan pac, int x, int y) {
		boolean moveon = true; 
		if ((x < 0 || y < 0) || (x >= maxX || y >= maxY)) { return false; }
		if (checkPosition(x, y)) {
			if (!thingyGrid[x][y].isEdible()) { return false; }
			moveon = pac.eat(thingyGrid[x][y]);
			thingyGrid[x][y] = null;
			numThings--;
			numall.setText("Things: " + String.valueOf(numThings));
			} 
		return moveon;
	}

	public void keytyped(KeyEvent e) {
		boolean occupied;
		char key = e.getKeyChar();
		int P1X = PacMan1.getX();
		int P1Y = PacMan1.getY();
		int P2X = PacMan2.getX();
		int P2Y = PacMan2.getY();
		switch (key) {
			case 'w':	if (changePosition(PacMan1, P1X, P1Y-1)) {
							PacMan1.moveUp();
							thingyGrid[P1X][P1Y] = null;
							statPac1.update();
						}
						break;
			case 'z':	if (changePosition(PacMan1, P1X, P1Y+1)) {
							PacMan1.moveDown();
							thingyGrid[P1X][P1Y] = null;
							statPac1.update();
						}
						break;
			case 'a':	if (changePosition(PacMan1, P1X-1, P1Y)) {
							PacMan1.moveLeft();
							thingyGrid[P1X][P1Y] = null;
							statPac1.update();
						}
						break;
			case 's':	if (changePosition(PacMan1, P1X+1, P1Y)) {
							PacMan1.moveRight();
							thingyGrid[P1X][P1Y] = null;
							statPac1.update();
						}
						break;
			case 'i':	if (changePosition(PacMan2, P2X, P2Y-1)) {
							PacMan2.moveUp();
							thingyGrid[P2X][P2Y] = null;
							statPac2.update();
						}
						break;
			case 'm':	if (changePosition(PacMan2, P2X, P2Y+1)) {
							PacMan2.moveDown();
							thingyGrid[P2X][P2Y] = null;
							statPac2.update();
						}
						break;
			case 'j':	if (changePosition(PacMan2, P2X-1, P2Y)) {
							PacMan2.moveLeft();
							thingyGrid[P2X][P2Y] = null;
							statPac2.update();
						}
						break;
			case 'k':	if (changePosition(PacMan2, P2X+1, P2Y)) {
							PacMan2.moveRight();
							thingyGrid[P2X][P2Y] = null;
							statPac2.update();
						}
						break;
			default:	break;
		}  
	} 

}
