package sample.game.ai;

import java.util.ArrayList;

import library.core.debug.CoreLog;
import sample.game.controller.GameController;
import sample.game.manager.EndIsland;
import sample.game.manager.Island;
import sample.game.manager.StartIsland;
import sample.game.model.BoatModel;
import sample.game.model.CharaModel;

public class AiSystemType1 extends AiSystem{






	private boolean nowMovePhase;
	private boolean nowStartIsland;
	private boolean nowSleepPhase;
	private boolean endTurnFlag=false;	//強制的にターンを交代する
	private float time=0;
	private float targetX=0;	//
	private float targetY=0;	//


	private GameController gameController;
	private StartIsland startIsland;
	private EndIsland endIsland;
	private BoatModel boat;



	private int moveMinisterNum=0;
	private int moveWolfNum=0;
	private int moveCabbageNum=0;
	private int moveCattleNum=0;

	//一つ前の移動情報
	private int bifmoveMinisterNum=0;
	private int bifmoveWolfNum=0;
	private int bifmoveCabbageNum=0;
	private int bifmoveCattleNum=0;

	private boolean marginTimeSwitch=true;
	private boolean thinkFlag=false;
	private boolean isStopUpdate;


	private  float moveSpeed=1f;


	public AiSystemType1(GameController g,BoatModel b,StartIsland startIsland,EndIsland eIsland) {

		nowStartIsland=true;
		nowMovePhase=false;
		nowSleepPhase=false;
		endTurnFlag=false;

		marginTimeSwitch=true;

		this.boat=b;
		this.gameController=g;
		this.startIsland=startIsland;
		this.endIsland=eIsland;

		targetMemory=gameController.getMoveData();



		time=0;

		this.isStopUpdate=false;


		thinkInit();

	}

	/**
	 * 再スタート用
	 * @param memory
	 * @param g
	 * @param b
	 * @param startIsland
	 * @param eIsland
	 * @param layout
	 */
	public AiSystemType1(Memory memory, GameController g,BoatModel b,StartIsland startIsland,EndIsland eIsland) {

		nowStartIsland=startIsland.getNowTurn();
		nowMovePhase=false;
		nowSleepPhase=false;
		endTurnFlag=false;

		this.boat=b;
		this.gameController=g;
		this.startIsland=startIsland;
		this.endIsland=eIsland;

		targetMemory=memory;

		marginTimeSwitch=true;
		this.isStopUpdate=false;
		thinkInit();



	}



	@Override
	public void update(float deltaTime) {

		if(isStopUpdate) return;

		if(nowSleepPhase){	//休憩フェイズ

			//休憩終了判定
			if(!gameController.isNowTurnChangePhase()){
				CoreLog.debug("start AI");
				nowSleepPhase=false;
				nowMovePhase=false;
				endTurnFlag=false;

				//startNextTurnの終了時にメモリーの更新が行われているためここでそれをキャッチ
/*				targetMemory=gameController.getMoveData();
				CoreLog.debug("start isLand");
				CoreLog.debug("ministersNum :"+targetMemory.getStartIsland().getMinisters().size());
				CoreLog.debug("wolfsNum :"+targetMemory.getStartIsland().getWolfs().size());
				CoreLog.debug("cabbagesNum :"+targetMemory.getStartIsland().getCabbages().size());
				CoreLog.debug("cattlesNum :"+targetMemory.getStartIsland().getCattles().size());
				CoreLog.debug("                                                    //");
				CoreLog.debug("end isLand");
				CoreLog.debug("ministersNum :"+targetMemory.getEndIsland().getMinisters().size());
				CoreLog.debug("wolfsNum :"+targetMemory.getEndIsland().getWolfs().size());
				CoreLog.debug("cabbagesNum :"+targetMemory.getEndIsland().getCabbages().size());
				CoreLog.debug("cattlesNum :"+targetMemory.getEndIsland().getCattles().size());
				CoreLog.debug("                                                    //");
				CoreLog.debug("nowStartIsland :"+targetMemory.getStartIsland().getNowTurn());*/


				thinkInit();
				CoreLog.debug("end thinkInit AI");
				time=0;
			}

			return ;
		}

		time+=deltaTime*moveSpeed;



		if(time>=0.1f){
			time=0;

			//少し待ってから処理をしないと演出が見えないため一定時間間隔で処理を分ける
			if(marginTimeSwitch){
				marginTimeSwitch=!marginTimeSwitch;
				thinkFlag=think();
				CoreLog.debug("end think AI");
			}else{
				marginTimeSwitch=!marginTimeSwitch;
				if(thinkFlag){
					if(endTurnFlag ||gameController.checkNextTurn()){
						gameController.changeTurn(false);
						nowStartIsland=!nowStartIsland;
						nowSleepPhase=true;
						CoreLog.debug("                       turn change");
					}else{
						//思考を続行
						nowMovePhase=false;
					}
				}else{
					//船に乗せるキャラがない場合
					gameController.changeTurn(false);
					nowStartIsland=!nowStartIsland;
					nowSleepPhase=true;
				}
			}

		}




	}


	/**
	 * 思考準備
	 */
	private void thinkInit(){
	/*	CoreLog.debug("start thinkInit");
		CoreLog.debug("deep: "+targetMemory.getDeepNumber());
		CoreLog.debug("id: "+targetMemory.getId());
		CoreLog.debug("next num: "+targetMemory.getNextMemorys().size());
*/

		CoreLog.debugSimple("start thinkInit",2);
		CoreLog.debugSimple("deep :"+targetMemory.getDeepNumber(),2);
		CoreLog.debugSimple("id :"+targetMemory.getId(),2);


		targetMemory.setData(startIsland.clone(), endIsland.clone(), boat.clone());


		//無限ループ対策
		if(targetMemory.getBifMemory()!=null){
			Memory m=targetMemory.getBifMemory();
			for(int i=0;i<targetMemory.getDeepNumber()-1;i++){
				m=m.getBifMemory();

				if(targetMemory.getStartIsland().getNowTurn() == m.getStartIsland().getNowTurn()){
					if(targetMemory.getStartIsland().getMinisters().size()==m.getStartIsland().getMinisters().size() &&
							targetMemory.getStartIsland().getWolfs().size()==m.getStartIsland().getWolfs().size() &&
							targetMemory.getStartIsland().getCabbages().size()==m.getStartIsland().getCabbages().size() &&
							targetMemory.getStartIsland().getCattles().size()==m.getStartIsland().getCattles().size() &&

							targetMemory.getEndIsland().getMinisters().size()==m.getEndIsland().getMinisters().size() &&
							targetMemory.getEndIsland().getWolfs().size()==m.getEndIsland().getWolfs().size() &&
							targetMemory.getEndIsland().getCabbages().size()==m.getEndIsland().getCabbages().size() &&
							targetMemory.getEndIsland().getCattles().size()==m.getEndIsland().getCattles().size()
							){
						CoreLog.debug("here");
						CoreLog.debug("here");
						this.thinkRestartProcess(false);

						return;
					}
				}

			}
		}

		//通常ゲームオーバー判定
		if(targetMemory.getStartIsland().cheakGameOver() || targetMemory.getEndIsland().cheakGameOver()){
			this.thinkRestartProcess(false);
			CoreLog.debugSimple("kokzyanai?  ",2);
			return;
		}


		Island is=null;

		if(nowStartIsland){
			is=startIsland;
		}else{
			is=endIsland;
		}


		CoreLog.debugSimple("---------------------");
		CoreLog.debug("this"+targetMemory.getNextMemorys().size());
		//経路を考えるのは一回だけでそれ以外の場合は残りの経路の中から選択
		if(targetMemory.getNextMemorys().size()>0){

			CoreLog.debugSimple("size :"+targetMemory.getNextMemorys().size(),2);
			CoreLog.debugSimple("------------------------------------",2);

			targetMemory=gameController.changeMemoryAndRemoveBifNextRoot();
			CoreLog.debugSimple(""+targetMemory.getMinisterMoveNum());
			CoreLog.debugSimple(""+targetMemory.getWolfMoveNum());
			CoreLog.debugSimple(""+targetMemory.getCabbageMoveNum());
			CoreLog.debugSimple(""+targetMemory.getCattleMoveNum());
			CoreLog.debugSimple("---------------------");

		}else{

			//初めのターン以外のstartIslandのターンであり、かつすべてのキャラがここにいる場合は止める
			if( targetMemory.getBifMemory()!=null && nowStartIsland){
				if(endIsland.getMinisters().size()==0 && endIsland.getWolfs().size()==0 &&
						endIsland.getCabbages().size()==0 && endIsland.getCattles().size()==0){
					CoreLog.debug("return start state");
//					gameController.setNowTurnChangePhase(true);
					this.thinkRestartProcess(false);
					return;
				}

			}





			//次の移動の可能性を判定
			//まずは牧師を一人動かす場合 牧師が一人以外で移動してきたなら一人で、向こう岸に移動する可能性がある
			if(targetMemory.getBifMemory()!=null){	//一番初めの場合は考慮に入れない
				if(targetMemory.getMinisterMoveNum()>1 ||
						(targetMemory.getWolfMoveNum()>0 || targetMemory.getCabbageMoveNum()>0 || targetMemory.getCattleMoveNum()>0 ) ){
					targetMemory.addNextMemorys(new Memory(targetMemory, startIsland.clone(), endIsland.clone(),
							boat.clone(),1, 0 ,0, 0));
					CoreLog.debug("add    only miniser");
				}
			}

			//牧師が一人で移動する以外の移動
			thinkNextMove(is, boat.getRideMaxMenberNum()-1,
					1, 0, 0, 0);

			CoreLog.debugSimple("size :"+targetMemory.getNextMemorys().size(),2);
			CoreLog.debugSimple("------------------------------------",2);

			//ボートに乗せる人数の多い順にするためにあえてソート
			//Collections.reverse(targetMemory.getNextMemorys());


			if(targetMemory.getNextMemorys().size()>0){
				targetMemory=gameController.changeMemoryAndRemoveBifNextRoot();
			}else{
//				gameController.setNowTurnChangePhase(true);
				CoreLog.debug("0 desu");
				this.thinkRestartProcess(false);
				return;
			}

		}

		CoreLog.debug("3");
		//移動記録情報の初期化

		//CoreLog.debug(""+moveMinisterNum+"/"+moveWolfNum+"/"+moveCabbageNum+"/"+moveCattleNum);

		bifmoveMinisterNum=moveMinisterNum;
		bifmoveWolfNum=moveWolfNum;
		bifmoveCabbageNum=moveCabbageNum;
		bifmoveCattleNum=moveCattleNum;

		moveMinisterNum=0;
		moveWolfNum=0;
		moveCabbageNum=0;
		moveCattleNum=0;


	}


	private void thinkNextMove(Island is, int rideNum,int mMoveNum,int wMoveNum,int cabMoveNum,int catMoveNum){

		if(rideNum>0){

			int ministerNum=is.getMinisters().size()-mMoveNum;
			int wolfNum=is.getWolfs().size()-wMoveNum;
			int cabbageNum=is.getCabbages().size()-cabMoveNum;
			int cattleNum=is.getCattles().size()-catMoveNum;


			if(ministerNum>1){

				//牧師を動かす場合
				thinkNextMoveSubProcess(is, rideNum, mMoveNum+1, wMoveNum, cabMoveNum, catMoveNum);
				CoreLog.debug("add m1");

				if(cattleNum>0){
					CoreLog.debug("add cat1");
					thinkNextMoveSubProcess(is, rideNum, mMoveNum, wMoveNum, cabMoveNum, catMoveNum+1);
				}

				if(wolfNum>0){
					CoreLog.debug("add w1");
					thinkNextMoveSubProcess(is, rideNum, mMoveNum, wMoveNum+1, cabMoveNum, catMoveNum);
				}

				if(cabbageNum>0){
					CoreLog.debug("add cab1");
					thinkNextMoveSubProcess(is, rideNum, mMoveNum, wMoveNum, cabMoveNum+1, catMoveNum);
				}



			}else if(ministerNum==1){


				if((cattleNum>0 && wolfNum==0 &&cabbageNum==0) || (cabbageNum>0 && cattleNum==0) ||
						(wolfNum>0 && cattleNum==0)){
					thinkNextMoveSubProcess(is, rideNum, mMoveNum+1, wMoveNum, cabMoveNum, catMoveNum);
					CoreLog.debug("add m2");
				}

				if(cattleNum>0){
					CoreLog.debug("add cat2");
					thinkNextMoveSubProcess(is, rideNum, mMoveNum, wMoveNum, cabMoveNum, catMoveNum+1);
				}

				if(wolfNum>0){
					CoreLog.debug("add w2");
					thinkNextMoveSubProcess(is, rideNum, mMoveNum, wMoveNum+1, cabMoveNum, catMoveNum);
				}

				if(cabbageNum>0){
					CoreLog.debug("add cab2");
					thinkNextMoveSubProcess(is, rideNum, mMoveNum, wMoveNum, cabMoveNum+1, catMoveNum);
				}

			}else{
				//牧師が一人もいない場合



				if((cattleNum>0)){
					CoreLog.debug("add cat3");
					thinkNextMoveSubProcess(is, rideNum, mMoveNum, wMoveNum, cabMoveNum, catMoveNum+1);
				}

				if((wolfNum>0 )){
					CoreLog.debug("add w3");
					thinkNextMoveSubProcess(is, rideNum, mMoveNum, wMoveNum+1, cabMoveNum, catMoveNum);
				}

				if((cabbageNum>0)){
					CoreLog.debug("add cab3");
					thinkNextMoveSubProcess(is, rideNum, mMoveNum, wMoveNum, cabMoveNum+1, catMoveNum);
				}

			}

		}
	}

	/**
	 * thinkNextMoveの共通処理部分を抽出
	 * @param is
	 * @param rideNum
	 * @param mMoveNum
	 * @param wMoveNum
	 * @param cabMoveNum
	 * @param catMoveNum
	 */
	private void thinkNextMoveSubProcess(Island is, int rideNum,int mMoveNum,int wMoveNum,int cabMoveNum,int catMoveNum){

		targetMemory.addNextMemorys(new Memory(targetMemory, startIsland.clone(), endIsland.clone(),
				boat.clone(),mMoveNum, wMoveNum ,cabMoveNum, catMoveNum));

		thinkNextMove(is, rideNum-1, mMoveNum, wMoveNum, cabMoveNum, catMoveNum);
	}


	/**
	 * 思考
	 * @return
	 */
	private boolean think(){


		Island is=null;

		if(nowStartIsland){
			is=startIsland;
		}else{
			is=endIsland;


		}

		//ここでのtargetMemoryは移動先のメモリーであり、どうやってそこに移動するかの情報を持っている


		//移動するものと、移動してきたものが同じになるのを防ぐ
		if(targetMemory.getMinisterMoveNum()==bifmoveMinisterNum &&
				targetMemory.getWolfMoveNum()==bifmoveWolfNum &&
				targetMemory.getCabbageMoveNum()==bifmoveCabbageNum &&
				targetMemory.getCattleMoveNum()==bifmoveCattleNum &&
				targetMemory.getBifMemory()!=null){
			if(targetMemory.getNextMemorys().size()>1){
				for(int i=1;i<targetMemory.getNextMemorys().size();i++){
					Memory tar=targetMemory.getNextMemorys().get(i);
					if(tar.getMinisterMoveNum()==bifmoveMinisterNum &&
							tar.getWolfMoveNum()==bifmoveWolfNum &&
							tar.getCabbageMoveNum()==bifmoveCabbageNum &&
							tar.getCattleMoveNum()==bifmoveCattleNum ){
						targetMemory=tar;
						targetMemory.removeNextmemorys(0);
					}
				}
			}else{
				CoreLog.debug("zenkai to onazidesuzo");
				this.thinkRestartProcess(false);
				return false;
			}
		}


		if(targetMemory.getMinisterMoveNum()>moveMinisterNum){

			ArrayList<CharaModel> c=is.getMinisters();

			moveMinisterNum++;
			for(int i=0;i<c.size();i++){
				if(!c.get(i).isNowTarget()){						///もともとはisChanMoveでやっていたが、canMoveを移植した際に使わなくなったため変更
					CoreLog.debug("    move minister");		///代わりにすでにタッチされたかどうかでとる
					targetDefine(c.get(i));						///この場合、ＡＩの挙動を１００％正しくないと、正確な動きにならないはず
					break;
				}
			}
			return true;
		}else if(targetMemory.getWolfMoveNum()>moveWolfNum){
			ArrayList<CharaModel> c=is.getWolfs();

			moveWolfNum++;
			for(int i=0;i<c.size();i++){
				if(!c.get(i).isNowTarget()){
					CoreLog.debug("    move wolf");
					targetDefine(c.get(i));
					break;
				}
			}
			return true;

		}else if(targetMemory.getCabbageMoveNum()>moveCabbageNum){
			ArrayList<CharaModel> c=is.getCabbages();

			moveCabbageNum++;
			for(int i=0;i<c.size();i++){
				if(!c.get(i).isNowTarget()){
				CoreLog.debug("    move cabbage");
					targetDefine(c.get(i));
					break;
				}
			}
			return true;
		}else if(targetMemory.getCattleMoveNum()>moveCattleNum){
			ArrayList<CharaModel> c=is.getCattles();

			moveCattleNum++;
			for(int i=0;i<c.size();i++){
				if(!c.get(i).isNowTarget()){
					CoreLog.debug("    move cattle");
					targetDefine(c.get(i));
					break;
				}
			}
			return true;
		}





		return false;
	}




	/**
	 * 移動キャラの確定処理
	 * @param c
	 */
	public void targetDefine(CharaModel c){

		c.onTouchDown();

/*		gameController.changeTouchTarget(c);
	*/	targetX=c.getCenterX();
		targetY=c.getCenterY();



	}


	@Override
	public void callGameOver() {
		CoreLog.debug("call gameOver");
		targetMemory.setData(startIsland.clone(), endIsland.clone(), boat.clone());
		this.thinkRestartProcess(true);
	}

	/**
	 * ゲームを巻き戻す時の思考
	 */
	public void thinkRestartProcess(boolean nowTurnChange){

		this.isStopUpdate=true;
//		CoreLog.debug("return :");
		int count=0;

		while(true){

			count++;
			targetMemory=targetMemory.getBifMemory();


			if(targetMemory==null){
				CoreLog.debug("this game can not clear");
				gameController.gameOver();
				return;
			}

			if(targetMemory.getNextMemorys().size()>1){


				/*Memory a=targetMemory.getNextMemorys().get(0);
				targetMemory.removeNextmemorys(0);
				targetMemory=a;*/
				break;
			}



		}

		CoreLog.debugSimple("[return :"+count+"]",2);
		CoreLog.debug("back Turn ="+count);



		gameController.returnGameTurn(count,nowTurnChange);
		//gameController.reStart(targetMemory.getStartIsland(), targetMemory.getEndIsland(), targetMemory.getBoat(),targetMemory.getLayout());




	}


	@Override
	public void changeAiMoveCharaSpeed(){

	}

	@Override
	public int getMoveSpeed(){
		return 1;
	}








}
