/**
 * 
 */
package snake;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;

/**
 * @author Aaron
 * @author Ryan
 *
 */
@SuppressWarnings("serial")
public class GamePanel extends JPanel implements Runnable, KeyListener {
	//Dimensions
	public static final int WIDTH = 640;
	public static final int HEIGHT = 512;
		
	//Properties
	public static final String TITLE = "Snake";
	public static final double VERSION = 1.0;
	private boolean debug = false;
		
	//Image
	private BufferedImage image;
	private Graphics2D g2d;
	
	//Thread
	private Thread thread;
	private boolean running;
	private int TargetFPS = 60;	
	private int FPS;
	private long targetTime = 1000 / TargetFPS;
	
	private Grid grid = new Grid();

	/**
	 * 
	 */
	public GamePanel() {
		//Sets JPanel size
		this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
		this.setFocusable(true);
		this.requestFocus();
	}
	
	/**
	 * Initializes double buffering and grid
	 */
	public void init(){
		image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
		g2d = (Graphics2D) image.getGraphics();
		running = true;
		
		//Initialize grid
		grid.init();
	}
	
	/**
	 * 
	 */
	public void update(){
		//Update the grid
		grid.update();
	}
	
	/**
	 * This method renders to the double buffered image
	 */
	public void render(){		
		//Render the grid
		grid.render(g2d);
		
		//Render the debug menu
		if(debug){
			g2d.setColor(Color.WHITE);
			g2d.drawString("Debug Menu", 5, 15);
			g2d.drawString("fps:" + FPS, 5, 35);
		}
	}
	
	/**
	 * Method to render the double buffered frame
	 */
	public void renderToScreen(){
		Graphics g = this.getGraphics();
		g.drawImage(image, 0, 0, null);
		g.dispose();
	}

	@Override
	public void run() {
		long start;
		long elapsed;
		long delay;
		
		init();
		
		//Game loop
		while(running){
			start = System.nanoTime();
			
			update();
			render();
			renderToScreen();
			
			elapsed = System.nanoTime() - start;
			delay = targetTime - elapsed / 1000000;
			FPS = (int) (1000000000 / elapsed);
			
			if(delay < 0){
				delay = 0;
			}
			
			try{
				Thread.sleep(delay);
			} catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	
	//Initializes thread and listeners
	@Override
	public void addNotify(){
		super.addNotify();
		if(thread == null){
			thread = new Thread(this);
			this.addKeyListener(this);
			//this.addMouseListener(this);
			//this.addMouseMotionListener(this);
			//this.addMouseWheelListener(this);
			thread.start();
		}
	}

	@Override
	public void keyPressed(KeyEvent e) {
		//Debugging Menu
		if(e.getKeyCode() == KeyEvent.VK_BACK_QUOTE){
			if(debug){
				debug = false;
			} else{
				debug = true;
			}
		}
		//Quit
		if(e.getKeyCode() == KeyEvent.VK_ESCAPE){
			System.exit(0);
		}
		if(e.getKeyCode() == KeyEvent.VK_RIGHT || e.getKeyCode() == KeyEvent.VK_D){
			grid.getSnake().setHeadDirectionRequest(1);
		}
		if(e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_A){
			grid.getSnake().setHeadDirectionRequest(3);
		}
		if(e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_W){
			grid.getSnake().setHeadDirectionRequest(0);
		}
		if(e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_S){
			grid.getSnake().setHeadDirectionRequest(2);
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
	}

	@Override
	public void keyTyped(KeyEvent e) {
	}

}

@@ -2942,13 +2942,10 @@
 .VK_
-RIGHT
+UP
  %7C%7C 
@@ -2974,17 +2974,17 @@
 vent.VK_
-D
+W
 )%7B%0A%09%09%09gr
@@ -3021,17 +3021,17 @@
 Request(
-1
+0
 );%0A%09%09%7D%0A%09
@@ -3068,11 +3068,12 @@
 .VK_
-LEF
+RIGH
 T %7C%7C
@@ -3103,17 +3103,17 @@
 vent.VK_
-A
+D
 )%7B%0A%09%09%09gr
@@ -3150,17 +3150,17 @@
 Request(
-3
+1
 );%0A%09%09%7D%0A%09
@@ -3185,34 +3185,36 @@
  == KeyEvent.VK_
-UP
+DOWN
  %7C%7C e.getKeyCode
@@ -3223,33 +3223,33 @@
  == KeyEvent.VK_
-W
+S
 )%7B%0A%09%09%09grid.getSn
@@ -3270,33 +3270,33 @@
 irectionRequest(
-0
+2
 );%0A%09%09%7D%0A%09%09if(e.ge
@@ -3313,36 +3313,36 @@
  == KeyEvent.VK_
-DOWN
+LEFT
  %7C%7C e.getKeyCode
@@ -3351,33 +3351,33 @@
  == KeyEvent.VK_
-S
+A
 )%7B%0A%09%09%09grid.getSn
@@ -3398,33 +3398,33 @@
 irectionRequest(
-2
+3
 );%0A%09%09%7D%0A%09%7D%0A%0A%09@Ove

Fix changed key order