/**
 * PongCanvas contains a Simple Pong game engine.
 *
 * Simple Pong is available for non-commercial use only!
 * 
 * @author      Ziga Hajdukovic
 * @version     1.0
 */

import javax.microedition.lcdui.*;

import com.nokia.mid.ui.FullCanvas;

class PongCanvas extends FullCanvas implements Runnable
{
	private final PongMIDlet midlet;
	
	int canvasWidth;
	int canvasHeight;

	boolean pongRunning;

	public static final int BALL_SIZE = 8;
	// ball position
	int ball_x;
	int ball_y;
	// ball velocity vector
	int ball_vx;
	int ball_vy;

	public static final int PADDLE_WIDTH = 8;
	public static final int PADDLE_HEIGHT = 32;
	// paddle position
	int paddle_x;
	int paddle_y;
	// paddle velocity vector
	int paddle_vy;

	public static final int SOFTKEY_1 = -6;
	public static final int SOFTKEY_2 = -7;
	
	public static boolean command_up;
	public static boolean command_down;
	
	PongCanvas(PongMIDlet midlet)
	{
		this.midlet = midlet;

		canvasWidth = this.getWidth();
		canvasHeight = this.getHeight();

		paddle_x = PADDLE_WIDTH;
		paddle_y = canvasHeight / 2 - PADDLE_HEIGHT / 2;
		paddle_vy = 2;
		
		ball_x = canvasWidth / 2 - BALL_SIZE / 2;
		ball_y = canvasHeight / 2 - BALL_SIZE / 2;
		ball_vx = 3;
		ball_vy = 2;
		
        pongRunning = true;
	}

	public void run()
	{
		while(pongRunning)
		{
			// update ball
			ball_x += ball_vx;
			ball_y += ball_vy;
			
			// detect and handle ball-wall collision
			if ( (ball_y < 0) || ((ball_y + BALL_SIZE) > canvasHeight) )
			{
				ball_vy = -ball_vy;
			}
			if ( ball_x < 0 )
			{
				ball_vx = -ball_vx;
				// TODO: right player scores a point! 
			}
			if ( (ball_x + BALL_SIZE) > canvasWidth )
			{
				ball_vx = -ball_vx;
				// TODO: left player scores a point! 
			}
			 
			// detect and handle for ball-paddle collision
			if ( (ball_x < paddle_x + PADDLE_WIDTH) && 
					(ball_y > paddle_y - BALL_SIZE) && (ball_y < paddle_y + PADDLE_HEIGHT) )
			{
				ball_vx = Math.abs(ball_vx);
			}
			
			if (command_up)
			{
				paddle_y -= paddle_vy;
				if (paddle_y < 0)
					paddle_y = 0;
			}
			if (command_down)
			{	
				paddle_y += paddle_vy;
				if (paddle_y + PADDLE_HEIGHT > canvasHeight)
					paddle_y = canvasHeight - PADDLE_HEIGHT;
			}

			// TODO: update AI paddle

			// 30 ms delay
			try
			{
				Thread.sleep(30);
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
			
			// request a repaint()
			repaint();
			// force pending repaints
			serviceRepaints();
		}
	}
	
	public void paint(Graphics g)
	{
		// set background color
		g.setColor(0x000000);
		// fill background
		g.fillRect(0, 0, canvasWidth, canvasHeight);
		
		// set foreground color
		g.setColor(0x00DD00);
		
		// paint the ball
		g.fillRect(ball_x, ball_y, BALL_SIZE, BALL_SIZE);

		// paint the paddle
		g.fillRect(paddle_x, paddle_y, PADDLE_WIDTH, PADDLE_HEIGHT);
		
		// TODO: paint AI paddle
		
		// TODO: paint score

		// draw keyPressed debug info
		//g.drawString(skey_debug,0,0,Graphics.TOP | Graphics.LEFT);
	}
	
	//String skey_debug = "";
	
	public void keyPressed(int key)
	{
		//skey_debug = ""+key +" / "+ getGameAction(key);
	
		// quit on right softkey press.
		if(key == SOFTKEY_2)
		{
			midlet.exitRequested();
		}
		
		int game_action = getGameAction(key);
		
		switch(game_action)
		{
		case UP:
			command_up = true;
			break;

		case DOWN:
			command_down = true;
			break;
		}
	}
	
	public void keyReleased(int key)
	{
		int game_action = getGameAction(key);

		switch(game_action)
		{
		case UP:
			command_up = false;
			break;

		case DOWN:
			command_down = false;
			break;
		}
	}
}
