package entities;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Animation.PlayMode;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.utils.Array;

import Global.Global;
import effects.HealthBar;
import u.UIDe;
import u.Uinput4;

public class Player4 extends Sprite {
	public enum State {
		STANDLEFT, STANDRIGHT, STANDUP, STANDDOWN, WALKLEFT, WALKRIGHT, WALKUP, WALKDOWN, DUCKLEFT, DUCKRIGHT, DUCKUP, DUCKDOWN, JUMPLEFT, JUMPRIGHT, JUMPUP,
		JUMPDOWN, KICKLEFT, KICKRIGHT, KICKUP, KICKDOWN, DUCKKICKLEFT, DUCKKICKRIGHT, DUCKKICKUP, DUCKKICKDOWN, DYING, BLOCK100, BLOCK75, BLOCK50, BLOCK25, BLOCK0,
		STUNNED
	};

	public State currentState;
	public State previousState;
	private Animation<TextureRegion> walkLeft;
	private Animation<TextureRegion> walkRight;
	private Animation<TextureRegion> walkUp;
	private Animation<TextureRegion> walkDown;
	private Animation<TextureRegion> jumpUp;
	private Animation<TextureRegion> jumpDown;
	private Animation<TextureRegion> jumpLeft;
	private Animation<TextureRegion> jumpRight;
	private Animation<TextureRegion> kickLeft;
	private Animation<TextureRegion> kickRight;
	private Animation<TextureRegion> kickUp;
	private Animation<TextureRegion> kickDown;
	private Animation<TextureRegion> block100;
	private Animation<TextureRegion> block75;
	private Animation<TextureRegion> block50;
	private Animation<TextureRegion> block25;
	private Animation<TextureRegion> block0;
	private Animation<TextureRegion> stunned;
	// private TextureAtlas atlas;
	private Texture t1;
	private TextureRegion standLeft;
	private TextureRegion standRight;
	private TextureRegion standUp;
	private TextureRegion standDown;
	private TextureRegion duckLeft;
	private TextureRegion duckRight;
	private TextureRegion duckUp;
	private TextureRegion duckDown;
	private TextureRegion dying;
	private float _stateTimer;
	public Color color;
	public Rectangle rect;
	public ShapeRenderer sr;
	private boolean isAnimationOver;
	public boolean dead;
	public boolean rmove;
	public boolean lmove;
	public boolean umove;
	public boolean dmove;
	public boolean isDying;
	public static boolean r;
	public static boolean l;
	public static boolean u;
	public static boolean d;
	private int _sw;// sprite width
	private int _sh;// sprite height
	// private Level _level;
	protected int MoveBufferX = 0, MoveBufferY = 0;
	private int fallUpTimer = 10;
	// sfx
	private Sound death;
	private Sound hurt;
	private Sound hurt2;
	private Sound hurt3;
	private Sound hurt4;
	private Sound hurt5;
	private Sound hurt6;
	private Sound sfx_kick;
	private Sound sfx_kick2;
	private Sound sfx_kick3;
	private Sound sfx_kick4;
	private Sound sfx_kick5;
	private Sound sfx_kick6;
	private Sound sfx_jump;
	private Sound sfx_block;
	/// <summary> //i have no idea if this translates. This is from another collider
	/// program because i can't invent this stuff a bizzilions times
	/// Determines how many units represent 1 pixel. Default is 100. Example: A
	/// speed of 100 would
	/// move the object 1 pixel per update.
	/// </summary>
	public int SpeedScale = 100;// this... um. did nothing hehehehahahhaha
	public static Float speed = 300f;// was 400
	private float normSpeed = speed;
	private float diagSpeed = speed - speed / 4;
	private float sprintSpeed = speed * 2;
	private float jumpMax = 10;// 100 worked great! :D
	private float jumpingTimer = jumpMax;
	public boolean isJumping = false;
	public boolean isDucked;
	private boolean isJumped;
	private Float duckSpeed = speed / 2;
	public float swirlingObjects;
	private boolean isKicked;
	public boolean isBlocked;
	public boolean isKicking;
	// private boolean isBlocking;
	private boolean isDown;
	private int isDownTimer = 300;
	public int powerBarMax = 1000;
	public int powerBarNumber = 1000;
	public HealthBar healthBar;
	private float reducer = 2;
	public static int health = 2000;// was 200
	public static int healthMax = 2000;// has to be the same as the health because of how the percentages are calculated
	public static int score = 0;

	public Player4(int _x, int _y) {
		rect = new Rectangle();
		rect.x = _x;
		rect.y = _y;
		rect.width = 20;// 15
		rect.height = 20;// 25

		_sw = 50;// was 80
		_sh = 50;// was 80
		// _level = level;
		System.out.println("x: " + _x + "y: " + _y);

		healthBar = new HealthBar(_x, _y, 20, 2);

		// sounds
		death = Gdx.audio.newSound(Gdx.files.internal("sfx/death.ogg"));
		hurt = Gdx.audio.newSound(Gdx.files.internal("sfx/select.ogg"));
		hurt2 = Gdx.audio.newSound(Gdx.files.internal("sfx/select2.ogg"));
		hurt3 = Gdx.audio.newSound(Gdx.files.internal("sfx/select3.ogg"));
		hurt4 = Gdx.audio.newSound(Gdx.files.internal("sfx/select4.ogg"));
		hurt5 = Gdx.audio.newSound(Gdx.files.internal("sfx/select.ogg"));
		hurt6 = Gdx.audio.newSound(Gdx.files.internal("sfx/select2.ogg"));
		sfx_jump = Gdx.audio.newSound(Gdx.files.internal("sfx/jump.ogg"));
		sfx_block = Gdx.audio.newSound(Gdx.files.internal("sfx/mmm.ogg"));
		sfx_kick = Gdx.audio.newSound(Gdx.files.internal("sfx/kick.ogg"));
		sfx_kick2 = Gdx.audio.newSound(Gdx.files.internal("sfx/kick2.ogg"));
		sfx_kick3 = Gdx.audio.newSound(Gdx.files.internal("sfx/kick3.ogg"));
		sfx_kick4 = Gdx.audio.newSound(Gdx.files.internal("sfx/kick4.ogg"));
		sfx_kick5 = Gdx.audio.newSound(Gdx.files.internal("sfx/kick.ogg"));
		sfx_kick6 = Gdx.audio.newSound(Gdx.files.internal("sfx/kick2.ogg"));
		// this is for the animations
		currentState = State.STANDRIGHT;
		previousState = State.STANDRIGHT;
		_stateTimer = 0f;
		// get Player atlas
		// atlas = new TextureAtlas(Gdx.files.internal("playersheettest.png"));
		t1 = new Texture(Gdx.files.internal("player.png"));
		// declare all the static frames (static states (no animation))
		standLeft = new TextureRegion(t1, (0 * _sw), (0 * _sh), _sw, _sh);
		standRight = new TextureRegion(t1, (1 * _sw), (0 * _sh), _sw, _sh);
		standUp = new TextureRegion(t1, (2 * _sw), (0 * _sh), _sw, _sh);
		standDown = new TextureRegion(t1, (3 * _sw), (0 * _sh), _sw, _sh);
		duckLeft = new TextureRegion(t1, (0 * _sw), (1 * _sh), _sw, _sh);
		duckRight = new TextureRegion(t1, (1 * _sw), (1 * _sh), _sw, _sh);
		duckUp = new TextureRegion(t1, (2 * _sw), (1 * _sh), _sw, _sh);
		duckDown = new TextureRegion(t1, (3 * _sw), (1 * _sh), _sw, _sh);
		dying = new TextureRegion(t1, (3 * _sw), (6 * _sh), _sw, _sh);
		// animated frames
		Array<TextureRegion> frames = new Array<TextureRegion>();
		// TextureRegion l = new TextureRegion(t1, (0 * _sw), (0 * _sh), _sw, _sh);
		// frames.add(l);//i think it's written this way so i could flip them. I don't
		// need to since i already drew it that way...
		// TextureRegion l2 = new TextureRegion(t1, (1 * _sw), (1 * _sh), _sw, _sh);
		// frames.add(l2);
		frames.add(new TextureRegion(t1, (0 * _sw), (0 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (4 * _sw), (0 * _sh), _sw, _sh));
		walkLeft = new Animation<TextureRegion>(.1f, frames, PlayMode.LOOP);
		frames.clear();
		frames.add(new TextureRegion(t1, (1 * _sw), (0 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (5 * _sw), (0 * _sh), _sw, _sh));
		walkRight = new Animation<TextureRegion>(.1f, frames, PlayMode.LOOP);
		frames.clear();
		frames.add(new TextureRegion(t1, (2 * _sw), (0 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (6 * _sw), (0 * _sh), _sw, _sh));
		walkUp = new Animation<TextureRegion>(.1f, frames, PlayMode.LOOP);
		frames.clear();
		frames.add(new TextureRegion(t1, (3 * _sw), (0 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (7 * _sw), (0 * _sh), _sw, _sh));
		walkDown = new Animation<TextureRegion>(.1f, frames, PlayMode.LOOP);
		frames.clear();
		frames.add(new TextureRegion(t1, (0 * _sw), (0 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (4 * _sw), (1 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (5 * _sw), (1 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (6 * _sw), (1 * _sh), _sw, _sh));
		jumpLeft = new Animation<TextureRegion>(.1f, frames, PlayMode.NORMAL);
		frames.clear();
		frames.add(new TextureRegion(t1, (1 * _sw), (0 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (7 * _sw), (1 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (0 * _sw), (2 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (1 * _sw), (2 * _sh), _sw, _sh));
		jumpRight = new Animation<TextureRegion>(.1f, frames, PlayMode.NORMAL);
		frames.clear();
		frames.add(new TextureRegion(t1, (2 * _sw), (0 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (2 * _sw), (2 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (3 * _sw), (2 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (4 * _sw), (2 * _sh), _sw, _sh));
		jumpUp = new Animation<TextureRegion>(.1f, frames, PlayMode.NORMAL);
		frames.clear();
		frames.add(new TextureRegion(t1, (3 * _sw), (0 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (5 * _sw), (2 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (6 * _sw), (2 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (7 * _sw), (2 * _sh), _sw, _sh));
		jumpDown = new Animation<TextureRegion>(.1f, frames, PlayMode.NORMAL);
		frames.clear();
		frames.add(new TextureRegion(t1, (0 * _sw), (3 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (1 * _sw), (3 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (2 * _sw), (3 * _sh), _sw, _sh));
		kickLeft = new Animation<TextureRegion>(.1f, frames, PlayMode.NORMAL);
		frames.clear();
		frames.add(new TextureRegion(t1, (3 * _sw), (3 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (4 * _sw), (3 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (5 * _sw), (3 * _sh), _sw, _sh));
		kickRight = new Animation<TextureRegion>(.1f, frames, PlayMode.NORMAL);
		frames.clear();
		frames.add(new TextureRegion(t1, (6 * _sw), (3 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (7 * _sw), (3 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (0 * _sw), (4 * _sh), _sw, _sh));
		kickUp = new Animation<TextureRegion>(.1f, frames, PlayMode.NORMAL);
		frames.clear();
		frames.add(new TextureRegion(t1, (1 * _sw), (4 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (2 * _sw), (4 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (3 * _sw), (4 * _sh), _sw, _sh));
		kickDown = new Animation<TextureRegion>(.1f, frames, PlayMode.NORMAL);
		frames.clear();
		frames.add(new TextureRegion(t1, (4 * _sw), (4 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (5 * _sw), (4 * _sh), _sw, _sh));
		block100 = new Animation<TextureRegion>(.1f, frames, PlayMode.LOOP);
		frames.clear();
		frames.add(new TextureRegion(t1, (6 * _sw), (4 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (7 * _sw), (4 * _sh), _sw, _sh));
		block75 = new Animation<TextureRegion>(.1f, frames, PlayMode.LOOP);
		frames.clear();
		frames.add(new TextureRegion(t1, (0 * _sw), (5 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (1 * _sw), (5 * _sh), _sw, _sh));
		block50 = new Animation<TextureRegion>(.1f, frames, PlayMode.LOOP);
		frames.clear();
		frames.add(new TextureRegion(t1, (2 * _sw), (5 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (3 * _sw), (5 * _sh), _sw, _sh));
		block25 = new Animation<TextureRegion>(.1f, frames, PlayMode.LOOP);
		frames.clear();
		frames.add(new TextureRegion(t1, (4 * _sw), (5 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (5 * _sw), (5 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (6 * _sw), (5 * _sh), _sw, _sh));
		block0 = new Animation<TextureRegion>(.2f, frames, PlayMode.NORMAL);
		frames.clear();
		frames.add(new TextureRegion(t1, (7 * _sw), (5 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (0 * _sw), (6 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (1 * _sw), (6 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (2 * _sw), (6 * _sh), _sw, _sh));
		stunned = new Animation<TextureRegion>(.2f, frames, PlayMode.LOOP);
		frames.clear();// definitely starts right. then we say, when the line is one length + one _sw
						// worth which would be what in actual numbers?
		// these two are specifically sprite settings to set the sprite's initial bounds
		// and region
		// assign random color
		color = new Color(Color.WHITE);// new Color(MathUtils.random(), MathUtils.random(), MathUtils.random(), 1);
		setBounds(-10, -40, _sw, _sh);
		setRegion(standRight);
		r = true;
	}

	// for all the animations: //this isn't even updated unless i call it from the
	// other screen oh bother. *facepalm*
	public void update(float dt, OrthographicCamera camera) {
		// setRegion(getFrame(dt));
		handleInput(dt, camera);
		checkIfDead();
		Global.P = rect;
		if (UIDe.JustPressed(Uinput4.P4MasterFire())) {// fire button.
			// System.out.println("pressed Kick!");
			isKicked = true;// for kick animation
			isKicking = true;// for actual kick
			if (!Global.SetVolumeToZero)
				playRandomKickSound(6);
		} else if (!isKicking)
			isKicked = false;
		if (UIDe.Pressed(Uinput4.P4MasterInventory())) {// going to use Inventory to 'block'. i think!
			isBlocked = true;// for block animation
			// isBlocking = true;// actually blocking
			// System.out.println("rect.x: " + rect.x);
			// System.out.println("rect.y: " + rect.y);
			if (!Global.SetVolumeToZero)
				sfx_block.play(.1f);// thinking a "mmmmm" sound that's quiet, a kind of focus. The actual reflect will be a ping by the projectile.
		} else if (!isDown)
			isBlocked = false;
		if (UIDe.Pressed(Uinput4.P4MasterJump()) && !isJumping && !isBlocked && !isKicking) {
			isJumped = true;// for jump animation
			isJumping = true;// for actual jump
			reducer = 2;
			// System.out.println("jump! " + isJumped);
			if (!Global.SetVolumeToZero)
				sfx_jump.play();
		} else if (!isJumping)
			isJumped = false;
		if (UIDe.Pressed(Uinput4.P4MasterCrouch()) && !isJumping && !isBlocked && !isKicking) {
			isDucked = true;
			// System.out.println("duck! " + isDucked);
		} else
			isDucked = false;
		checkIfAnimationsAreDone();
		if (isDown && isDownTimer > 0) {
			isDownTimer--;
			powerBarNumber += 4;// this is for charging a bar possibly!
		}
		if (isDown && isDownTimer <= 0) {
			isDown = false;
			powerBarNumber = 1000; // ( i guess 100?);
			isDownTimer = 300;
		}
//		System.out.println("isKicking: " + isKicking);
//		System.out.println("isBlocking: " + isBlocking);
//		System.out.println("isJumping: " + isJumping);
//		System.out.println("isDucked: " + isDucked);
	}

	private void checkIfAnimationsAreDone() {
		if (isKicking) {
			if (currentState == State.KICKLEFT) {
//				kickLeft.getAnimationDuration();
//				System.out.println("kickLeft: getAnimationDuration: " + kickLeft.getAnimationDuration());
//				kickLeft.getFrameDuration();
//				System.out.println("kickLeft: getFrameDuration: " + kickLeft.getFrameDuration());
//				kickLeft.getKeyFrame(_stateTimer);
//				System.out.println("kickLeft: getFrameDuration(stateTimer): " + kickLeft.getKeyFrame(_stateTimer));
//				kickLeft.getKeyFrameIndex(_stateTimer);
//				System.out.println("kickLeft: getKeyFrameIndex(stateTimer): " + kickLeft.getKeyFrameIndex(_stateTimer));
//				kickLeft.getKeyFrames();
//				System.out.println("kickLeft: getKeyFrames: " + kickLeft.getKeyFrames());
//				kickLeft.isAnimationFinished(_stateTimer);
//				System.out.println("kickLeft: isAnimationFinished(stateTimer): " + kickLeft.isAnimationFinished(_stateTimer));
				if (kickLeft.isAnimationFinished(_stateTimer))
					isKicking = false;
			}
			if (currentState == State.KICKRIGHT) {
				if (kickRight.isAnimationFinished(_stateTimer))
					isKicking = false;
			}
			if (currentState == State.KICKUP) {
				if (kickUp.isAnimationFinished(_stateTimer))
					isKicking = false;
			}
			if (currentState == State.KICKDOWN) {
				if (kickDown.isAnimationFinished(_stateTimer))
					isKicking = false;
			}
		}
		if (currentState == State.BLOCK0) {
			if (block0.isAnimationFinished(_stateTimer)) {
				isDown = true;// this is to triggers animation and NOT getting up
			}

		}

	}

	public void checkIfDead() {
		if (dead) {
			rmove = false;
			lmove = false;
			umove = false;
			dmove = false;
		}
		if (isBlocked) {
			rmove = false;
			lmove = false;
			umove = false;
			dmove = false;
		}

	}

	public TextureRegion getFrame(float dt, OrthographicCamera camera) {
		// System.out.println("getting frame: " + getState());
		// System.out.println("_stateTimer: " + _stateTimer);
		// System.out.println("animation Index: " + walkLeft.getKeyFrame(_stateTimer));
		update(dt, camera);
		currentState = getState();
		// System.out.println("state: " + currentState);
		TextureRegion region;
		switch (currentState) {
		case WALKRIGHT:
			region = walkRight.getKeyFrame(_stateTimer, true);
			break;
		case WALKLEFT:
			region = walkLeft.getKeyFrame(_stateTimer, true);
			break;
		case WALKUP:
			region = walkUp.getKeyFrame(_stateTimer, true);
			break;
		case WALKDOWN:
			region = walkDown.getKeyFrame(_stateTimer, true);
			break;
		case DUCKLEFT:
			region = duckLeft;
			break;
		case DUCKRIGHT:
			region = duckRight;
			break;
		case DUCKUP:
			region = duckUp;
			break;
		case DUCKDOWN:
			region = duckDown;
			break;
		case JUMPLEFT:
			region = jumpLeft.getKeyFrame(_stateTimer, false);
			break;
		case JUMPRIGHT:
			region = jumpRight.getKeyFrame(_stateTimer, false);
			break;
		case JUMPUP:
			region = jumpUp.getKeyFrame(_stateTimer, false);
			break;
		case JUMPDOWN:
			region = jumpDown.getKeyFrame(_stateTimer, false);
			break;
		case STANDLEFT:
			region = standLeft;
			break;
		case STANDUP:
			region = standUp;
			break;
		case STANDDOWN:
			region = standDown;
			break;
		case KICKLEFT:
			region = kickLeft.getKeyFrame(_stateTimer, false);
			break;
		case KICKRIGHT:
			region = kickRight.getKeyFrame(_stateTimer, false);
			break;
		case KICKUP:
			region = kickUp.getKeyFrame(_stateTimer, false);
			break;
		case KICKDOWN:
			region = kickDown.getKeyFrame(_stateTimer, false);
			break;
		case BLOCK100:
			region = block100.getKeyFrame(_stateTimer, true);
			break;
		case BLOCK75:
			region = block75.getKeyFrame(_stateTimer, true);
			break;
		case BLOCK50:
			region = block50.getKeyFrame(_stateTimer, true);
			break;
		case BLOCK25:
			region = block25.getKeyFrame(_stateTimer, true);
			break;
		case BLOCK0:
			region = block0.getKeyFrame(_stateTimer, false);
			break;
		case STUNNED:
			region = stunned.getKeyFrame(_stateTimer, true);
			break;
		case DYING:
			region = dying;
			break;
		case STANDRIGHT:
		default:
			region = standRight;
			break;
		}
		if (currentState != previousState)
			isAnimationOver = false;

		if (!isAnimationOver && currentState == previousState) {
			_stateTimer += dt;
		} else
			_stateTimer = 0;
		// System.out.println("statetimer: " + _stateTimer);
		previousState = currentState;

		return region;
	}

	public State getState() {
		// System.out.println("l: " + l + " r: " + r + " u: " + u + " d: " + d);
		// System.out.println("lmove: " + lmove + " rmove: " + rmove + " umove: " +
		// umove + " dmove: " + dmove);
		if (isDying)
			return State.DYING;
		else if (isDown)
			return State.STUNNED;
		else if (isBlocked && powerBarNumber > powerBarMax * .75)
			return State.BLOCK100;
		else if (isBlocked && powerBarNumber > powerBarMax * .50)
			return State.BLOCK75;
		else if (isBlocked && powerBarNumber > powerBarMax * .25)
			return State.BLOCK50;
		else if (isBlocked && powerBarNumber > 0)
			return State.BLOCK25;
		else if (powerBarNumber <= 0)
			return State.BLOCK0;
		else if (isKicked && l)
			return State.KICKLEFT;
		else if (isKicked && r)
			return State.KICKRIGHT;
		else if (isKicked && u)
			return State.KICKUP;
		else if (isKicked && d)
			return State.KICKDOWN;
		else if (isDucked && lmove)
			return State.DUCKLEFT;
		else if (isDucked && rmove)
			return State.DUCKRIGHT;
		else if (isDucked && umove)
			return State.DUCKUP;
		else if (isDucked && dmove)
			return State.DUCKDOWN;
		else if (isDucked && l)
			return State.DUCKLEFT;
		else if (isDucked && r)
			return State.DUCKRIGHT;
		else if (isDucked && u)
			return State.DUCKUP;
		else if (isDucked && d)
			return State.DUCKDOWN;
		else if (isJumped && lmove)
			return State.JUMPLEFT;
		else if (isJumped && rmove)
			return State.JUMPRIGHT;
		else if (isJumped && umove)
			return State.JUMPUP;
		else if (isJumped && dmove)
			return State.JUMPDOWN;
		else if (isJumped && l)
			return State.JUMPLEFT;
		else if (isJumped && r)
			return State.JUMPRIGHT;
		else if (isJumped && u)
			return State.JUMPUP;
		else if (isJumped && d)
			return State.JUMPDOWN;
		else if (l && lmove && umove || l && lmove && dmove)
			return State.WALKLEFT;
		else if (r && rmove && dmove || r && rmove && umove)
			return State.WALKRIGHT;
		else if (u && umove && lmove || u && umove && rmove)
			return State.WALKUP;
		else if (d && dmove && lmove || d && dmove && rmove)
			return State.WALKDOWN;
		else if (lmove)
			return State.WALKLEFT;
		else if (rmove)
			return State.WALKRIGHT;
		else if (umove)
			return State.WALKUP;
		else if (dmove)
			return State.WALKDOWN;
		else if (l)
			return State.STANDLEFT;
		else if (r)
			return State.STANDRIGHT;
		else if (u)
			return State.STANDUP;
		else if (d)
			return State.STANDDOWN;
		else
			return State.STANDRIGHT;
	}

	private void handleInput(float dt, OrthographicCamera camera) {
		boolean isCT = false;// collision tile

		if (UIDe.Pressed(Uinput4.P4MasterRight())) {
			if (isBlocked | isDown | rect.x >= 1551)// if you use | it will evaluate both sides of the or.
				isCT = true;
			else
				isCT = false;
			// isCT = (GetTileYouWillBeOn("right", dt)) ? true : false;// right
			MoveRight(speed, isCT, dt);
			l = false;
			r = true;
			u = false;
			d = false;
			rmove = true;
		} else
			rmove = false;
		if (UIDe.Pressed(Uinput4.P4MasterLeft())) {// this is going to get crazy. This room is NOT shaped like a square! :O
			if (isBlocked | isDown | rect.x <= 53)
				isCT = true;
			else
				isCT = false;
			// isCT = (GetTileYouWillBeOn("left", dt)) ? true : false;// left
			MoveLeft(speed, isCT, dt);
			l = true;
			r = false;
			u = false;
			d = false;
			lmove = true;
		} else
			lmove = false;
		if (UIDe.Pressed(Uinput4.P4MasterUp())) {
			if (isBlocked | isDown | rect.y >= 815)
				isCT = true;
			else
				isCT = false;
			// isCT = (GetTileYouWillBeOn("up", dt)) ? true : false;
			MoveUp(speed, isCT, dt);
			u = true;
			d = false;
			l = false;
			r = false;
			umove = true;
		} else
			umove = false;
		if (UIDe.Pressed(Uinput4.P4MasterDown())) {
			if (isBlocked | isDown | rect.y <= 41)
				isCT = true;
			else
				isCT = false;
			// isCT = (GetTileYouWillBeOn("down", dt)) ? true : false;// down
			MoveDown(speed, isCT, dt);
			u = false;
			d = true;
			l = false;
			r = false;
			dmove = true;
		} else
			dmove = false;
		if (isDying)
			MoveFalling(speed, dt);
		// diag catches.// priority is top to bottom
		if (UIDe.Pressed(Uinput4.P4MasterSprint()))
			speed = sprintSpeed;
		else
			speed = normSpeed;
		if (isDucked)
			speed = duckSpeed;
		if (umove && lmove || umove && rmove || dmove && lmove || dmove && rmove) {
			if (speed == sprintSpeed)
				speed = sprintSpeed - sprintSpeed / 4;
			else if (speed == duckSpeed)
				speed = duckSpeed - duckSpeed / 4;
			else
				speed = diagSpeed;
		} else if (sprintSpeed != speed && duckSpeed != speed)
			speed = normSpeed;
		if (isJumping)
			Jumping(speed, dt);
		// System.out.println("speeed: " + speed);
	}

	public void MoveFalling(float speed, float dt) {
		if (fallUpTimer > 0) {
			rect.y += speed * 4 * dt;
			fallUpTimer--;
			if (!Global.SetVolumeToZero)
				death.play();
		} else
			rect.y -= 4 * speed * dt;
	}

	public void Jumping(float speed, float dt) {
		if (rect.y <= 41) {// this is buggy but at least you don't jump out of the map. :-)
			rect.y += 1;
		} else {
			if (jumpingTimer > 0) {
				reducer -= .01;
				rect.y += speed * reducer * dt;
			} else {
				rect.y -= reducer * speed * dt;
				reducer += .01;
			}
			if (jumpingTimer <= -jumpMax) {
				jumpingTimer = jumpMax;
				isJumping = false;
			}
			jumpingTimer--;
		}
	}

	public void MoveRight(float speed, boolean isColl, float dt) {
		if (isColl)
			rect.x -= 0;
		else
			rect.x += speed * dt;
		// rect.add(velocity);
		// rect.x.add(velocity);
		// rect.setPosition(position)
		// rect.getPosition(position)
	}

	public void MoveLeft(float speed, boolean isColl, float dt) {
		// test this:
		if (isColl)
			rect.x += 0;
		else
			rect.x -= speed * dt;
	}

	public void MoveUp(float speed, boolean isColl, float dt) {
		// test this:
		if (isColl)
			rect.y -= 0;
		else
			rect.y += speed * dt;
	}

	public void MoveDown(float speed, boolean isColl, float dt) {
		// test this:
		if (isColl)
			rect.y += 0;
		else
			rect.y -= speed * dt;
	}

	public void playRandomHurtSound(int numberOfSounds) {
		int randomSound = MathUtils.random(1, numberOfSounds);
		if (!Global.SetVolumeToZero) {
			if (randomSound == 1)
				hurt.play();
			else if (randomSound == 2)
				hurt2.play();
			else if (randomSound == 3)
				hurt3.play();
			else if (randomSound == 4)
				hurt4.play();
			else if (randomSound == 5)
				hurt5.play();
			else if (randomSound == 6)
				hurt6.play();
		}
	}

	public void playRandomKickSound(int numberOfSounds) {
		int randomSound = MathUtils.random(1, numberOfSounds);
		if (!Global.SetVolumeToZero) {
			if (randomSound == 1)
				sfx_kick.play(.2f);
			else if (randomSound == 2)
				sfx_kick2.play(.2f);
			else if (randomSound == 3)
				sfx_kick3.play(.2f);
			else if (randomSound == 4)
				sfx_kick4.play(.2f);
			else if (randomSound == 5)
				sfx_kick5.play(.2f);
			else if (randomSound == 6)
				sfx_kick6.play(.2f);
		}
	}

	public void dispose() {
		death.dispose();
		hurt.dispose();
		hurt2.dispose();
		hurt3.dispose();
		hurt4.dispose();
		hurt5.dispose();
		hurt6.dispose();
		sfx_jump.dispose();
		sfx_kick.dispose();
		sfx_kick2.dispose();
		sfx_kick3.dispose();
		sfx_kick4.dispose();
		sfx_kick5.dispose();
		sfx_kick6.dispose();
		sfx_block.dispose();
	}
}
