package colro;

import java.awt.AWTException;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.util.ArrayList;

import util.MP3;
import util.WAV;
import world.GameObject;

public class Player extends GameObject {
	
	public Player() {
		fallAcceleration = Double.MAX_VALUE;
	}
	
	public void update() {
		walk();
	}
	
	double speed = 1;
	
	private double height;
	private double currentHeight;
	
	private double seaLevel;
	
	private double walkCycleIncrement = .035;
	
	private double fallAcceleration = Double.MIN_VALUE;
	
	private boolean flying = false;
	private MP3 jet = new MP3("/audio/FX/Jet.mp3");
	
	private void walk() {
		
		if(fallAcceleration == Double.MAX_VALUE) {
			
			camera.setView(0, 1, 0);
			camera.setPosition(0, 2500, 0);
			
			fallAcceleration = 0;
		}
		
		ArrayList<Integer> keysDown = input.getKeysDown();
		
		processMouseGround();
		
		boolean isWalking = false;
		boolean running = false;
		
		for(int i = 0; i < keysDown.size(); i++) {
			
			// walk
			
			if(keysDown.get(i) == KeyEvent.VK_W) {
				camera.move(speed);
				isWalking = true;
			}

			if(keysDown.get(i) == KeyEvent.VK_S) {
				camera.move(-speed);
				isWalking = true;
			}

			if(keysDown.get(i) == KeyEvent.VK_A) {
				camera.strafeHorizontal(-speed);
				isWalking = true;
			}

			if(keysDown.get(i) == KeyEvent.VK_D) {
				camera.strafeHorizontal(speed);
				isWalking = true;
			}
			
			if(flying) {
				
				if(keysDown.get(i) == KeyEvent.VK_E)
					camera.strafeVertical(-speed);

				if(keysDown.get(i) == KeyEvent.VK_Q)
					camera.strafeVertical(speed);
			}
			
			// running
			
			if(keysDown.get(i) == KeyEvent.VK_SHIFT)
				running = true;
			
			// running
			
			if(keysDown.get(i) == KeyEvent.VK_SPACE &&
					fallAcceleration == Double.MIN_VALUE &&
					camera.getYPosition() > seaLevel)
				
				fallAcceleration = 5;
		}
		
//		if(input.getMouseButtons()[2] && fallAcceleration != Double.MIN_VALUE && !flying && gunCoolDown == 0) {
//			
//			fallAcceleration = 0;
//			
//			flying = true;
//			jet.play();
//			
//			gunCoolDown = 25;
//		}
//		
//		if(input.getMouseButtons()[2] && fallAcceleration != Double.MIN_VALUE && flying && gunCoolDown == 0) {
//			
//			flying = false;
//			jet.stop();
//			
//			gunCoolDown = 25;
//		}
		
		if(running)
			speed = 5;
		
		else
			speed = 2;
		
		//stepping sound
		
		if(isWalking)
			
			if(running)
				walkCycleCount += walkCycleIncrement * 1.5;
			
			else
				walkCycleCount += walkCycleIncrement;
		
		// staying withing map borders
		
		if(camera.getXPosition() < -4850)
			camera.setXPosition(-4850);
		
		if(camera.getZPosition() < -4850)
			camera.setZPosition(-4850);
		
		if(camera.getXPosition() > 4850)
			camera.setXPosition(4850);
		
		if(camera.getZPosition() > 4850)
			camera.setZPosition(4850);
		
		if(camera.getYPosition() > 1500)
			camera.setYPosition(1500);
		
		// player height
		
		if(Math.abs(height - currentHeight) > 100)
			currentHeight = height;
		
		if(currentHeight < height)
			
			currentHeight += speed;
		
		if(currentHeight > height)
			
			currentHeight -= speed;
		
		// falling
		
		if(fallAcceleration != Double.MIN_VALUE && !flying) {
			
			camera.setYPosition(camera.getYPosition() + fallAcceleration);
			
			fallAcceleration -= .15;
			
			if(camera.getYPosition() < seaLevel) {
				
				fallAcceleration = Double.MIN_VALUE;
				
				new WAV("/audio/FX/Splash.wav").play(1);
			}
			
			else if(camera.getYPosition() < currentHeight) {
				
				fallAcceleration = Double.MIN_VALUE;
				
				new WAV("/audio/FX/Land.wav").play(1);
			}
		}
		
		if(fallAcceleration == Double.MIN_VALUE && !flying) {
			
			if(height > seaLevel || camera.getYPosition() < height)
				camera.setYPosition(height + 60);
			
			if(height < seaLevel && camera.getYPosition() > seaLevel + 2)
				camera.setYPosition(seaLevel + 2);
			
			walkCycle();
		}
		
		if(flying && camera.getYPosition() < currentHeight) {
			
			camera.setYPosition(currentHeight);
			
			flying = false;
			jet.stop();
			
			new WAV("/audio/FX/Land.wav").play(1);
		}
		
		if(flying && camera.getYPosition() < seaLevel) {
			
			camera.setYPosition(seaLevel);
			
			flying = false;
			jet.stop();
			
			new WAV("/audio/FX/Splash.wav").play(1);
		}
		
		if(camera.getYAngle() == -1 && !flying && height > seaLevel)
			camera.rotate(0, .05);
	}
	
	Robot robot;
	
	private void processMouseGround() {
		
		if(robot == null)
			
			try {
				robot = new Robot();
			}
			
			catch (AWTException exception) {
				exception.printStackTrace();
			}
		
		PointerInfo pointer = MouseInfo.getPointerInfo();
		Point point = pointer.getLocation();
		
		double rotateFactor = 1000;
		
		if(camera.getYAngle() == 1)
			
			camera.rotate((point.getX() - Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2) / rotateFactor,
					(point.getY() - Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2) / -rotateFactor);
		
		else
			
			camera.rotate(-(point.getX() - Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2) / rotateFactor,
					(point.getY() - Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2) / -rotateFactor);
		
		if(camera.getYAngle() == -1 && !flying && height > seaLevel)
			
			camera.rotate(0, (point.getY() - Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2) / rotateFactor);
		
		robot.mouseMove((int)(Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2),
				(int)(Toolkit.getDefaultToolkit().getScreenSize().getHeight()) / 2);
	}
	
	private double walkCycleCount;
	
	private void walkCycle() {
		
		if(walkCycleCount >= 1) {
			
			if(height < seaLevel)
				new WAV("/audio/FX/Swim.wav").play(1);
			
			else
				new WAV("/audio/FX/Walk.wav").play(1);
			
			walkCycleCount = 0;
		}
	}
	
	public void interact(GameObject object) {
		
		 if(object instanceof Map) {
			 
			 height = ((Map) object).getHeightAt(
					 camera.getXPosition(), camera.getZPosition());
			 
			 seaLevel = -5000;
		 }
	}
}