package entities;

import java.util.HashMap;
import java.util.Iterator;
import java.util.UUID;

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.math.MathUtils;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.ld58.game.rcr;

import Global.Global;
import effects.HealthBar;
import levelElements.Bread;
import u.UsefulMethods;
import unearthables.Amethyst;
import unearthables.Copper;
import unearthables.Diamond;
import unearthables.Food;
import unearthables.Gold;
import unearthables.Platinum;
import unearthables.Ruby;
import unearthables.Sapphire;
import unearthables.Silver;
import unearthables.Topaz;

public class Student extends Sprite {
	public enum State {
		WALKLEFT, WALKRIGHT, DEAD, MAIN
	};

	public State currentState;
	public State previousState;
	private Animation<TextureRegion> walkLeft;
	private Animation<TextureRegion> walkRight;
	public int health = 100;
	public int healthMax = 100;
	// private TextureAtlas atlas;
	private Texture t1;
	private TextureRegion main;
	private TextureRegion dying;
	public Color color;
	public Float speed = MathUtils.random(100f, 200f);// was 400
	public Rectangle rect;
	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
	protected int MoveBufferX = 0, MoveBufferY = 0;
	// sfx
	private Sound sfx_death;
	private Sound hurt;
	private Sound hurt2;
	private Sound hurt3;
	private Sound hurt4;
	private Sound hurt5;
	private Sound hurt6;
	private Sound hurt7;
	private Sound hurt8;
	private Sound hurt9;
	private Sound hurt10;
	private Sound hurt11;
	private Sound hurt12;
	private Sound hurt13;
	private Sound hurt14;
	private Sound hurt15;
	private Sound hurt16;
	private Sound hurt17;
	private Sound hurt18;
	private Sound hurt19;
	private Sound hurt20;
	private Sound hurt21;
	private Sound hurt22;
	private Sound hurt23;
	private Sound eat;
	private Sound eat2;
	private Sound eat3;
	private Sound eat4;
	private Sound eat5;
	private Sound eat6;
	private Sound eat7;
	private Sound eat8;
	private Sound eat9;
	private Sound eat10;
	private Sound eat11;
	private Sound death;
	private Sound death2;
	private Sound death3;
	private Sound death4;
	private Sound death5;
	private Sound death6;
	private Sound death7;
	private Sound death8;
	private Sound death9;
	private Sound death10;
	private Sound death11;
	private Sound death12;
	private Sound death13;
	private Sound death14;
	private Sound death15;
	private Sound roar;
	private Sound roar2;
	private Sound roar3;
	private Sound roar4;
	private Sound roar5;
	public int SpeedScale = 20;
	public boolean isJumping = false;
	// testing vectors
	Vector2 position = new Vector2();
	Vector2 velocity = new Vector2();
	Vector2 movement = new Vector2();
	Vector2 touch = new Vector2();
	Vector2 dir = new Vector2();
	// private Float duckSpeed = speed / 2;
	public Vector2 sp = new Vector2(0, 0);
	public Vector2 ep = new Vector2(0, 0);
	public boolean isWait = true;
	public boolean getDir;
	public boolean isDead;
	public boolean isEating;
	public boolean isFat;
	private int isDyingTimer;
	private boolean playOnce;
	private float targetX;
	private float targetY;
	private int walkTimer;
	private int walkTimerMax = MathUtils.random(10, 200);// was 10, 200
	private boolean isChosen;
	public boolean canHit = true;
	private boolean isOneEatSound;
	public HealthBar healthBar;
	public int amethystStockpile;
	public int copperStockpile;
	public int diamondStockpile;
	public int goldStockpile;
	public int platinumStockpile;
	public int rubyStockpile;
	public int sapphireStockpile;
	public int silverStockpile;
	public int topazStockpile;
	public UUID uuid = UUID.randomUUID();
	private int fallUpTimer = 10;
	private float _stateTimer;
	private boolean isAnimationOver;
	public boolean isHolding;

	public Student(int _x, int _y) {
		rect = new Rectangle();
		rect.x = _x;
		rect.y = _y;
		rect.width = 50;
		rect.height = 50;

		_sw = 50;
		_sh = 50;
		healthBar = new HealthBar(_x, _y, 50, 2);

		if (MathUtils.random(1, 2) == 1)
			isChosen = true;
		// _level = level;

		// set location and intial velocities?
		position.set(rect.getX(), rect.getY());
		// sounds
		sfx_death = Gdx.audio.newSound(Gdx.files.internal("sfx/death.ogg"));
		hurt = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt.ogg"));
		hurt2 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt2.ogg"));
		hurt3 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt3.ogg"));
		hurt4 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt4.ogg"));
		hurt5 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt5.ogg"));
		hurt6 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt6.ogg"));
		hurt7 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt7.ogg"));
		hurt8 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt8.ogg"));
		hurt9 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt9.ogg"));
		hurt10 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt10.ogg"));
		hurt11 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt11.ogg"));
		hurt12 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt12.ogg"));
		hurt13 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt13.ogg"));
		hurt14 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt14.ogg"));
		hurt15 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt15.ogg"));
		hurt16 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt16.ogg"));
		hurt17 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt17.ogg"));
		hurt18 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt18.ogg"));
		hurt19 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt19.ogg"));
		hurt20 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt20.ogg"));
		hurt21 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt21.ogg"));
		hurt22 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt22.ogg"));
		hurt23 = Gdx.audio.newSound(Gdx.files.internal("sfx/hurt23.ogg"));
		eat = Gdx.audio.newSound(Gdx.files.internal("sfx/eat.ogg"));
		eat2 = Gdx.audio.newSound(Gdx.files.internal("sfx/eat2.ogg"));
		eat3 = Gdx.audio.newSound(Gdx.files.internal("sfx/eat3.ogg"));
		eat4 = Gdx.audio.newSound(Gdx.files.internal("sfx/eat4.ogg"));
		eat5 = Gdx.audio.newSound(Gdx.files.internal("sfx/eat5.ogg"));
		eat6 = Gdx.audio.newSound(Gdx.files.internal("sfx/eat6.ogg"));
		eat7 = Gdx.audio.newSound(Gdx.files.internal("sfx/eat7.ogg"));
		eat8 = Gdx.audio.newSound(Gdx.files.internal("sfx/eat8.ogg"));
		eat9 = Gdx.audio.newSound(Gdx.files.internal("sfx/eat9.ogg"));
		eat10 = Gdx.audio.newSound(Gdx.files.internal("sfx/eat10.ogg"));
		eat11 = Gdx.audio.newSound(Gdx.files.internal("sfx/eat11.ogg"));
		death = Gdx.audio.newSound(Gdx.files.internal("sfx/death.ogg"));
		death2 = Gdx.audio.newSound(Gdx.files.internal("sfx/death2.ogg"));
		death3 = Gdx.audio.newSound(Gdx.files.internal("sfx/death3.ogg"));
		death4 = Gdx.audio.newSound(Gdx.files.internal("sfx/death4.ogg"));
		death5 = Gdx.audio.newSound(Gdx.files.internal("sfx/death5.ogg"));
		death6 = Gdx.audio.newSound(Gdx.files.internal("sfx/death6.ogg"));
		death7 = Gdx.audio.newSound(Gdx.files.internal("sfx/death7.ogg"));
		death8 = Gdx.audio.newSound(Gdx.files.internal("sfx/death8.ogg"));
		death9 = Gdx.audio.newSound(Gdx.files.internal("sfx/death9.ogg"));
		death10 = Gdx.audio.newSound(Gdx.files.internal("sfx/death10.ogg"));
		death11 = Gdx.audio.newSound(Gdx.files.internal("sfx/death11.ogg"));
		death12 = Gdx.audio.newSound(Gdx.files.internal("sfx/death12.ogg"));
		death13 = Gdx.audio.newSound(Gdx.files.internal("sfx/death13.ogg"));
		death14 = Gdx.audio.newSound(Gdx.files.internal("sfx/death14.ogg"));
		death15 = Gdx.audio.newSound(Gdx.files.internal("sfx/death15.ogg"));
		roar = Gdx.audio.newSound(Gdx.files.internal("sfx/roar.ogg"));
		roar2 = Gdx.audio.newSound(Gdx.files.internal("sfx/roar2.ogg"));
		roar3 = Gdx.audio.newSound(Gdx.files.internal("sfx/roar3.ogg"));
		roar4 = Gdx.audio.newSound(Gdx.files.internal("sfx/roar4.ogg"));
		roar5 = Gdx.audio.newSound(Gdx.files.internal("sfx/roar5.ogg"));

		t1 = new Texture(Gdx.files.internal("student.png"));
		main = new TextureRegion(t1, (0 * _sw), (0 * _sh), _sw, _sh);
		dying = new TextureRegion(t1, (6 * _sw), (0 * _sh), _sw, _sh);
		// animated frames
		Array<TextureRegion> frames = new Array<TextureRegion>();
		frames.add(new TextureRegion(t1, (2 * _sw), (0 * _sh), _sw, _sh));
		frames.add(new TextureRegion(t1, (3 * _sw), (0 * _sh), _sw, _sh));
		walkLeft = new Animation<TextureRegion>(.1f, frames, PlayMode.LOOP);
		frames.clear();
		frames.add(new TextureRegion(t1, (4 * _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();
		color = new Color(MathUtils.random(.1f, 1f), MathUtils.random(.1f, 1f), MathUtils.random(.1f, 1f), 1);
		setBounds(0, 0, _sw, _sh);
		setRegion(main);
		r = true;
	}

	public Vector2 GetDirection(Vector2 sp, Vector2 ep) {
		return ep.sub(sp).nor();
	}

	// 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, Array<Amethyst> amethystGems, Array<Copper> copperMetals, Array<Diamond> diamondGems,
			Array<Food> foodHealth, Array<Gold> goldMetals, Array<Platinum> platinumMetals, Array<Ruby> rubyGems, Array<Sapphire> sapphireGems,
			Array<Silver> silverMetals, Array<Topaz> topazGems, Bread bread) {

		if (isDying && isDyingTimer > 0) {
			if (!Global.SetVolumeToZero && !playOnce) {
				playOnce = true;
				playRandomDeathSound(15);
			}
			isDyingTimer--;
			MoveFalling(speed, dt);
		} else {
			if (isDying && isDyingTimer <= 0) {
				isDead = true;
			}
			if (isDead) {
				rect.x += 0;
				rect.y += 0;
				playOnce = false;
				isHolding = false;
			} else {
				if (walkTimer <= 0) {
					walkTimer = walkTimerMax;
					sp = new Vector2(rect.x, rect.y);
					// System.out.println("bread.uuid: " + bread.uuid + " uuid: " + uuid);
					if (bread.uuid == uuid) {// if you have the bread walk away
						sp = new Vector2(Global.P.x, Global.P.y);
						ep = new Vector2(rect.x, rect.y);
						dir = GetDirection(sp, ep);
					} else if (!bread.isCarriedByPlayer && Global.WhatLevel != 1 && !bread.isCarried) {// make sure it's not going to it on the first level
						ep = new Vector2(bread.rect.x, bread.rect.y);
						dir = GetDirection(sp, ep);
					} else if (bread.isCarriedByPlayer && Global.WhatLevel != 1) {// make sure it's not going to it on the first level
						ep = new Vector2(Global.P.x, Global.P.y);
						dir = GetDirection(sp, ep);
					} else if (!isFat) {// go towards the closest gem or money wait till the player has his gun working, them mimic it here. :P
						getClosestEnemy(amethystGems, copperMetals, diamondGems, foodHealth, goldMetals, platinumMetals, rubyGems, sapphireGems, silverMetals,
								topazGems);
						ep = new Vector2(targetX, targetY);
						dir = GetDirection(sp, ep);
					} else {// go to the corner. bye bye this is just funny. lol. how about the center?
						// System.out.println("rectX: " + rect.x + "rectY: " + rect.y);
						ep = new Vector2(0, 0 + MathUtils.random(rcr.MH / 2, rcr.MW / 2));
						// System.out.println("sp go to corner?: " + sp + "ep go to corner? what?: " + ep);
						dir = GetDirection(sp, ep);
					}
				}
				if (walkTimer > 0)
					walkTimer--;
				// System.out.println("sp: " + sp + "ep: " + ep);
				rect.x += dir.x * speed * dt;
				rect.y += dir.y * speed * dt;
				// if offscreen
				if (rect.x < 0)
					rect.x = rcr.MW;
				if (rect.x > rcr.MW)
					rect.x = 0;
				if (rect.y < 0)
					rect.y = rcr.MH;
				if (rect.y > rcr.MH)
					rect.y = 0;
			}
		}
		checkIfAnimationsAreDone();
		getCorrectWalkingAnimation(dt);
		// System.out.println("isDead: " + isDead);
	}

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

	private void checkIfAnimationsAreDone() {
		if (isEating) {
			if (!isOneEatSound) {
				isOneEatSound = true;
				if (!Global.SetVolumeToZero)
					playRandomEatSound(5);
			}
//			if (currentState == State.EATING) {
//				if (eating.isAnimationFinished(_stateTimer)) {
//					isEating = false;
//					isOneEatSound = false;
//					isjumpAtPlayer = false;
//					isFat = true;
//				}
//			}
		}
	}

	/**
	 * array of whoever is closest
	 */
	private Vector2 getClosestEnemy(Array<Amethyst> amethystGems, Array<Copper> copperMetals, Array<Diamond> diamondGems, Array<Food> foodHealth,
			Array<Gold> goldMetals, Array<Platinum> platinumMetals, Array<Ruby> rubyGems, Array<Sapphire> sapphireGems, Array<Silver> silverMetals,
			Array<Topaz> topazGems) {
		float closestDistance = 1000000;
		Vector2 _sp = new Vector2(rect.x, rect.y);// starting point is always this initial 'living point'.
		Vector2 _ep = new Vector2(ep.x, ep.y);// we don't actually know this. This is what we are determining.
		HashMap<Float, Vector2> _distances = new HashMap<Float, Vector2>();
		// amethystGems
		for (Iterator<Amethyst> iter = amethystGems.iterator(); iter.hasNext();) {
			Amethyst am = iter.next();
			ep = new Vector2(am.rect.x, am.rect.y);
			float dist = UsefulMethods.GetDistance(_sp, ep);
			if (dist < closestDistance && !am.isDead && !am.isCarried) {
				closestDistance = dist;
				_ep = ep;
			}
			_distances.put(closestDistance, _ep);
		}
		// copperMetals
		for (Iterator<Copper> iter = copperMetals.iterator(); iter.hasNext();) {
			Copper cp = iter.next();
			ep = new Vector2(cp.rect.x, cp.rect.y);
			float dist = UsefulMethods.GetDistance(_sp, ep);
			if (dist < closestDistance && !cp.isDead && !cp.isCarried) {
				closestDistance = dist;
				_ep = ep;
			}
			_distances.put(closestDistance, _ep);
		}
		// diamondGems
		for (Iterator<Diamond> iter = diamondGems.iterator(); iter.hasNext();) {
			Diamond cp = iter.next();
			ep = new Vector2(cp.rect.x, cp.rect.y);
			float dist = UsefulMethods.GetDistance(_sp, ep);
			if (dist < closestDistance && !cp.isDead && !cp.isCarried) {
				closestDistance = dist;
				_ep = ep;
			}
			_distances.put(closestDistance, _ep);
		}
		// foodHealth
		for (Iterator<Food> iter = foodHealth.iterator(); iter.hasNext();) {
			Food cp = iter.next();
			ep = new Vector2(cp.rect.x, cp.rect.y);
			float dist = UsefulMethods.GetDistance(_sp, ep);
			if (dist < closestDistance && !cp.isDead && !cp.isCarried) {
				closestDistance = dist;
				_ep = ep;
			}
			_distances.put(closestDistance, _ep);
		}
		// goldMetals
		for (Iterator<Gold> iter = goldMetals.iterator(); iter.hasNext();) {
			Gold cp = iter.next();
			ep = new Vector2(cp.rect.x, cp.rect.y);
			float dist = UsefulMethods.GetDistance(_sp, ep);
			if (dist < closestDistance && !cp.isDead && !cp.isCarried) {
				closestDistance = dist;
				_ep = ep;
			}
			_distances.put(closestDistance, _ep);
		}
		// platinumMetals
		for (Iterator<Platinum> iter = platinumMetals.iterator(); iter.hasNext();) {
			Platinum cp = iter.next();
			ep = new Vector2(cp.rect.x, cp.rect.y);
			float dist = UsefulMethods.GetDistance(_sp, ep);
			if (dist < closestDistance && !cp.isDead && !cp.isCarried) {
				closestDistance = dist;
				_ep = ep;
			}
			_distances.put(closestDistance, _ep);
		}
		// rubyGems
		for (Iterator<Ruby> iter = rubyGems.iterator(); iter.hasNext();) {
			Ruby cp = iter.next();
			ep = new Vector2(cp.rect.x, cp.rect.y);
			float dist = UsefulMethods.GetDistance(_sp, ep);
			if (dist < closestDistance && !cp.isDead && !cp.isCarried) {
				closestDistance = dist;
				_ep = ep;
			}
			_distances.put(closestDistance, _ep);
		}
		// sapphireGems
		for (Iterator<Sapphire> iter = sapphireGems.iterator(); iter.hasNext();) {
			Sapphire cp = iter.next();
			ep = new Vector2(cp.rect.x, cp.rect.y);
			float dist = UsefulMethods.GetDistance(_sp, ep);
			if (dist < closestDistance && !cp.isDead && !cp.isCarried) {
				closestDistance = dist;
				_ep = ep;
			}
			_distances.put(closestDistance, _ep);
		}
		// silverMetals
		for (Iterator<Silver> iter = silverMetals.iterator(); iter.hasNext();) {
			Silver cp = iter.next();
			ep = new Vector2(cp.rect.x, cp.rect.y);
			float dist = UsefulMethods.GetDistance(_sp, ep);
			if (dist < closestDistance && !cp.isDead && !cp.isCarried) {
				closestDistance = dist;
				_ep = ep;
			}
			_distances.put(closestDistance, _ep);
		}
		// topazGems
		for (Iterator<Topaz> iter = topazGems.iterator(); iter.hasNext();) {
			Topaz cp = iter.next();
			ep = new Vector2(cp.rect.x, cp.rect.y);
			float dist = UsefulMethods.GetDistance(_sp, ep);
			if (dist < closestDistance && !cp.isDead && !cp.isCarried) {
				closestDistance = dist;
				_ep = ep;
			}
			_distances.put(closestDistance, _ep);
		}
		// player1
//		ep = new Vector2(shipv1.rect.x, shipv1.rect.y);
//		float dist = UsefulMethods.GetDistance(_sp, ep);
//		if (dist < closestDistance) {
//			closestDistance = dist;
//			_ep = ep;
//		}
//		_distances.put(closestDistance, _ep);
//		// player2
//		ep = new Vector2(player2.rect.x, player2.rect.y);
//		float dist2 = UsefulMethods.GetDistance(_sp, ep);
//		if (dist2 < closestDistance) {
//			closestDistance = dist2;
//			_ep = ep;
//		}
//		_distances.put(closestDistance, _ep);
//		// player3
//		ep = new Vector2(player3.rect.x, player3.rect.y);
//		float dist3 = UsefulMethods.GetDistance(_sp, ep);
//		if (dist3 < closestDistance) {
//			closestDistance = dist3;
//			_ep = ep;
//		}
//		_distances.put(closestDistance, _ep);
//		// player4
//		ep = new Vector2(player4.rect.x, player4.rect.y);
//		float dist4 = UsefulMethods.GetDistance(_sp, ep);
//		if (dist4 < closestDistance) {
//			closestDistance = dist4;
//			_ep = ep;
//		}
//		_distances.put(closestDistance, _ep);
//		// player5
//		ep = new Vector2(player5.rect.x, player5.rect.y);
//		float dist5 = UsefulMethods.GetDistance(_sp, ep);
//		if (dist5 < closestDistance) {
//			closestDistance = dist5;
//			_ep = ep;
//		}
		_distances.put(closestDistance, _ep);
		// check all of them.
		for (Float key : _distances.keySet()) {
			if (key < closestDistance)
				closestDistance = key;
		}
		Vector2 td = _distances.get(closestDistance);
		// System.out.println("distance?: " + td);
		if (!isEmpty(td))
			setTargetToClosestItem(td.x, td.y);
		else {
			Vector2 oopsNoOneIsLeft = new Vector2(rcr.MW / 2, rcr.MH / 2);
			td = oopsNoOneIsLeft;
		}
		return td;
	}

	private boolean isEmpty(Vector2 v) {
		if (v == null)
			return true;
		else
			return false;
	}

	private void setTargetToClosestItem(float _x, float _y) {
		targetX = _x;
		targetY = _y;
	}

	private void getCorrectWalkingAnimation(float dt) {
		if (isChosen) {
			if (targetX > rect.x) {
				rmove = true;
				lmove = false;
				r = true;
				l = false;
				u = false;
				d = false;
			} else if (targetX <= rect.x) {
				lmove = true;
				rmove = false;
				l = true;
				r = false;
				u = false;
				d = false;
			}
		} else {
			if (targetY > rect.y) {
				umove = true;
				dmove = false;
				u = true;
				d = false;
				l = false;
				r = false;
			} else if (targetY <= rect.y) {
				dmove = true;
				umove = false;
				d = true;
				u = false;
				l = false;
				r = false;
			}
		}
	}

	public TextureRegion getFrame(OrthographicCamera camera, float dt, Array<Amethyst> amethystGems, Array<Copper> copperMetals, Array<Diamond> diamondGems,
			Array<Food> foodHealth, Array<Gold> goldMetals, Array<Platinum> platinumMetals, Array<Ruby> rubyGems, Array<Sapphire> sapphireGems,
			Array<Silver> silverMetals, Array<Topaz> topazGems, Bread bread) {
		// System.out.println("getting frame: " + getState(player));
		// System.out.println("_stateTimer: " + _stateTimer);
		// System.out.println("animation Index: " + walkLeft.getKeyFrame(_stateTimer));
		update(dt, camera, amethystGems, copperMetals, diamondGems, foodHealth, goldMetals, platinumMetals, rubyGems, sapphireGems, silverMetals, topazGems, bread);
		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 DEAD:
			region = dying;
			break;
		case MAIN:
			region = main;
			break;
		default:
			region = main;
			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 (isDead)
			return State.DEAD;
		else if (l && lmove && umove || l && lmove && dmove)
			return State.WALKLEFT;
		else if (r && rmove && dmove || r && rmove && umove)
			return State.WALKRIGHT;
		else
			return State.MAIN;
	}

	/**
	 * @numberOfHurts = 23
	 */
	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();
			else if (randomSound == 7)
				hurt7.play();
			else if (randomSound == 8)
				hurt8.play();
			else if (randomSound == 9)
				hurt9.play();
			else if (randomSound == 10)
				hurt10.play();
			else if (randomSound == 11)
				hurt11.play();
			else if (randomSound == 12)
				hurt12.play();
			else if (randomSound == 13)
				hurt13.play();
			else if (randomSound == 14)
				hurt14.play();
			else if (randomSound == 15)
				hurt15.play();
			else if (randomSound == 16)
				hurt16.play();
			else if (randomSound == 17)
				hurt17.play();
			else if (randomSound == 18)
				hurt18.play();
			else if (randomSound == 19)
				hurt19.play();
			else if (randomSound == 20)
				hurt20.play();
			else if (randomSound == 21)
				hurt21.play();
			else if (randomSound == 22)
				hurt22.play();
			else
				hurt23.play();
		}
	}

	/**
	 * @numberOfEats = 11
	 */
	public void playRandomEatSound(int numberOfSounds) {
		int randomSound = MathUtils.random(1, numberOfSounds);
		if (!Global.SetVolumeToZero) {
			if (randomSound == 1)
				eat.play();
			else if (randomSound == 2)
				eat2.play();
			else if (randomSound == 3)
				eat3.play();
			else if (randomSound == 4)
				eat4.play();
			else if (randomSound == 5)
				eat5.play();
			else if (randomSound == 6)
				eat6.play();
			else if (randomSound == 7)
				eat7.play();
			else if (randomSound == 8)
				eat8.play();
			else if (randomSound == 9)
				eat9.play();
			else if (randomSound == 10)
				eat10.play();
			else if (randomSound == 11)
				eat11.play();
		}
	}

	/**
	 * @numberOfDeaths = 15
	 */
	public void playRandomDeathSound(int numberOfSounds) {
		int randomSound = MathUtils.random(1, numberOfSounds);
		if (!Global.SetVolumeToZero) {
			if (randomSound == 1)
				death.play();
			else if (randomSound == 2)
				death2.play();
			else if (randomSound == 3)
				death3.play();
			else if (randomSound == 4)
				death4.play();
			else if (randomSound == 5)
				death5.play();
			else if (randomSound == 6)
				death6.play();
			else if (randomSound == 7)
				death7.play();
			else if (randomSound == 8)
				death8.play();
			else if (randomSound == 9)
				death9.play();
			else if (randomSound == 10)
				death10.play();
			else if (randomSound == 11)
				death11.play();
			else if (randomSound == 12)
				death12.play();
			else if (randomSound == 13)
				death13.play();
			else if (randomSound == 14)
				death14.play();
			else
				death15.play();
		}
	}

	public void playRandomRoarSound(int numberOfSounds) {
		int randomSound = MathUtils.random(1, numberOfSounds);
		if (!Global.SetVolumeToZero) {
			if (randomSound == 1)
				roar.play();
			else if (randomSound == 2)
				roar2.play();
			else if (randomSound == 3)
				roar3.play();
			else if (randomSound == 4)
				roar4.play();
			else if (randomSound == 5)
				roar5.play();
		}
	}

	public void dispose() {
		sfx_death.dispose();
		hurt.dispose();
		hurt2.dispose();
		eat.dispose();
		eat2.dispose();
		eat3.dispose();
		eat4.dispose();
		eat5.dispose();
		eat6.dispose();
		eat7.dispose();
		eat8.dispose();
		eat9.dispose();
		eat10.dispose();
		eat11.dispose();
		death.dispose();
		death2.dispose();
		death3.dispose();
		death4.dispose();
		death5.dispose();
		death6.dispose();
		death7.dispose();
		death8.dispose();
		death9.dispose();
		death10.dispose();
		death11.dispose();
		death12.dispose();
		death13.dispose();
		death14.dispose();
		death15.dispose();
		hurt.dispose();
		hurt2.dispose();
		hurt3.dispose();
		hurt4.dispose();
		hurt5.dispose();
		hurt6.dispose();
		hurt7.dispose();
		hurt8.dispose();
		hurt9.dispose();
		hurt10.dispose();
		hurt11.dispose();
		hurt12.dispose();
		hurt13.dispose();
		hurt14.dispose();
		hurt15.dispose();
		hurt16.dispose();
		hurt17.dispose();
		hurt18.dispose();
		hurt19.dispose();
		hurt20.dispose();
		hurt21.dispose();
		hurt22.dispose();
		hurt23.dispose();
		roar.dispose();
		roar2.dispose();
		roar3.dispose();
		roar4.dispose();
		roar5.dispose();
	}

	public void render(rcr game, OrthographicCamera camera, float dt, Array<Amethyst> amethystGems, Array<Copper> copperMetals, Array<Diamond> diamondGems,
			Array<Food> foodHealth, Array<Gold> goldMetals, Array<Platinum> platinumMetals, Array<Ruby> rubyGems, Array<Sapphire> sapphireGems,
			Array<Silver> silverMetals, Array<Topaz> topazGems, Bread bread) {
		game.batch.draw(getFrame(camera, dt, amethystGems, copperMetals, diamondGems, foodHealth, goldMetals, platinumMetals, rubyGems, sapphireGems, silverMetals,
				topazGems, bread), rect.x, rect.y);
	}
}
