/** 軍隊ユニット */

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.applet.*;

public class Army extends Creature {

	Commander commander;	//指揮官

	int numberOfSoldier;	//兵士数
	int numberOfHorse;	//馬の数
	int numberOfArchery;	//弓の数

	TacticsApplet applet;

	static final int TACTICS_FIELD_SIZE_X = 16;
	static final int TACTICS_FIELD_SIZE_Y = 16;

	public Army(int x, int y, Board board, Direction direction, int nationality, Unit target, boolean auto, Commander commander, TacticsApplet applet) {
		super(x, y, board,  direction, nationality, target, auto);

		this.commander = commander;
		this.applet = applet;

		init();
	}

	public int  getNumberOfSoldier() { return numberOfSoldier; }
	public void setNumberOfSoldier(int number) {
		if (number > maxHP) {
			number = maxHP;
		}
		hp = numberOfSoldier = number;
	}

	public Commander getCommander() { return commander; }
	public void setCommander( Commander commander ) { this.commander = commander; }

	public void init() {
		hp = 2000;		//兵士数。
		maxHP = 5000;	//最大兵士数。

		maxSpeed = 2;
		movementPower = 0;

		numberOfSoldier = hp;	//兵士数
		numberOfHorse	= 500;	//馬の数
		numberOfArchery = 300;	//弓の数
	}

	public void run() {

		// まず自分が生きているかどうか。死んでいた場合には即刻終了する。
		if (!checkExistence())
			return;

		// もし自動操縦状態ならば、なにをすればよいか自己判断させる。
		if (auto)
			selfJudge();

		// 移動。
		move();

	}

	public void show(Graphics g, int x, int y, Component view) {
		uge.show(g, x,y, this, view);
	}

	protected void move() {

		// 停止していろという命令が出されていなければ、歩こうとしてみる。
		if (walking) {

			movementPower = movementPower + maxSpeed;

			// もし移動力が十分にたまっているのなら、いまいるスクウェアから抜け出す。
			if (board.getGround(x,y).getRestraint() <= movementPower ) {

				movementPower = 0;


				int destX = x + direction.getNextX();
				int destY = y + direction.getNextY();

				if ( board.moveCreature(x,y, destX, destY) ) {
				 	// 移動に成功。
					x = destX;
					y = destY;
				}
				else
				{
				 	// 移動に失敗。
					// 前方に敵がいるかいないか
					Army frontArmy = (Army)board.getCreature(destX, destY);

					if ( checkEnemy(frontArmy) ) {

						makeTacticsField( frontArmy );
					}
				}

			}
		}


	}


	/** 自身の持つ兵をdirectionの方向にしたがい、tacticsField上に配置する。 */
	public void makeFormation( Board tacticsField, Direction direction, Commander enemyCommander ) {

		int tacticsX;
		int tacticsY;

		switch ( direction.getDirection() ) {
			case Direction.UP:
				tacticsX = TACTICS_FIELD_SIZE_X / 2;
				tacticsY = TACTICS_FIELD_SIZE_Y -1;

				// 指揮官の配置。
				getCommander().setBoard( tacticsField );
				getCommander().setX( tacticsX );
				getCommander().setY( tacticsY );
				getCommander().setDirection( new Direction( direction ) );
				getCommander().setTarget( enemyCommander );
				tacticsField.setCreature(tacticsX, tacticsY, getCommander() );
				tacticsField.getRunnableUnitList().add( getCommander() );

				// 一般兵士の配置。
				for (tacticsX = 0, tacticsY += direction.getNextY(); tacticsX < TACTICS_FIELD_SIZE_X; tacticsX++ ) {
					Soldier soldier = new Archer(tacticsX, tacticsY, tacticsField, new Direction( direction ), nationality, enemyCommander, auto);
					tacticsField.setCreature(tacticsX, tacticsY, soldier );
					tacticsField.getRunnableUnitList().add( soldier );
				}
				for (tacticsX = 0, tacticsY += direction.getNextY(); tacticsX < TACTICS_FIELD_SIZE_X; tacticsX++ ) {
					Soldier soldier = new Infantry(tacticsX, tacticsY, tacticsField, new Direction( direction ), nationality, enemyCommander, auto);
					tacticsField.setCreature(tacticsX, tacticsY, soldier );
					tacticsField.getRunnableUnitList().add( soldier );
				}
				for (tacticsX = 0, tacticsY += direction.getNextY(); tacticsX < TACTICS_FIELD_SIZE_X; tacticsX++ ) {
					Soldier soldier = new Cavalry(tacticsX, tacticsY, tacticsField, new Direction( direction ), nationality, enemyCommander, auto);
					tacticsField.setCreature(tacticsX, tacticsY, soldier );
					tacticsField.getRunnableUnitList().add( soldier );
				}

				break;

			case Direction.RIGHT:
				tacticsX = 0;
				tacticsY = TACTICS_FIELD_SIZE_Y / 2;

				// 指揮官の配置。
				getCommander().setBoard( tacticsField );
				getCommander().setX( tacticsX );
				getCommander().setY( tacticsY );
				getCommander().setDirection( new Direction( direction ) );
				getCommander().setTarget( enemyCommander );
				tacticsField.setCreature(tacticsX, tacticsY, getCommander() );
				tacticsField.getRunnableUnitList().add( getCommander() );

				// 一般兵士の配置。
				for (tacticsX += direction.getNextX(), tacticsY = 0; tacticsY < TACTICS_FIELD_SIZE_Y; tacticsY++ ) {
					Soldier soldier = new Archer(tacticsX, tacticsY, tacticsField, new Direction( direction ), nationality, enemyCommander, auto);
					tacticsField.setCreature(tacticsX, tacticsY, soldier );
					tacticsField.getRunnableUnitList().add( soldier );
				}
				for (tacticsX += direction.getNextX(), tacticsY = 0; tacticsY < TACTICS_FIELD_SIZE_Y; tacticsY++ ) {
					Soldier soldier = new Infantry(tacticsX, tacticsY, tacticsField, new Direction( direction ), nationality, enemyCommander, auto);
					tacticsField.setCreature(tacticsX, tacticsY, soldier );
					tacticsField.getRunnableUnitList().add( soldier );
				}
				for (tacticsX += direction.getNextX(), tacticsY = 0; tacticsY < TACTICS_FIELD_SIZE_Y; tacticsY++ ) {
					Soldier soldier = new Cavalry(tacticsX, tacticsY, tacticsField, new Direction( direction ), nationality, enemyCommander, auto);
					tacticsField.setCreature(tacticsX, tacticsY, soldier );
					tacticsField.getRunnableUnitList().add( soldier );
				}

				break;

			case Direction.DOWN:
				tacticsX = TACTICS_FIELD_SIZE_X / 2;
				tacticsY = 0;

				// 指揮官の配置。
				getCommander().setBoard( tacticsField );
				getCommander().setX( tacticsX );
				getCommander().setY( tacticsY );
				getCommander().setDirection( new Direction( direction ) );
				getCommander().setTarget( enemyCommander );
				tacticsField.setCreature(tacticsX, tacticsY, getCommander() );
				tacticsField.getRunnableUnitList().add( getCommander() );

				// 一般兵士の配置。
				for (tacticsX = 0, tacticsY += direction.getNextY(); tacticsX < TACTICS_FIELD_SIZE_X; tacticsX++ ) {
					Soldier soldier = new Archer(tacticsX, tacticsY, tacticsField, new Direction( direction ), nationality, enemyCommander, auto);
					tacticsField.setCreature(tacticsX, tacticsY, soldier );
					tacticsField.getRunnableUnitList().add( soldier );
				}
				for (tacticsX = 0, tacticsY += direction.getNextY(); tacticsX < TACTICS_FIELD_SIZE_X; tacticsX++ ) {
					Soldier soldier = new Infantry(tacticsX, tacticsY, tacticsField, new Direction( direction ), nationality, enemyCommander, auto);
					tacticsField.setCreature(tacticsX, tacticsY, soldier );
					tacticsField.getRunnableUnitList().add( soldier );
				}
				for (tacticsX = 0, tacticsY += direction.getNextY(); tacticsX < TACTICS_FIELD_SIZE_X; tacticsX++ ) {
					Soldier soldier = new Cavalry(tacticsX, tacticsY, tacticsField, new Direction( direction ), nationality, enemyCommander, auto);
					tacticsField.setCreature(tacticsX, tacticsY, soldier );
					tacticsField.getRunnableUnitList().add( soldier );
				}

				break;

			case Direction.LEFT:
				tacticsX = TACTICS_FIELD_SIZE_X -1;
				tacticsY = TACTICS_FIELD_SIZE_Y / 2;

				// 指揮官の配置。
				getCommander().setBoard( tacticsField );
				getCommander().setX( tacticsX );
				getCommander().setY( tacticsY );
				getCommander().setDirection( new Direction( direction ) );
				getCommander().setTarget( enemyCommander );
				tacticsField.setCreature(tacticsX, tacticsY, getCommander() );
				tacticsField.getRunnableUnitList().add( getCommander() );

				// 一般兵士の配置。
				for (tacticsX += direction.getNextX(), tacticsY = 0; tacticsY < TACTICS_FIELD_SIZE_Y; tacticsY++ ) {
					Soldier soldier = new Archer(tacticsX, tacticsY, tacticsField, new Direction( direction ), nationality, enemyCommander, auto);
					tacticsField.setCreature(tacticsX, tacticsY, soldier );
					tacticsField.getRunnableUnitList().add( soldier );
				}
				for (tacticsX += direction.getNextX(), tacticsY = 0; tacticsY < TACTICS_FIELD_SIZE_Y; tacticsY++ ) {
					Soldier soldier = new Infantry(tacticsX, tacticsY, tacticsField, new Direction( direction ), nationality, enemyCommander, auto);
					tacticsField.setCreature(tacticsX, tacticsY, soldier );
					tacticsField.getRunnableUnitList().add( soldier );
				}
				for (tacticsX += direction.getNextX(), tacticsY = 0; tacticsY < TACTICS_FIELD_SIZE_Y; tacticsY++ ) {
					Soldier soldier = new Cavalry(tacticsX, tacticsY, tacticsField, new Direction( direction ), nationality, enemyCommander, auto);
					tacticsField.setCreature(tacticsX, tacticsY, soldier );
					tacticsField.getRunnableUnitList().add( soldier );
				}

				break;
		}


	}

	/** 
	 * 合戦に負けるなどして、この軍隊が消滅するときに呼び出される。
	 * このメソッドを呼び出すのは、tacticsFieldに配置されたCommander
	 */
	public void defeated() {

		Board tempBoard = applet.getBoard();

		// アプレットが参照するボードを、一時的に生成されたtacticsFieldから行軍フィールドにもどす。
		applet.setBoard( board );

		// tacticsFieldを消去。
		tempBoard.remove();

		// 自分自身を消去。
		remove();
	}

	/** 戦場を作成するメソッド。 */
	public void makeTacticsField( Army frontArmy ) {

		// 行軍フィールドの時間の流れを停止させる。
		board.setSpeed(0);

		int geoKind = 0;	//地形データは0(平野)
		Board tacticsField = new Board( TACTICS_FIELD_SIZE_X, TACTICS_FIELD_SIZE_Y );

		// tacticsFieldの初期化。地形データ(Groundオブジェクト)を配置する。。
		for (int y = 0; y < TACTICS_FIELD_SIZE_Y; y++)
			for (int x = 0; x < TACTICS_FIELD_SIZE_X; x++) {

				// 得られたgeoKindの値をもとにGroundオブジェクトを生成し、chineseContinentにセット。
				tacticsField.setUnit(x, y, new Ground(x, y, tacticsField, geoKind) );
			}

		// 自軍の指揮官・兵士たをtacticsField上に配置する。
		makeFormation( tacticsField, direction, frontArmy.getCommander() );
		// 敵軍の指揮官・兵士たをtacticsField上に配置する。
		frontArmy.makeFormation( tacticsField, new Direction( direction.getContrary() ), getCommander() );

		// アプレットが参照するボードを、行軍フィールドからtacticsFieldからに切り替える。
		applet.setBoard( tacticsField );

	}


}
