import java.awt.*;

public class Enemy extends Sprite {
	public static final byte TYPE_NORMAL = 0;
	public static final byte TYPE_JUMP = 1;
	public static final byte TYPE_SMART = 2;
	
	private static final int DEATH_COUNT_TIME = 40;
	private static final double JUMP_PROB = .03;
	private static final float JUMP_VELOCITY = -4;
	private Level l;
	protected int[] animLengths;
	protected float vx, vy;
	protected float maxvy;
	protected float speed;
	protected float grav;
	private float spawnX, spawnY;
	private boolean midair;
	private boolean midjump;
	private boolean facingRight;
	private boolean moving;
	private boolean dead;
	private byte type;
	private int deathCounter;
	private int value;

	public Enemy(Level l, String imgName, int[] animL, float x, float y, int w, int h, byte type, int value) {
		super(l.spriteCache, imgName, animL);
		animLengths = animL;
		this.type=type;
		this.l=l;
		setLoc(x,y);
		setSpawn(x,y);
		setSpriteMode(0);
		speed = 1.5f;
		vx = 0;
		vy = 0;
		this.w=w;
		this.h=h;
		grav = .2f;
		maxvy = 4;
		this.l=l;
		moving=false;
		dead=false;
		deathCounter=-1;
		this.value = value;
	}
	
	public boolean isMoving() {
		return moving;
	}
	public void setMoving(boolean move) {
		moving = move;
	}
	public void setSpawn(float x, float y) {
		spawnX = x;
		spawnY = y;
	}
	public float getSpawnX() {
		return spawnX;
	}
	public float getSpawnY() {
		return spawnY;
	}
	public void respawn() {
		x=spawnX;
		y=spawnY;
	}
	
	public void die() {
		//Enemy has been jumped on
		setMoving(false);
		dead=true;
		deathCounter = DEATH_COUNT_TIME;
	}
	
	public void draw(Graphics2D g, int x, int y) {
		if (!dead) {
			super.draw(g, x, y);
		} else if (deathCounter > 0) {
			g.setColor(Color.black);
			g.setFont(new Font("Monospaced", Font.PLAIN, 12));
			g.drawString(value+"", x, y);
		}
	}
	
	public void act() {
		if (deathCounter > 0) {
			if (--deathCounter == 0)
				respawn();
			return;
		}
		if (dead && !l.onScreen(this))
			dead=false;
		if(!dead && l.onScreen(this))
			setMoving(true);
		if (!moving || dead)
			return;
		x+=vx;
		y+=vy;
		if (!l.onMap(this)) {
			die();
			return;
		}
		byte hitState = l.hitDetect((int)x, (int)y, w*32, h*32, vx, vy);
		if ((hitState & Level.HIT_RIGHT) != 0) {
			x-=x%32;
			if (vx > 0) vx*=-1;
		}
		if ((hitState & Level.HIT_LEFT) != 0) {
			x-=x%32;
			x+=32;
			if (vx < 0) vx*=-1;
		}
		if ((hitState & Level.HIT_TOP) != 0) {
			y-=y%32;
			y+=32;
			if (vy < 0) vy=0;
		}
		if ((hitState & Level.HIT_BOTTOM) != 0) {
			midair=false;
			midjump=false;
			y-=y%32;
			if (vy > 0) vy=0;
		} else {
			vy += grav;
			midair=true;
		}
		if (vx < 0)
			facingRight = false;
		else if (vx > 0)
			facingRight = true;
		if (Math.abs(vy) > maxvy)
			vy = maxvy*Math.signum(vy);
		if (facingRight) {
			vx = speed;
			if (animLengths.length == 2)
				setSpriteMode(0);
		} else {
			vx = speed * -1;
			if (animLengths.length == 2)
				setSpriteMode(1);
		}
		if (midair && !midjump)
			vx = 0;
		Player p = l.player;
		if (hitSprite(p)) {
			if (p.getY()+p.getH()*32<=y+16 && p.vy>0) {
				l.player.bounce();
				l.gamestate.addKills(1);
				l.gamestate.addPoints(value);
				die();
			} else {
				//Enemy killed player
				l.player.respawn();
			}
		}
		if (type == TYPE_SMART) {
			float tx=x+32*w*Math.signum(vx);
			try {
				if (!midair && (l.hitDetect((int)tx, (int)y, 32*w, 32*h, vx, vy) & Level.HIT_BOTTOM) == 0)
					vx*=-1;
			} catch (RuntimeException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				vx*=-1;
			}
		} else if (type == TYPE_JUMP) {
			if (!midair && Math.random() <= JUMP_PROB) {
				midjump=true;
				vy = JUMP_VELOCITY;
			}
		}
	}

	
}
