package servlet;

import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import account.Account;
import account.AccountManager;
import framework.model3D.Position3D;
import game.Game;
import game.GameManager;
import game.Laser;
import game.LaserTurret;
import game.Mirror;
import game.Player;
import game.PlayerSearchVisitor;
import game.Team;
import game.Stage;
import room.Room;
import room.RoomManager;

public class GameUpdateServlet extends HttpServlet {

	public static final int TEAM_RED = 0;
	public static final int TEAM_BLUE = 1;
	public static final int GAME_START = 180000;

	// 受け取る部分							↓reqで受け取る　　　　　　　　　　　↓respで返す
	public void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, java.io.IOException {
		
System.out.println("----------------------------- GameUpdateServlet -----------------------------");
		
		// 返す文字の宣言 ↓返すためresp
		PrintWriter printwriter = resp.getWriter();
		GameManager gamemgr = GameManager.getInstance();
		
//System.out.println("GameUpdateServlet : データ取得");

		//sId
		String sId = req.getSession().getId();
		
		//Player
		Double pointX = Double.parseDouble(req.getParameter("myPointX"));
		Double pointY = Double.parseDouble(req.getParameter("myPointY"));
		Double pointZ = Double.parseDouble(req.getParameter("myPointZ"));
		Double angle = Double.parseDouble(req.getParameter("myAngle"));
		String mode = req.getParameter("mode");
		
//System.out.println("受け取ったplayer : " + pointX + " : " + pointY + " : " + pointZ + " : " + angle + " : " +  mode);
		
		//Laser
		String sLaser = req.getParameter("Laser");
		boolean Laser = false;
		Double lPointX = 0.0;
		Double lPointY = 0.0;
		Double lPointZ = 0.0;
		Double lAngle = 0.0;
		String lState = null;
		if (sLaser != null) {
			Laser = Boolean.parseBoolean(sLaser);
			lPointX = Double.parseDouble(req.getParameter("lPointX"));
			lPointY = Double.parseDouble(req.getParameter("lPointY"));
			lPointZ = Double.parseDouble(req.getParameter("lPointZ"));
			lAngle = Double.parseDouble(req.getParameter("lAngle"));
			lState = req.getParameter("lState");
System.out.println("Laser : " + Laser + " : " + lPointX  + " : " + lPointY  + " : " + lPointZ  
			+ " : " + lAngle  + " : " + lState);
		}

		//Mirror
		String sMirror = req.getParameter("Mirror");
		boolean Mirror = false;
		Double mPointX = 0.0;
		Double mPointY = 0.0;
		Double mPointZ = 0.0;
		Double mAngle = 0.0;
		String mState = null;
		if (sMirror != null) {
			mPointX = Double.parseDouble(req.getParameter("mPointX"));
			mPointY = Double.parseDouble(req.getParameter("mPointY"));
			mPointZ = Double.parseDouble(req.getParameter("mPointZ"));
			mAngle = Double.parseDouble(req.getParameter("mAngle"));
			mState = req.getParameter("mState");
System.out.println("Mirror : " + Mirror + " : " + mPointX  + " : " + mPointY  + " : " + mPointZ  
			+ " : " + mAngle  + " : " + mState);
		}

//System.out.println("GameUpdateServlet : visiter開始");
		//++++++++++++++++++++++++++++++++++visitor++++++++++++++++++++++++++++++++++

		PlayerSearchVisitor visitor = new PlayerSearchVisitor(sId);
		gamemgr.accept(visitor);
				
		Game game = visitor.getGame();					//当人のゲームを特定
		Team team = visitor.getTeam();					//所属チームの特定
		Account account = visitor.getPlayerAccount();	//個人を特定
		
		//++++++++++++++++++++++++++++++++++visitor++++++++++++++++++++++++++++++++++
//System.out.println("GameUpdateServlet : visiter終了");

		//Team分け
		Team redTeam = game.getTeamRed();
		Team blueTeam = game.getTeamBlue();			

		Player myPlayer;
		myPlayer = account.getPlayer();

//System.out.println("GameUpdateServlet : 自分を更新");
		//自分を更新
		myPlayer.setPoint(new Position3D(pointX,pointY,pointZ));
		myPlayer.setAngle(angle);
		myPlayer.setMode(mode);

		//ゴール判定
		int myColor = account.getTeam();
		if(game.getState().equals("play")) {
			if(game.getStage().isFinished(myColor, new Position3D(myPlayer.getPointX(),myPlayer.getPointY(),myPlayer.getPointZ())) == true){
				if(myColor == TEAM_RED) {
					game.setState("red");				
				} else if(myColor == TEAM_BLUE) {
					game.setState("blue");				
				}
			}
		}
//System.out.println("GameUpdateServlet : レーザを更新");
		//レーザの情報を格納　
		if(Laser == true) {
			LaserTurret myLaserTurret = team.getLaserTurret();
			
			//新規設置　チームのレーザがない場合
			if(myLaserTurret == null) {
				//クールタイムの確認
				if(team.getCoolTimeFlag() == false) {
					team.createLaserTurret(lPointX, lPointY, lPointZ, lAngle, lState, sId);
				}
				
			//情報更新　設置してあるレーザの情報更新　設置者のsIdが一致したとき
			} else if(myLaserTurret.getsId().equals(sId)) {
//System.out.println("myLaserTurret.gesId().equals(sId) 1");				
				//stateがpreの時はupdate
				if(lState.equals("pre")) {
					if(team.getLaserTurret() != null) {
						team.updateLaserTurret(lAngle, lState);	//本仕様
					} else {
						team.createLaserTurret(lPointX, lPointY, lPointZ, lAngle, lState, sId);	//仮仕様
					}				
					//lStateがcompでレーザが無い時に、newLaserかつgameのuniverseに配置
				} else if(lState.equals("comp") && myLaserTurret.getLaser() == null) {
System.out.println("lState.equals(comp) && myLaserTurret.getLaser() == null 2");				
					team.updateLaserTurret(lAngle, lState);	//本仕様
System.out.println("lState.equals(comp) && myLaserTurret.getLaser() == null 3");				
//					team.createLaserTurret(lPointX, lPointY, lPointZ, lAngle, lState, sId);	//仮仕様
					game.placeLaser(myLaserTurret.createLaser(myLaserTurret.getX(), myLaserTurret.getY(), myLaserTurret.getZ()));
System.out.println("lState.equals(comp) && myLaserTurret.getLaser() == null 4");				
				}
			}

		}
		
		//ミラーの情報を格納
		if(Mirror == true) {
			Mirror myMirror = team.getMyMirror(sId);
			
			//myMirrorが無ければcreate
			if(myMirror == null) {
				team.createMirror(mPointX,mPointY,mPointZ,mAngle,mState,sId);
				
			//myMirrorがある場合
			} else {
				//preの時は情報をupdate
				if(mState.equals("pre")) {
					team.updateMirror(mAngle, mState, myMirror);
				//preからonに変わった時は、updateとplaceMirror
				} else if (mState.equals("on") && myMirror.getState().equals("pre")) {
					team.updateMirror(mAngle, mState, myMirror);
					game.placeMirror(myMirror);
				}
			}
		}
		
//System.out.println("GameUpdateServlet : データを送り返す");

		//送り返す(全員分)　visit

		printwriter.println("<game>");
		printwriter.println("<manager time=\"" + (int)game.remainTime() + "\" game=\"" + game.getState() + "\"></manager>");
System.out.println("manager time=" + (int)game.remainTime() + " game=" + game.getState());

		printwriter.println("<players>");

			//自分の情報を転送
			printwriter.println("<myPlayer hp = \"" + myPlayer.getHp() + "\" hit = \"" + myPlayer.getHit() + "\">");
			printwriter.println("</myPlayer>");
			myPlayer.setHit("no");
	
			//赤チームの情報を転送
			printwriter.println("<teamRed>");
			for(int i=0; i<redTeam.getTeamMemberCount(); i++){

				Account ac = new Account();
				ac = game.getTeamMemberExceptSelf(i, TEAM_RED, sId);
				if(ac != null){
					Player player = ac.getPlayer();
					printwriter.println("<player sid = \"" + ac.getsId() + "\" "
							+ "pointX = \"" + player.getPointX() + "\" pointY = \"" + player.getPointY() +"\" "
							+ "pointZ = \"" + player.getPointZ() + "\" angle = \"" + player.getAngle() + "\" "
							+ "hp = \"" + player.getHp() + "\" hit = \"" + player.getHit() + "\" mode = \"" + player.getMode() + "\">");
System.out.println("name : " + ac.getName() + " mode = " + player.getMode());
					printwriter.println("</player>");
				}
			}
			
			printwriter.println("</teamRed>");
	
			//青チームの情報を転送
			printwriter.println("<teamBlue>");
			for(int i=0;i<blueTeam.getTeamMemberCount();i++){
				Account ac = new Account();
				ac = game.getTeamMemberExceptSelf(i, TEAM_BLUE, sId);
				if(ac != null){
					Player player = ac.getPlayer();
					printwriter.println("<player sid = \"" + ac.getsId() + "\" "
							+ "pointX = \"" + player.getPointX() + "\" pointY = \"" + player.getPointY() +"\" "
							+ "pointZ = \"" + player.getPointZ() + "\" angle = \"" + player.getAngle() + "\" "
							+ "hp = \"" + player.getHp() + "\" hit = \"" + player.getHit() + "\" mode = \"" + player.getMode() + "\">");
System.out.println("name : " + ac.getName() + " mode = " + player.getMode());
					printwriter.println("</player>");
				}
			}			
			printwriter.println("</teamBlue>");				
		
			printwriter.println("</players>");
			
			printwriter.println("<item>");
//System.out.println("GameUpdateServlet : <item>");
			
				printwriter.println("<teamRed>");
	
				//laser　redチーム
				LaserTurret redLaserTurret = redTeam.getLaserTurret();
				//laserのクールタイムを設定
				String redCool = "off";
				if(redTeam.getCoolTimeFlag() == true) {
					redCool = "on";						
				}
				//クールタイムを送信
				printwriter.println("<cool laser=\"" + redCool + "\"></cool>");
				if(redLaserTurret != null) {
					Laser redLaser = redLaserTurret.getLaser();
					if (redLaser != null) {
						//laserの情報を送信
						printwriter.println("<laser pointX=\"" + redLaser.getX() + "\" pointY=\"" + redLaser.getY() + "\" pointZ=\"" + redLaser.getZ() + "\" angle=\"" +redLaser.getAngle() + "\" state=\"on\">");
					} else {
						//laserTurretの情報を送信
						printwriter.println("<laser pointX=\"" + redLaserTurret.getX() + "\" pointY=\"" + redLaserTurret.getY() + "\" pointZ=\"" + redLaserTurret.getZ() + "\" angle=\"" + redLaserTurret.getAngle() + "\" state=\"pre\">");
					}
					printwriter.println("</laser>");
				}

				
				//mirror
				Mirror redMirror = redTeam.getMyMirror(sId);
				if(redMirror != null) {
					//mirrorの情報を送信
					printwriter.println("<mirror id=\"" + sId +
											"\" pointX=\"" + redMirror.getX() + 
											"\" pointY=\"" + redMirror.getY() + 
											"\" pointZ=\"" + redMirror.getZ() + 
											"\" angle=\"" + redMirror.getAngle() + 
											"\" state=\"" + redMirror.getState() + "\">");
					printwriter.println("</mirror>");
				}

				//bomb
					//printwriter.println("<bomb id="xxx" pointX=”xx” pointY=”yy” pointZ=”zz” state=”***”>");
					//printwriter.println("</bomb>");
				
				printwriter.println("</teamRed>");
				
				printwriter.println("<teamBlue>");
	
				//laser blueチーム
				LaserTurret blueLaserTurret = blueTeam.getLaserTurret();
				//laserのクールタイムを設定
				String blueCool = "off";
				if(blueTeam.getCoolTimeFlag() == true) {
					blueCool = "on";						
				}
				//クールタイムを送信
				printwriter.println("<cool laser=\"" + blueCool + "\"></cool>");
				if(blueLaserTurret != null) {
					Laser blueLaser = blueLaserTurret.getLaser();
					if(blueLaser != null) {
						//laserの情報を送信
						printwriter.println("<laser pointX=\"" + blueLaser.getX() + "\" pointY=\"" + blueLaser.getY() + "\" pointZ=\"" + blueLaser.getZ() + "\" angle=\"" + blueLaser.getAngle() + "\" state=\"on\">");
					} else {
						//laserTurretの情報を送信
						printwriter.println("<laser pointX=\"" + blueLaserTurret.getX() + "\" pointY=\"" + blueLaserTurret.getY() + "\" pointZ=\"" + blueLaserTurret.getZ() + "\" angle=\"" + blueLaserTurret.getAngle() + "\" state=\"pre\">");
					}
					printwriter.println("</laser>");
				}

				//mirror
				Mirror blueMirror = blueTeam.getMyMirror(sId);
				if(blueMirror != null) {
					//mirrorの情報を送信
					printwriter.println("<mirror id=\"" + sId + 
											"\" pointX=\"" + blueMirror.getX() + 
											"\" pointY=\"" + blueMirror.getY() + 
											"\" pointZ=\"" + blueMirror.getZ() +
											"\" angle=\"" + blueMirror.getAngle() +
											"\" state=\"" + blueMirror.getState() + "\">");
					printwriter.println("</mirror>");
				}
				
				//bomb
					//printwriter.println("<bomb id="xxx" pointX=”xx” pointY=”yy” pointZ=”zz” state=”***”>");
					//printwriter.println("</bomb>");
							
				printwriter.println("</teamBlue>");

			printwriter.println("</item>");
//			System.out.println("GameUpdateServlet : </item>");
			
		printwriter.println("</game>");
		System.out.println("GameUpdateServlet : </game>");
		
	}
		
	// 返す部分(テスト用)
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, java.io.IOException {

		// 共有させることによってこちらだけで実効できる
		doPost(req, resp);

	}


}
