/** ゲーム盤 */
public class Board {

	Unit square[][];	//ユニットを配置する桝目。
	int sizeX;	//盤の大きさ。
	int sizeY;	//盤の大きさ。

	RunnableUnitList runnableUnitList;	//時間とともに変化するユニットのリスト。(都市・田畑・軍隊。歩兵・騎兵・弓兵など)
	RunnableUnitList flyingUnitList;	//飛来物を配置するリスト。(飛びかう矢・弾丸など)

	int speed;	// ゲームのスピード。この数値が小さいほどゲーム速度は速く、多ければ遅い。0なら一時停止。

	public Board(int sizeX, int sizeY) {

		speed = 0;

		this.sizeX = sizeX;
		this.sizeY = sizeY;

		square = new Unit[sizeX][sizeY];
		for (int x = 0; x < sizeX; x++)
			for (int y = 0; y < sizeY; y++)
				square[x][y] = null;

		flyingUnitList = new RunnableUnitList(this);
		runnableUnitList = new RunnableUnitList(this);

	}
	public void remove() {

		setSpeed(0);

		for (int x = 0; x < sizeX; x++)
			for (int y = 0; y < sizeY; y++)
				removeUnit(x, y);

		flyingUnitList = null;
		runnableUnitList = null;

	}

	public RunnableUnitList getFlyingUnitList() { return flyingUnitList; }
	public RunnableUnitList getRunnableUnitList() { return runnableUnitList; }

	/** ゲームスピードを変更する */
	public void setSpeed(int argSpeed) {
		if (0 == speed && 0 != argSpeed)
			startAllUnit();	// もし、いままでのスピードがゼロだったなら、停止していた盤上の全スレッドを再びrunさせる。
		speed = argSpeed;
	}
	public int getSpeed() { return speed; }

	/** 盤上の全スレッドをrunさせる。 */
	public void startAllUnit() {
		runnableUnitList.start();
		flyingUnitList.start();
	}

	public int getSizeX() { return sizeX; }
	public int getSizeY() { return sizeY; }

	public Unit getUnit(int x, int y) {
		if (0 <= x && x < sizeX && 0 <= y && y < sizeY)
			return square[x][y];
		else
			return null;
	}
	public void setUnit(int x, int y, Unit unit) {
		if (0 <= x && x < sizeX && 0 <= y && y < sizeY)
			square[x][y] = unit;
	}
	public void removeUnit(int x, int y) {
		if (0 <= x && x < sizeX && 0 <= y && y < sizeY)
			square[x][y] = null;
	}

	public Ground getGround(int x, int y) {
		if (0 <= x && x < sizeX && 0 <= y && y < sizeY)
			return (Ground)square[x][y];
		else
			return null;
	}
	public void setGround(int x, int y, Ground unit) {
		if (0 <= x && x < sizeX && 0 <= y && y < sizeY)
			square[x][y] = unit;
	}
	public void removeGround(int x, int y) {
		if (0 <= x && x < sizeX && 0 <= y && y < sizeY)
			square[x][y] = null;
	}


	public Structure getStructure(int x, int y) {
		if (0 <= x && x < sizeX && 0 <= y && y < sizeY)
			return ( (Ground)square[x][y] ).getStructure();
		else
			return null;
	}
	public void setStructure(int x, int y, Structure structure) {
		if (0 <= x && x < sizeX && 0 <= y && y < sizeY)
			( (Ground)square[x][y] ).setStructure(structure);
	}
	public void removeStructure(int x, int y) {
		if (0 <= x && x < sizeX && 0 <= y && y < sizeY)
			( (Ground)square[x][y] ).removeStructure();
	}

	public Creature getCreature(int x, int y) {
		if (0 <= x && x < sizeX && 0 <= y && y < sizeY)
			return ( (Ground)square[x][y] ).getCreature();
		else
			return null;
	}
	public void setCreature(int x, int y, Creature creature) {
		if (0 <= x && x < sizeX && 0 <= y && y < sizeY)
			( (Ground)square[x][y] ).setCreature(creature);
	}
	public void removeCreature(int x, int y) {
		if (0 <= x && x < sizeX && 0 <= y && y < sizeY)
			( (Ground)square[x][y] ).removeCreature();
	}


	/**
	 * source_x,source_yにあるCreatureユニットを、dest_x,dest_yの位置に移動させる。
	 * 成功すれば真を返し、失敗すれば偽を返す。
	 */
	public boolean moveCreature(int sourceX, int sourceY, int destX, int destY) {

		if (0 <= sourceX && sourceX < sizeX && 0 <= sourceY && sourceY < sizeY &&
			0 <= destX && destX < sizeX && 0 <= destY && destY < sizeY ) {

			if ( ( getCreature(destX, destY) == null ) &&  ( getCreature(sourceX, sourceY) != null ) ) {
				setCreature(destX, destY, getCreature(sourceX, sourceY));
				removeCreature(sourceX, sourceY);
				return true;
			} else {
				return false;
			}
		}
		else
			return false;
	}

}

