package sample.game.manager;

import java.util.ArrayList;

import library.core.model.CoreModel;
import sample.game.controller.GameController;
import sample.game.model.AiChara;
import sample.game.model.BoatModel;
import sample.game.model.CharaModel;
import sample.game.model.CharaModel.TARGET_TYPE;
import sample.game.model.NumBox;



public class LayoutManager{

	//左右にあるキャラの配置予定場所
	private CharaModel[] rightMinisters;
	private CharaModel[] rightCabbages;
	private CharaModel[] rightCattels;
	private CharaModel[] rightWolfs;

	private CharaModel[] leftMinisters;
	private CharaModel[] leftCabbages;
	private CharaModel[] leftCattels;
	private CharaModel[] leftWolfs;

	//縦の順番変換に使用　（真ん中のＩＤを０にしたいため（配列のIndex的な意味で））
	private int[] indexBox=new int[]{1,0,2};

	private static final int RIGHT_CHARA_X_TOP=705;
	private static final int CHARA_Y_TOP=110;
	private static final int CHARA_X_MARGIN=145;
	private static final int CHARA_Y_MARGIN=190;

	private static final int LEFT_CHARA_X_TOP=144;


	private int boatRideMenberNum=0;

	private int heightBase=0;
	private int heightDist=100;

	private int widthLeftBase=300;
	private int widthRightBase=1000;
	private int widthDist=150;

	//キャラの移動関連
	private ArrayList<Float> lenXs;
	private ArrayList<Float> lenYs;
	private ArrayList<Float> charaDefoCenterXs;
	private ArrayList<Float> charaDefoCenterYs;
	private float time;

	private float moveSpeed=1f;

	private int boatSize=1;

	public LayoutManager(boolean isNowTurnRight,int boatSize){


		rightMinisters=new CharaModel[3];
		rightCabbages=new CharaModel[3];
		rightCattels=new CharaModel[3];
		rightWolfs=new CharaModel[3];

		leftMinisters=new CharaModel[3];
		leftCabbages=new CharaModel[3];
		leftCattels=new CharaModel[3];
		leftWolfs=new CharaModel[3];


		this.boatSize=boatSize;

		indexBox=new int[]{1,0,2};
	}


	/**
	 * 右にキャラを追加
	 * @param type
	 * @param model
	 * @param setMove	//座標の移動までやってしまうかどうか
	 */
	public void addRight(CharaModel model,boolean setMove){

		int mId=0;

		switch (model.getType()) {
		case MINISTART:
			mId=0;
			for(int i=0;i<3;i++){
				if(rightMinisters[i]==null){
					rightMinisters[i]=model;
					model.setLayoutId(mId, indexBox[i]);
					if(!setMove) break;
					model.setXY(RIGHT_CHARA_X_TOP+CHARA_X_MARGIN*mId, CHARA_Y_TOP+CHARA_Y_MARGIN*indexBox[i]);
					break;
				}
			}
			break;
		case WOLF:
			mId=3;
			for(int i=0;i<3;i++){
				if(rightWolfs[i]==null){
					rightWolfs[i]=model;
					model.setLayoutId(mId, indexBox[i]);
					if(!setMove) break;
					model.setXY(RIGHT_CHARA_X_TOP+CHARA_X_MARGIN*mId, CHARA_Y_TOP+CHARA_Y_MARGIN*indexBox[i]);
					break;
				}
			}
			break;
		case CABBAGE:
			mId=1;
			for(int i=0;i<3;i++){
				if(rightCabbages[i]==null){
					rightCabbages[i]=model;
					model.setLayoutId(mId, indexBox[i]);
					if(!setMove) break;
					model.setXY(RIGHT_CHARA_X_TOP+CHARA_X_MARGIN*mId, CHARA_Y_TOP+CHARA_Y_MARGIN*indexBox[i]);
					break;
				}
			}
			break;
		case CATTLE:
			mId=2;
			for(int i=0;i<3;i++){
				if(rightCattels[i]==null){
					rightCattels[i]=model;
					model.setLayoutId(mId, indexBox[i]);
					if(!setMove) break;
					model.setXY(RIGHT_CHARA_X_TOP+CHARA_X_MARGIN*mId, CHARA_Y_TOP+CHARA_Y_MARGIN*indexBox[i]);
					break;
				}
			}
			break;
		}

	}


	/**
	 * 右のキャラの削除
	 * @param model
	 */
	public void removeRight(CharaModel model){

		switch (model.getType()) {
		case MINISTART:
			for(int i=0;i<3;i++){
				if(rightMinisters[i]==null) continue;

				if(rightMinisters[i].equals(model)){
					rightMinisters[i]=null;
				}
			}
			break;
		case WOLF:
			for(int i=0;i<3;i++){
				if(rightWolfs[i]==null) continue;

				if(rightWolfs[i].equals(model)){
					rightWolfs[i]=null;
				}
			}
			break;
		case CABBAGE:
			for(int i=0;i<3;i++){
				if(rightCabbages[i]==null) continue;

				if(rightCabbages[i].equals(model)){
					rightCabbages[i]=null;
				}
			}
			break;
		case CATTLE:
			for(int i=0;i<3;i++){
				if(rightCattels[i]==null) continue;

				if(rightCattels[i].equals(model)){
					rightCattels[i]=null;
				}
			}
			break;
		}
	}


	/**
	 *
	 * @param model
	 * @param setMove
	 */
	public void addLeft(CharaModel model,boolean setMove){

		int mId=0;

		switch (model.getType()) {
		case MINISTART:
			mId=0;
			for(int i=0;i<3;i++){
				if(leftMinisters[i]==null){
					leftMinisters[i]=model;
					model.setLayoutId(mId, indexBox[i]);
					if(!setMove) break;
					model.setXY(LEFT_CHARA_X_TOP+CHARA_X_MARGIN*mId, CHARA_Y_TOP+CHARA_Y_MARGIN*indexBox[i]);
					break;
				}
			}
			break;
		case WOLF:
			mId=3;
			for(int i=0;i<3;i++){
				if(leftWolfs[i]==null){
					leftWolfs[i]=model;
					model.setLayoutId(mId, indexBox[i]);
					if(!setMove) break;
					model.setXY(LEFT_CHARA_X_TOP+CHARA_X_MARGIN*mId, CHARA_Y_TOP+CHARA_Y_MARGIN*indexBox[i]);
					break;
				}
			}
			break;
		case CABBAGE:
			mId=1;
			for(int i=0;i<3;i++){
				if(leftCabbages[i]==null){
					leftCabbages[i]=model;
					model.setLayoutId(mId, indexBox[i]);
					if(!setMove) break;
					model.setXY(LEFT_CHARA_X_TOP+CHARA_X_MARGIN*mId, CHARA_Y_TOP+CHARA_Y_MARGIN*indexBox[i]);
					break;
				}
			}
			break;
		case CATTLE:
			mId=2;
			for(int i=0;i<3;i++){
				if(leftCattels[i]==null){
					leftCattels[i]=model;
					model.setLayoutId(mId, indexBox[i]);
					if(!setMove) break;
					model.setXY(LEFT_CHARA_X_TOP+CHARA_X_MARGIN*mId, CHARA_Y_TOP+CHARA_Y_MARGIN*indexBox[i]);
					break;
				}
			}
			break;
		}

	}

	public void removeLeft(CharaModel model){
		switch (model.getType()) {
		case MINISTART:
			for(int i=0;i<3;i++){
				if(leftMinisters[i]==null) continue;

				if(leftMinisters[i].equals(model)){
					leftMinisters[i]=null;
				}
			}
			break;
		case WOLF:
			for(int i=0;i<3;i++){
				if(leftWolfs[i]==null) continue;

				if(leftWolfs[i].equals(model)){
					leftWolfs[i]=null;
				}
			}
			break;
		case CABBAGE:
			for(int i=0;i<3;i++){
				if(leftCabbages[i]==null) continue;

				if(leftCabbages[i].equals(model)){
					leftCabbages[i]=null;
				}
			}
			break;
		case CATTLE:
			for(int i=0;i<3;i++){
				if(leftCattels[i]==null) continue;

				if(leftCattels[i].equals(model)){
					leftCattels[i]=null;
				}
			}
			break;
		}
	}




	/**
	 * キャラがボートに移動するための初期情報の作成
	 * @param boat
	 * @param charas
	 */
	public void charaMove2BoatInit(BoatModel boat,ArrayList<CharaModel> charas){

		if(lenXs==null){
			lenXs=new ArrayList<Float>();	//キャラとボートの距離
		}else{
			lenXs.clear();
		}

		if(lenYs==null){
			lenYs=new ArrayList<Float>();	//キャラとボートの距離
		}else{
			lenYs.clear();
		}


		//キャラの初期位置確保用リスト
		if(charaDefoCenterXs==null){
			charaDefoCenterXs=new ArrayList<Float>();
		}else{
			charaDefoCenterXs.clear();
		}

		if(charaDefoCenterYs==null){
			charaDefoCenterYs=new ArrayList<Float>();
		}else{
			charaDefoCenterYs.clear();
		}



		//距離を計算する
		for(int i=0;i<charas.size();i++){
			float cx=charas.get(i).getCenterX();
			float cy=charas.get(i).getCenterY();

			charaDefoCenterXs.add(cx);
			charaDefoCenterYs.add(cy);

			float distX=boat.getCenterX()-90+(i*60)-cx;	//複数に乗ることによるずれも考慮
			float distY=boat.getCenterY()-100-cy;		//少し座標をずらして顔が見えるようにする

			lenXs.add(distX);
			lenYs.add(distY);


		}

		time=0;

	}

	/**
	 * キャラのボートへの移動　移動が終わるとtrue
	 * @param charas
	 * @return
	 */
	public boolean charaMove2Boat(ArrayList<CharaModel> charas,float deltaTime,float moveTime){

		time+=deltaTime*moveSpeed;

		float rate=time/moveTime;
		if(rate>=1) rate=1;

		for(int i=0;i<charas.size();i++){
			charas.get(i).setXY(charaDefoCenterXs.get(i)+lenXs.get(i)*rate, charaDefoCenterYs.get(i)+lenYs.get(i)*rate);
		}

		if(rate>=1){

			for(int i=0;i<charas.size();i++){
				//設定ついでにアニメーションを変更
				if(charas.get(i).getType()!=TARGET_TYPE.CABBAGE){	//りんごにはアニメーションがないため

					charas.get(i).changeAnimation(0);
				}
			}

			return true;
		}

		return false;
	}

	private static final int BOAT_MOVE_LEN=430;	//ボートが動いているように見せるために動かす距離
	private boolean nowBackScreenRightPoint;	//画面が右を対象に映っているかどうか
	private boolean checkFlag=false;		//ゲームオーバー判定を行ったかどうか

	private float boatDefoX;
	private float boatDefoY;
	private float backScreenDefoX;
	private float backScreenDefoY;

	private float aiDefoX;


	public void moveBackScreenInit(CoreModel backScreen,BoatModel boat,ArrayList<CharaModel> charas,AiChara ai,boolean isStartIsland){
		time=0;

		boatDefoX=boat.getCenterX();
		boatDefoY=boat.getCenterY();

		backScreenDefoX=backScreen.getCenterX();
		backScreenDefoY=backScreen.getCenterY();

		if(charaDefoCenterXs==null){
			charaDefoCenterXs=new ArrayList<Float>();
		}else{
			charaDefoCenterXs.clear();
		}

		if(charaDefoCenterYs==null){
			charaDefoCenterYs=new ArrayList<Float>();
		}else{
			charaDefoCenterYs.clear();
		}

		for(int i=0;i<charas.size();i++){
			float cx=charas.get(i).getCenterX();
			float cy=charas.get(i).getCenterY();

			charaDefoCenterXs.add(cx);
			charaDefoCenterYs.add(cy);
		}

		if(ai!=null){
			aiDefoX=ai.getCenterX();
		}


		nowBackScreenRightPoint=isStartIsland;
		checkFlag=false;
	}

	//x座標　0〜1280を移動　0が右　　ボートは左がX870ぐらい 右420
	/**
	 * 背景場面の移動
	 * @param backScreen
	 * @param deltaTime
	 * @param 巻き戻しかどうか
	 * @return
	 */
	public boolean moveBackScreen(GameController controller,CoreModel backScreen,BoatModel boat,ArrayList<CharaModel> rideCharas,
			AiChara ai,NumBox numbox,float deltaTime,float moveTime,boolean isReturn){

		//たぶんmoveでやった方ら上の初期設定でこんなに値を確保しなくてすむ・・・

		if(isReturn) {
			deltaTime=-deltaTime;
		}

		time+=deltaTime*moveSpeed;


		float rate=time/moveTime;

		if(rate>1) rate=1;
		else if(rate<0) rate=0;


		if(nowBackScreenRightPoint){


			backScreen.setXY(backScreenDefoX+1280*rate, backScreenDefoY);

			for(int i=0;i<rideCharas.size();i++){
				rideCharas.get(i).setXY(charaDefoCenterXs.get(i)+BOAT_MOVE_LEN*rate, charaDefoCenterYs.get(i));
			}

			for(CharaModel c :rightMinisters){
				if(c!=null){
					c.setXY(RIGHT_CHARA_X_TOP+CHARA_X_MARGIN*c.getLayoutXId()+1280*rate,
							CHARA_Y_TOP+CHARA_Y_MARGIN*c.getLayoutYId());
				}
			}
			for(CharaModel c :rightWolfs){
				if(c!=null){
					c.setXY(RIGHT_CHARA_X_TOP+CHARA_X_MARGIN*c.getLayoutXId()+1280*rate,
							CHARA_Y_TOP+CHARA_Y_MARGIN*c.getLayoutYId());
				}
			}
			for(CharaModel c :rightCabbages){
				if(c!=null){
					c.setXY(RIGHT_CHARA_X_TOP+CHARA_X_MARGIN*c.getLayoutXId()+1280*rate,
							CHARA_Y_TOP+CHARA_Y_MARGIN*c.getLayoutYId());
				}
			}
			for(CharaModel c :rightCattels){
				if(c!=null){
					c.setXY(RIGHT_CHARA_X_TOP+CHARA_X_MARGIN*c.getLayoutXId()+1280*rate,
							CHARA_Y_TOP+CHARA_Y_MARGIN*c.getLayoutYId());
				}
			}


			for(CharaModel c :leftMinisters){
				if(c!=null){
					c.setXY(LEFT_CHARA_X_TOP+CHARA_X_MARGIN*c.getLayoutXId()+1280*rate-1280,
							CHARA_Y_TOP+CHARA_Y_MARGIN*c.getLayoutYId());
				}
			}
			for(CharaModel c :leftWolfs){
				if(c!=null){
					c.setXY(LEFT_CHARA_X_TOP+CHARA_X_MARGIN*c.getLayoutXId()+1280*rate-1280,
							CHARA_Y_TOP+CHARA_Y_MARGIN*c.getLayoutYId());
				}
			}
			for(CharaModel c :leftCabbages){
				if(c!=null){
					c.setXY(LEFT_CHARA_X_TOP+CHARA_X_MARGIN*c.getLayoutXId()+1280*rate-1280,
							CHARA_Y_TOP+CHARA_Y_MARGIN*c.getLayoutYId());
				}
			}
			for(CharaModel c :leftCattels){
				if(c!=null){
					c.setXY(LEFT_CHARA_X_TOP+CHARA_X_MARGIN*c.getLayoutXId()+1280*rate-1280,
							CHARA_Y_TOP+CHARA_Y_MARGIN*c.getLayoutYId());
				}
			}

			boat.setXY(boatDefoX+BOAT_MOVE_LEN*rate,boatDefoY);

			numbox.setXY(170+(940)*rate, numbox.getCenterY());

			if(ai!=null){
				ai.setXY(aiDefoX+(BOAT_MOVE_LEN-250)*rate, ai.getCenterY());
			}

		}else{

			backScreen.setXY(backScreenDefoX-1280*rate, backScreenDefoY);

			for(int i=0;i<rideCharas.size();i++){
				rideCharas.get(i).setXY(charaDefoCenterXs.get(i)-BOAT_MOVE_LEN*rate, charaDefoCenterYs.get(i));
			}

			for(CharaModel c :leftMinisters){
				if(c!=null){
					c.setXY(LEFT_CHARA_X_TOP+CHARA_X_MARGIN*c.getLayoutXId()-1280*rate,
							CHARA_Y_TOP+CHARA_Y_MARGIN*c.getLayoutYId());
				}
			}
			for(CharaModel c :leftWolfs){
				if(c!=null){
					c.setXY(LEFT_CHARA_X_TOP+CHARA_X_MARGIN*c.getLayoutXId()-1280*rate,
							CHARA_Y_TOP+CHARA_Y_MARGIN*c.getLayoutYId());
				}
			}
			for(CharaModel c :leftCabbages){
				if(c!=null){
					c.setXY(LEFT_CHARA_X_TOP+CHARA_X_MARGIN*c.getLayoutXId()-1280*rate,
							CHARA_Y_TOP+CHARA_Y_MARGIN*c.getLayoutYId());
				}
			}
			for(CharaModel c :leftCattels){
				if(c!=null){
					c.setXY(LEFT_CHARA_X_TOP+CHARA_X_MARGIN*c.getLayoutXId()-1280*rate,
							CHARA_Y_TOP+CHARA_Y_MARGIN*c.getLayoutYId());
				}
			}


			for(CharaModel c :rightMinisters){
				if(c!=null){
					c.setXY(1280+RIGHT_CHARA_X_TOP+CHARA_X_MARGIN*c.getLayoutXId()-1280*rate,
							CHARA_Y_TOP+CHARA_Y_MARGIN*c.getLayoutYId());
				}
			}
			for(CharaModel c :rightWolfs){
				if(c!=null){
					c.setXY(1280+RIGHT_CHARA_X_TOP+CHARA_X_MARGIN*c.getLayoutXId()-1280*rate,
							CHARA_Y_TOP+CHARA_Y_MARGIN*c.getLayoutYId());
				}
			}
			for(CharaModel c :rightCabbages){
				if(c!=null){
					c.setXY(1280+RIGHT_CHARA_X_TOP+CHARA_X_MARGIN*c.getLayoutXId()-1280*rate,
							CHARA_Y_TOP+CHARA_Y_MARGIN*c.getLayoutYId());
				}
			}
			for(CharaModel c :rightCattels){
				if(c!=null){
					c.setXY(1280+RIGHT_CHARA_X_TOP+CHARA_X_MARGIN*c.getLayoutXId()-1280*rate,
							CHARA_Y_TOP+CHARA_Y_MARGIN*c.getLayoutYId());
				}
			}

			numbox.setXY(1280-170-(940)*rate, numbox.getCenterY());

			boat.setXY(boatDefoX-BOAT_MOVE_LEN*rate,boatDefoY);

			if(ai!=null){
				ai.setXY(aiDefoX-(BOAT_MOVE_LEN-250)*rate, ai.getCenterY());
			}

		}

		//巻き戻すかどうかによって抜ける処理が異なる
		if(!isReturn){
			if(rate>=1){
				return true;
			}
		}else{
			if(rate<=0){
				return true;
			}
		}


		if(!checkFlag&&rate>=0.5f){
			checkFlag=true;
			controller.checkGameState();
		}



		return false;

	}




	/**
	 * キャラを船から下ろす処理の初期処理
	 */
	public void charaGetOffInit(ArrayList<CharaModel> rideChara,boolean isStartIsland){

		nowBackScreenRightPoint=isStartIsland;

		if(charaDefoCenterXs==null){
			charaDefoCenterXs=new ArrayList<Float>();
		}else{
			charaDefoCenterXs.clear();
		}

		if(charaDefoCenterYs==null){
			charaDefoCenterYs=new ArrayList<Float>();
		}else{
			charaDefoCenterYs.clear();
		}

		if(lenXs==null){
			lenXs=new ArrayList<Float>();	//キャラとボートの距離
		}else{
			lenXs.clear();
		}

		if(lenYs==null){
			lenYs=new ArrayList<Float>();	//キャラとボートの距離
		}else{
			lenYs.clear();
		}



		for(int i=0;i<rideChara.size();i++){

			CharaModel c=rideChara.get(i);

			float cx=c.getCenterX();
			float cy=c.getCenterY();

			charaDefoCenterXs.add(cx);
			charaDefoCenterYs.add(cy);

			if(nowBackScreenRightPoint){

				lenXs.add(LEFT_CHARA_X_TOP+CHARA_X_MARGIN*c.getLayoutXId()-cx);
				lenYs.add(CHARA_Y_TOP+CHARA_Y_MARGIN*c.getLayoutYId()-cy);
			}else{

				lenXs.add(RIGHT_CHARA_X_TOP+CHARA_X_MARGIN*c.getLayoutXId()-cx);
				lenYs.add(CHARA_Y_TOP+CHARA_Y_MARGIN*c.getLayoutYId()-cy);
			}
		}




		time=0;
	}

	/**
	 * キャラを船から下ろす処理		//addRight/addLeftはすでに行っていて、どこに配置されるかは確定している
	 * @param rideChara
	 */
	public boolean charaGetOff(ArrayList<CharaModel> rideChara,float deltaTime,float moveTime){

		time+=deltaTime*moveSpeed;

		float rate=time/moveTime;
		if(rate>1) rate=1;


		for(int i=0;i<rideChara.size();i++){
			CharaModel c=rideChara.get(i);
			c.setXY(charaDefoCenterXs.get(i)+lenXs.get(i)*rate, charaDefoCenterYs.get(i)+lenYs.get(i)*rate);
		}


		if(rate>=1){
			//キャラを止まった状態のアニメーションに変更
			for(int i=0;i<rideChara.size();i++){
				if(rideChara.get(i).getType()!=TARGET_TYPE.CABBAGE){
					rideChara.get(i).changeAnimation(0);
				}
			}

			return true;
		}

		return false;

	}



	//二人乗りボートを想定
	public void moveRightBoat(CharaModel c){
		boatRideMenberNum++;


	/*	//c.getView().setXY(800+(boatRideMenberNum%2==0?1:-1)*50,360);
		c.setXY(750+(boatRideMenberNum/(float)boatSize)*100f, 360);

		if(rightPositionFlags.size()>0){
			for(int i=0;i<rightPositionFlags.size();i++){
				CharaModel c2=rightPositionFlags.get(i);
				if(c2!=null){
					if(c2.equals(c)){
						rightPositionFlags.set(i, null);
					}
				}
			}
		}*/
	}

	public void moveLeftBoat(CharaModel c){
		boatRideMenberNum++;

	/*	c.setXY(450+(boatRideMenberNum/(float)boatSize)*100f,360);

		if(leftPositionFlags.size()>0){
			for(int i=0;i<leftPositionFlags.size();i++){
				CharaModel c2=leftPositionFlags.get(i);
				if(c2!=null){
					if(c2.equals(c)){
						leftPositionFlags.set(i, null);
					}
				}
			}
		}*/

	}


	public void resetRideBoatMenbers(){
		boatRideMenberNum=0;
	}



/*	*//**
	 * レイアウトを整理する
	 *//*
	public void layoutArrange(){
		ArrayList<CharaModel> c=new ArrayList<CharaModel>();

		for(int i=0;i<4;i++){
			for(int j=0;j<rightPositionFlags.size();j++){
				CharaModel tmp=rightPositionFlags.get(j);
				if(tmp!=null){
					switch (i) {
					case 0:
						if(tmp.getType()==TARGET_TYPE.MINISTART){
							c.add(tmp);
						}
						break;
					case 1:
						if(tmp.getType()==TARGET_TYPE.WOLF){
							c.add(tmp);
						}
						break;
					case 2:
						if(tmp.getType()==TARGET_TYPE.CABBAGE){
							c.add(tmp);
						}
						break;
					case 3:
						if(tmp.getType()==TARGET_TYPE.CATTLE){
							c.add(tmp);
						}
						break;
					}
				}

			}
		}

		rightPositionFlags.clear();
		for(int i=0;i<c.size();i++){
			this.setRight(c.get(i));
		}


		 c=new ArrayList<CharaModel>();

			for(int i=0;i<4;i++){
				for(int j=0;j<leftPositionFlags.size();j++){
					CharaModel tmp=leftPositionFlags.get(j);
					if(tmp!=null){
						switch (i) {
						case 0:
							if(tmp.getType()==TARGET_TYPE.MINISTART){
								c.add(tmp);
							}
							break;
						case 1:
							if(tmp.getType()==TARGET_TYPE.WOLF){
								c.add(tmp);
							}
							break;
						case 2:
							if(tmp.getType()==TARGET_TYPE.CABBAGE){
								c.add(tmp);
							}
							break;
						case 3:
							if(tmp.getType()==TARGET_TYPE.CATTLE){
								c.add(tmp);
							}
							break;
						}
					}

				}
			}

			leftPositionFlags.clear();
			for(int i=0;i<c.size();i++){
				this.setLeft(c.get(i));
			}


	}
*/



}
