// Workshop 3 part 2

import sdljava.*;
import sdljava.video.*;
import sdljava.event.*;

class s03_p02
{
		// Our SDL surface for drawing on
	protected static SDLSurface screen;

		// The speed of our object
	protected static float speed_x, speed_y, max_speed;

		// The position of our object
	protected static float position_x, position_y;


		// We will call this function whenever we want to exit the program.
		// It uninitialises SDL and forces a program exit.
	public static void exit(int value)
	{
		SDLMain.quit();
		System.out.println("Exiting..");
		System.exit(value);
	}

		// In this function, we retrieve and handle events.
		// The function returns true if the user wishes to exit the program.
	public static boolean handle_events()
	{
		try
		{
			// SDL stores events in a queue.
			// To look at events we have two options:
			//  1. We can wait for events, in which case we call a function that will not return until there is an event.
			//  2. We can have a quick look at the event queue, using a function that will retrieve an event if there is one, returning null if there isn't.
			//
			// In an interactive game, it's not much use if we get stuck waiting for events, as we won't be able to draw or update the scene.
			// Therefore, we want to use the 'quick look' option.
			// This is called polling for events.
			// The waiting technique is known as blocking.
			// Both methods remove the oldest event from the queue and give it to us to decide what to do with it.

				// Poll for events
			SDLEvent event = SDLEvent.pollEvent();

				// If there was an event..
			if( event != null )
					// What we do depends on the type
				switch( event.getType() )
				{
					case SDLEvent.SDL_QUIT:
							// This event type is generated when the user clicks on the 'x' to close the window.
							// We want to exit our handle_events function, returning true to indicate that the user wishes to quit.
						return true;

					case SDLEvent.SDL_KEYDOWN: // The user has pressed a key
						{
								// This means that the event is actually of a sub-type called an SDLKeyboardEvent.
								// If we cast the event to this type, we can retrieve the actual key type
							int key = ((SDLKeyboardEvent) event).getSym();

								// What we do now depends on the key that was pressed
							switch( key )
							{
								case SDLKey.SDLK_ESCAPE:
									exit(0);
								case SDLKey.SDLK_UP:
									speed_y += -max_speed;
									break;
								case SDLKey.SDLK_DOWN:
									speed_y += max_speed;
									break;
								case SDLKey.SDLK_LEFT:
									speed_x += -max_speed;
									break;
								case SDLKey.SDLK_RIGHT:
									speed_x += max_speed;
									break;
								default:
									System.out.println(key);
							}
						}
						break;

					case SDLEvent.SDL_KEYUP: // The user has released a key
						{
								// This means that the event is actually of a sub-type called an SDLKeyboardEvent.
								// If we cast the event to this type, we can retrieve the actual key type
							int key = ((SDLKeyboardEvent) event).getSym();

								// What we do now depends on the key that was pressed
							switch( key )
							{
								case SDLKey.SDLK_UP:
									speed_y -= -max_speed;
									break;
								case SDLKey.SDLK_DOWN:
									speed_y -= max_speed;
									break;
								case SDLKey.SDLK_LEFT:
									speed_x -= -max_speed;
									break;
								case SDLKey.SDLK_RIGHT:
									speed_x -= max_speed;
									break;

								// Letter keys are: SDLK_[letter] e.g. SDLK_g is g
								// See the SDL Java documentation for more details: http://sdljava.sourceforge.net/docs/api/
							}
						}
						break;

					case SDLEvent.SDL_MOUSEBUTTONDOWN: // The user has pressed a mouse button
						break;

					case SDLEvent.SDL_MOUSEBUTTONUP: // The user has released a mouse button
						break;
				}

		}
		catch(SDLException e)
		{
				System.err.println("Error while polling event : " + SDLMain.getError());
  				exit(1);
		}

		return false;

	}

		// In this function, we update our scene
	public static void update( float deltaT_s )
	{
			// Update the position of our object
		position_x +=  deltaT_s * speed_x;
		position_y +=  deltaT_s * speed_y;
	}

		// In this function, we draw our scene
		// Upon encountering an error, this function throws an SDLException, which is passed on from SDL function calls
	public static void draw() throws sdljava.SDLException
	{
			// First, we clear the screen
		screen.fillRect(screen.mapRGB(0,0,0));
			// Our object will be a rectangle, so create it at the correct position
		SDLRect rectangle = new SDLRect((int)position_x,(int)position_y,30,10);
			// Draw it, specifying the colour
		screen.fillRect(rectangle,screen.mapRGB(255,255,255));

			// That flip command again..
		screen.flip();
	}


	public static void main(String[] args)
	{
			// Initialise our variables to zero
		speed_x = speed_y = 0.0f;

			// The maximum speed of our object: this is in pixels per second
		max_speed = 400.0f;

			// The initial position of our object.
			// This should put it in the centre of the window
		position_x = 320;
		position_y = 240;

			// Create an SDLMain object
		SDLMain sdl = new SDLMain();

			// SDL uses exceptions when it encounters problems
		try
		{
				// Initialise SDL to use its video (graphics) capabilities
			sdl.init(SDLMain.SDL_INIT_VIDEO);
				// SDL uses what it calls a 'surface' as a window.
			screen = SDLVideo.setVideoMode(640, 480, 0, 0 );

				// Timing is one of the most crucial aspects of an interactive game-like program.
				// Since the graphics on screen can take a variable amount of time to draw,
				// we cannot rely on a constant frame rate. Besides, if we run our program on a
				// faster or slower machine, it will be different anyway.
				// We must therefore calculate the amount of time that has elapsed between each 
				// iteration of our game loop, and use this when we update our scene.
			long previous_time = 0, current_time = 0, deltaT = 0;
			float deltaT_s = 0.0f; // (delta in mathematics means 'change', so this is the change in time, measured in seconds)

				// Retrieves the time
			current_time = System.currentTimeMillis();
			previous_time = current_time;

				// This will store whether or not the user has asked to quit
			boolean quit = false;

				// This is our main "game loop", and we will run it 
				// while we've not been asked to quit...
			while( quit == false )
			{

					// When the user presses a key, or uses the mouse, that input is stored in SDL as an 'event'.
					// As an interactive program, we need to look at these events and decide what to do about them.
					// Our function here also returns true if we want to quit:
				quit = handle_events();
	
					// In an interactive program, be it a game or whatever, we usually have a variety of things to update each frame.
					// These could be character animations, physics simulations, explosions, whatever we want...
				update(deltaT_s);
	
					// Finally, we need to draw our scene
				draw();

					// Update our current time
				current_time = System.currentTimeMillis();
					// Work out the frame time for that frame
				deltaT_s = (float)(current_time-previous_time)/1000.0f;
					// For the next frame, our current time will the the previous one
				previous_time = current_time;

			}

			exit(0);

		}
		catch(SDLException e) // Catch SDL problems
		{
				// We shall handle any problems by printing a stack trace:
			e.printStackTrace();
				// and an explanation if that wasn't enough
			System.err.println("SDL encountered a problem");
			exit(1);
		}

		
	}
}