import java.awt.image.*;
import java.util.*;
import java.awt.*;
import java.io.*;
import javax.imageio.ImageIO;

public class TDLevel {
	public static final int DEF_MAX_FIRE_TIME = 10;
	public byte[][] tdlevelmap;
	HWGameState gamestate;
	HWDisplay frame;
	TDPlayer player;
	int levelNum;
	int initKills;
	ArrayList<TDEnemy> enemies;
	ArrayList<TDProjectile> projs;
	HashMap<Sprite, BufferedImage[][]> spriteCache;
	BufferedImage screen;
	BufferedImage bkg;
	BufferedImage[] walls;
	int winX, winY;
	protected int maxFireTime, fireCounter;
	boolean collide = false;
	private ClassLoader cl = HWDisplay.cl;
	String imgs;
	/*
	 *	 0: BLACK
	 *	 1: VERTICAL SIDEWALK
	 *	 2: HORIZONTAL SIDEWALK
	 *	 3: LEFT CENTER STREET
	 *	 4: RIGHT CENTER STREET
	 *	 5: BOTTOM CENTER STREET
	 *	 6: TOP CENTER STREET
	 *	-1: TOP LEFT SIDEWALK CORNER
	 *	-2: TOP RIGHT SIDEWALK CORNER
	 *	-3: BOTTOM LEFT SIDEWALK CORNER
	 *	=4: BOTTOM RIGHT SIDEWALK CORNER
	 */
	public TDLevel(HWDisplay hwd, HWGameState gs, int levelNum, String imgPath, byte[][] levelmap) {
		frame = hwd;
		imgs = imgPath;
		this.levelNum = levelNum;
		gamestate = gs;
		initKills = gamestate.getKills();
		spriteCache = new HashMap<Sprite, BufferedImage[][]>();
		walls = new BufferedImage[11];
		tdlevelmap = levelmap;
		try {
			for (int i=0; i<11; i++)
				walls[i] = ImageIO.read(cl.getResource(imgPath+"terrain"+i+".png"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		player = new TDPlayer(this, 128, 128, imgs);
		enemies = new ArrayList<TDEnemy>();
		maxFireTime = 10;
		projs = new ArrayList<TDProjectile>();
		maxFireTime = DEF_MAX_FIRE_TIME;
		winX=512;
		winY=512;
		drawBkg();
	}
	public void update(BufferedImage buf) {
		if(gamestate.getKills()-initKills >= 50) {
			frame.changeTo(levelNum+1);
		}
		player.act();
		addEnemies();
		for(TDEnemy e: enemies)
			e.act();
		draw(buf);
		drawProjectiles(buf);
		hitDetect();
	}
	public void addEnemies() {
		while(enemies.size()<10) {
			enemies.add(new TDEnemy(this, imgs));
		}
	}
	public void drawBkg() {
		Graphics2D g;
		if (bkg == null) {
			bkg = new BufferedImage(256,256,BufferedImage.TYPE_INT_RGB);
		}
		g = (Graphics2D)bkg.getGraphics();
		g.setColor(Color.black);
		g.fillRect(0, 0, 256, 256);
		for (int i=0; i<16; i++) {
			for (int j=0; j<16; j++) {
				if (tdlevelmap[i][j] == 1) {
					g.drawImage(walls[0],i*16,j*16,null);
				} else if (tdlevelmap[i][j] == 2) {
					g.drawImage(walls[1],i*16, j*16,null);
				} else if (tdlevelmap[i][j] == 3) {
					g.drawImage(walls[7],i*16, j*16,null);
				} else if (tdlevelmap[i][j] == 4) {
					g.drawImage(walls[6],i*16, j*16,null);
				} else if (tdlevelmap[i][j] == 5) {
					g.drawImage(walls[9],i*16, j*16,null);
				} else if (tdlevelmap[i][j] == 6) {
					g.drawImage(walls[8],i*16, j*16,null);
				} else if (tdlevelmap[i][j] == -1) {
					g.drawImage(walls[2],i*16, j*16,null);
				} else if (tdlevelmap[i][j] == -2) {
					g.drawImage(walls[5],i*16, j*16,null);
				} else if (tdlevelmap[i][j] == -3) {
					g.drawImage(walls[3],i*16, j*16,null);
				} else if (tdlevelmap[i][j] == -4) {
					g.drawImage(walls[4],i*16, j*16,null);
				} else if (tdlevelmap[i][j] == 7) {
					g.drawImage(walls[10],i*16, j*16,null);
				} 
			}
		}
	}
	public void hitDetect() {
		Iterator<TDProjectile> it = projs.iterator();
		while(it.hasNext()) {
			TDProjectile p = it.next();
			p.hitDetect();
			if(p.hitTarget()) {
				it.remove();
				gamestate.addKills(1);
				gamestate.addPoints(2);
			}
			if(p.isOffScreen())
				it.remove();
		}
	}
	public void drawProjectiles(BufferedImage proj) {
		Graphics2D g = (Graphics2D)proj.getGraphics();
		if(player.keyFireState != 0)
			if(projs.size() < 10)
				if (fireCounter <= 0) {
					projs.add(new TDProjectile(this, player.dir, (int)(player.x+8),(int)(player.y+8)));
					fireCounter = maxFireTime;
				}
				fireCounter--;
				
		for(TDProjectile p: projs) {
			p.draw(g);
		}
	//	for(TDProjectile p: projs) {
	//		if(p.isOffScreen())
	//			projs.remove(p);
	//	}
	}
	public BufferedImage draw(BufferedImage screen) {
		Graphics2D g;
		g = (Graphics2D)screen.getGraphics();
		g.clearRect(0, 0, 256, 256);
		g.drawImage(bkg, 0, 0, null);
		player.draw(g, player.getX(), player.getY());
		for(TDEnemy e: enemies) {
			e.draw(g, e.getX(), e.getY());
		}
		return screen;
	}
}
