package com.goatsandtigers.ripvanwinkle;

import java.applet.Applet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

public class RipVanWinkleApplet extends Applet
	implements MouseListener, MouseMotionListener
{
	private int               level;
	private RipVanWinkleBoard board          = null;
	private Image             skittleImage   = null;
	private Image             hoveredOverSkittleImage = null;
	private Image             gameOverImage  = null;
	private Image             nextLevelImage = null;
	private Font              levelTextFont  = new Font("Arial", Font.ITALIC, 16);
	private int               state          = RipVanWinkleApplet.STATE_MAIN_GAME;

	public static final int STATE_MAIN_GAME  = 1;
	public static final int STATE_GAME_OVER  = 2;
	public static final int STATE_NEXT_LEVEL = 3;

	public void init()
	{
		this.skittleImage            = this.getImage(this.getCodeBase(), "skittle/bottle1.png");
		this.hoveredOverSkittleImage = this.getImage(this.getCodeBase(), "skittle/bottle2.png");
		this.gameOverImage           = this.getImage(this.getCodeBase(), "skittle/gameover1.jpg");
		this.nextLevelImage          = this.getImage(this.getCodeBase(), "skittle/welldone1.jpg");
		this.addMouseMotionListener(this);
		this.addMouseListener(this);
		this.beginLevel(1);
	}

	public void beginLevel(int level)
	{
		this.state = RipVanWinkleApplet.STATE_MAIN_GAME; 
		this.level = level;
		this.board = new RipVanWinkleBoardClassic(13, 500);
		switch(level)
		{
		case 1:
		case 2:
			this.board.knockSkittleDown(1);
			break;
		case 4:
		case 5:
			this.board.makeRandomMove();
			break;
		case 7:
			this.board.knockSkittleDown(6);
		}
	}

	public void paint(Graphics g)
	{
		if(this.state == RipVanWinkleApplet.STATE_MAIN_GAME)
		{
			g.setFont(this.levelTextFont);
			g.drawString("Level " + this.level + " / 7", 3, 140);
			for(int i = 0; i < this.board.getNumSkittles(); i++)
			{
				if(this.board.isSkittleStillStanding(i))
				{
					Rectangle rect = this.board.getSkittleRectangle(i);
					this.drawImageInCenterOfRect(g,
							this.board.isSkittleHoveredOver(i) ?
									this.hoveredOverSkittleImage : this.skittleImage,
							rect);
				}
			}
		}
		else if(this.state == RipVanWinkleApplet.STATE_GAME_OVER)
		{
			g.setFont(this.levelTextFont);
			g.drawImage(this.gameOverImage,
					(this.getWidth() - this.gameOverImage.getWidth(this)) / 2,
					(this.getHeight() - this.gameOverImage.getHeight(this)) / 2,
					this);
		}
		else if(this.state == RipVanWinkleApplet.STATE_NEXT_LEVEL)
		{
			g.setColor(Color.BLACK);
			g.setFont(this.levelTextFont);
			g.drawImage(this.nextLevelImage,
					(this.getWidth() - this.nextLevelImage.getWidth(this)) / 2,
					(this.getHeight() - this.nextLevelImage.getHeight(this)) / 2,
					this);
		}
	}

	public void drawImageInCenterOfRect(Graphics g, Image i, Rectangle r)
	{
		int left = r.x + (r.width - i.getWidth(this)) / 2,
			top = r.y + (r.height - i.getHeight(this)) / 2;
		g.drawImage(i, left, top, this);
	}

	public void mouseDragged(MouseEvent arg0) {}

	public void mouseMoved(MouseEvent me)
	{
		long skittlesHoveredOverBefore = this.board.getSkittlesHoveredOver();
		this.board.updateSkittlesHoveredOver(me.getPoint());
		long skittlesHoveredOverAfter = this.board.getSkittlesHoveredOver();
		if(skittlesHoveredOverBefore != skittlesHoveredOverAfter)
		{
			this.repaint();
		}
	}

	/**
	 * If the player is hovering over any skittles when the click the mouse
	 * then these are knocked over then a check is performed to see if the
	 * player has won. If they have not then the AI makes a move and a check
	 * is performed to see if the player has lost.
	 */
	public void mouseClicked(MouseEvent me)
	{
		if(this.state == RipVanWinkleApplet.STATE_GAME_OVER)
		{
			this.beginLevel(1);
			this.repaint();
		}
		else if(this.state == RipVanWinkleApplet.STATE_NEXT_LEVEL)
		{
			this.beginLevel(this.level + 1);
			this.repaint();
		}
		else
		{
			long humanPlayersMove = this.board.getSkittlesHoveredOver(); 
			if(humanPlayersMove != 0)
			{
				this.board.knockOverHoveredOverSkittles();
				if(this.board.isGameOver())
				{
					//JOptionPane.showMessageDialog(null, "You win");
					this.state = RipVanWinkleApplet.STATE_NEXT_LEVEL;
					//this.repaint();
					//this.beginLevel(this.level + 1);
				}
				else
				{
					switch(level)
					{
					case 1:
						this.board.makeRandomMove();
						break;
					case 2:
						if(this.board.getNumSkittlesStillStanding() > 9)
						{
							this.board.makeRandomMove();
						}
						else
						{
							this.board.makePerfectMove(RipVanWinkleBoard.UNLIMITED_SEARCH_DEPTH);
						}
						break;
					case 3:
						if(this.board.canMirrorLastMove())
						{
							this.board.mirrorLastMove();
						}
						else
						{
							this.board.makeRandomMove();
						}
						break;
					case 4:
						this.board.makePerfectMove(RipVanWinkleBoard.UNLIMITED_SEARCH_DEPTH);
						break;
					case 5:
						this.board.makePerfectMove(5);
						break;
					case 6:
						if(this.board.getNumSkittlesStillStanding() > 7)
						{
							this.board.makePerfectMove(RipVanWinkleBoard.UNLIMITED_SEARCH_DEPTH);
						}
						else
						{
							this.board.makeRandomMove();
						}
						break;
					case 7:
						this.board.mirrorLastMove();
						break;
					}
					if(this.board.isGameOver())
					{
						//JOptionPane.showMessageDialog(null, "Comp wins");
						this.state = RipVanWinkleApplet.STATE_GAME_OVER;
					}
				}
				this.repaint();
			}
		}
	}

	public void mouseEntered(MouseEvent arg0) {}
	public void mouseExited(MouseEvent arg0) {}
	public void mousePressed(MouseEvent arg0) {}
	public void mouseReleased(MouseEvent arg0) {}
}
