package Game;

import java.io.IOException;
import java.util.Random;

import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.TiledLayer;

public class Map {

	protected byte[][][] mapArray;

	private int row;
	private int col;

	private Image floorImage;
	private Image buildImage;
	private Image bombImage;
	private Image toolImage;

	private TiledLayer floorLayer;
	private TiledLayer buildLayer;
	private TiledLayer bombLayer;
	private TiledLayer toolLayer;

	private Random random;

	private int mapClock;

	protected int mapRows;
	protected int mapCols;

	public Map(byte[][][] mapArray) {

		this.mapArray = new byte[mapArray.length][mapArray[0].length][mapArray[0][0].length];
		for (int i = 0; i < mapArray.length; i++) {
			for (int j = 0; j < mapArray[i].length; j++) {
				for (int n = 0; n < mapArray[i][j].length; n++) {
					this.mapArray[i][j][n] = mapArray[i][j][n];
				}
			}
		}

		this.row = mapArray[Global.MAP_LAYER_FEATURE][0].length;
		this.col = mapArray[Global.MAP_LAYER_FEATURE].length;

		this.mapCols = row;
		this.mapRows = col;

		try {
			this.floorImage = Image.createImage("/Game/Floor.png");
			this.buildImage = Image.createImage("/Game/Build.png");
			this.bombImage = Image.createImage("/Game/Bomb.png");
			this.toolImage = Image.createImage("/Game/Tool.png");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		random = new Random();

		floorLayer = new TiledLayer(row, col, floorImage, 20, 20);
		buildLayer = new TiledLayer(row, col, buildImage, 20, 20);
		bombLayer = new TiledLayer(row, col, bombImage, 20, 20);
		toolLayer = new TiledLayer(row, col, toolImage, 20, 20);

		for (int x = 0; x < row; x++) {
			for (int y = 0; y < col; y++) {
				floorLayer.setCell(x, y,
						this.mapArray[Global.MAP_LAYER_FLOOR][y][x]);
			}
		}
		for (int x = 0; x < row; x++) {
			for (int y = 0; y < col; y++) {
				buildLayer.setCell(x, y,
						this.mapArray[Global.MAP_LAYER_BUILD][y][x]);
			}
		}
	}

	public TiledLayer getFloorLayer() {
		return this.floorLayer;
	}

	public TiledLayer getBuildLayer() {
		return this.buildLayer;
	}

	public TiledLayer getBombLayer() {
		return this.bombLayer;
	}

	public TiledLayer getToolLayer() {
		return this.toolLayer;
	}

	public boolean destroy(int row, int col) {
		if (this.hasFeature(row, col, Global.CAN_DESTROY)) {
			this.removeFeature(row, col, Global.CAN_DESTROY);
		} else {
			return false;
		}
		if (this.mapArray[Global.MAP_LAYER_BUILD][row][col] > 0
				&& this.mapArray[Global.MAP_LAYER_BUILD][row][col] < Global.IMAGE_BUILD_DESTROY) {
			this.mapArray[Global.MAP_LAYER_BUILD][row][col]++;
		}
		return true;
	}

	public void update() {
		if (this.mapClock < 10000) {
			this.mapClock++;
		} else {
			this.mapClock = 0;
		}
		for (int x = 0; x < col; x++) {
			for (int y = 0; y < row; y++) {
				if (this.toolLayer.getCell(y, x) > 0 && this.mapClock % 2 == 0) {
					if (this.toolLayer.getCell(y, x) % 3 == 0) {
						this.toolLayer.setCell(y, x, ((this.toolLayer.getCell(
								y, x) - 1) / 3) * 3 + 1);
					} else {
						this.toolLayer.setCell(y, x, (this.toolLayer.getCell(y,
								x) + 1));
					}
				}
				if (this.mapArray[Global.MAP_LAYER_BUILD][x][y] > 0
						&& this.mapArray[Global.MAP_LAYER_BUILD][x][y] <= Global.IMAGE_BUILD_DESTROY
						&& this.mapArray[Global.MAP_LAYER_BUILD][x][y]
								% Global.IMAGE_BUILD_FRAME != 1) {
					if (this.mapArray[Global.MAP_LAYER_BUILD][x][y]
							% Global.IMAGE_BUILD_FRAME == 0) {
						this.mapArray[Global.MAP_LAYER_BUILD][x][y] = 0;
						this.addFeature(x, y, Global.CAN_PASS);
						this.toolLayer.setCell(y, x, this.randomTool());
					} else {
						this.mapArray[Global.MAP_LAYER_BUILD][x][y]++;
					}
					buildLayer.setCell(y, x,
							this.mapArray[Global.MAP_LAYER_BUILD][x][y]);
				}
			}
		}
	}

	private int randomTool() {
		int probability = random.nextInt(100);
		if (probability >= Global.TOOL_PROBABILITY) {
			return 0;
		}
		int tool = random.nextInt(6) * 3 + 1;
		return tool;
	}

	public boolean hasFeature(int row, int col, int feature) {
		if(row> -1 && row<Global.ROW && col >-1 && col < Global.COL)
		return ((this.mapArray[Global.MAP_LAYER_FEATURE][row][col] & feature) != 0);
		else return false;
	}

	public void addFeature(int row, int col, int feature) {
		if(row> -1 && row<Global.ROW && col >-1 && col < Global.COL)
		this.mapArray[Global.MAP_LAYER_FEATURE][row][col] |= feature;
		else return;
	}

	public void removeFeature(int row, int col, int feature) {
		if(row> -1 && row<Global.ROW && col >-1 && col < Global.COL)
		this.mapArray[Global.MAP_LAYER_FEATURE][row][col] = (byte) ((this.mapArray[Global.MAP_LAYER_FEATURE][row][col] | feature) - feature);
		else return;
	}
}
