import java.util.List;

public class OnlinePlayer_1_1_0 extends OnlinePlayer {
	public OnlinePlayer_1_1_0(Integer size, AsyncSocket socket) {
		super(size, socket);
	}


	/**
	 * receives a message from the AsyncSocket
	 * implemented according to version 1.1.0 of https://github.com/lgc-4/ProgProjekt-Netzwerkstandard
	 * @param message the message from the socket
	 * @author Peer Ole Wachtel, Luca Conte
	 */
	@Override
	public void receive(String message) {
		SocketPackage p = new SocketPackage(message);

		List<String> data = p.splitData();
		switch (p.getName()) {
			case "IAM":
				if (data.size() < 2) break;
				if (this.board != null) break;

				int semester = Integer.parseInt(data.get(0));
				String username = p.getData().substring(data.get(0).length() + 1);

				int usedBoardSize = Math.min(GameController.semesterToBoardSize(semester), this.wantedBoardSize);
				
				this.setName(username);
				this.createBoard(usedBoardSize);
				this.enemy.createBoard(usedBoardSize);

				GameController.startGameWithInstancedPlayers((LocalPlayer)this.enemy, (Player)this, usedBoardSize);

				break;

			// TODO: IAMU

			case "COIN":
				if(!this.hasReceivedCoinPackage && (p.getData().equals("1") || p.getData().equals("0"))){
					this.myCoin = p.getData().equals("1");
					this.hasReceivedCoinPackage = true;
					this.ready();
				}
				break;


			case "SHOOT":
				if (Point.isValidSyntax(p.getData())){
					Point point = new Point(p.getData());
					this.enemy.receiveShoot(point);
				}
				break;

			case "HIT":
				if (data.size()==2){
					Point point = new Point(data.get(0));
					int typeIndex = Integer.parseInt(data.get(1));
					if (Point.isValidSyntax(data.get(0)) && typeIndex >= 0 && typeIndex < HitResponseType.values().length){
						this.enemy.receiveHit(new HitResponse(typeIndex, point));
					}
				}
				break;

			case "CHAT":
				//TODO CHAT
				break;

			default:
				//nichts passier da Paket ungültig
				break;
		}
	}

	/**
	 * sends introduction package IAM to online partner.
	 * @author Luca Conte
	 */
	@Override
	public synchronized void sendIAM() {
		if (this.enemy == null) throw new RuntimeException("enemy has not yet been defined");
		socket.send(new SocketPackage("IAM", GameController.boardSizeToSemester(this.wantedBoardSize) + " " + this.enemy.name));
	}

	/**
	 * receives a shot from the enemy and sends it to the online partner
	 * if it is not the enemies turn, this method does nothing.
	 * @param point the point to be shot
	 * @author Peer Ole Wachtel
	 */
	@Override
	public synchronized void receiveShoot(Point point){
		if (!this.enemy.myTurn) return;
		super.socket.send(new SocketPackage("SHOOT",point.toString()));
	}

	/**
	 * receives a hitresponse from the enemy player and sends it to the online partner
	 * @param hitResponse the hitresponse to be sent
	 * @author Peer Ole Wachtel
	 */
	@Override
	public synchronized void receiveHit(HitResponse hitResponse) {
		super.socket.send(new SocketPackage("HIT", hitResponse.toString()));
	}

	/**
	 * receives the coin toss result from the enemy player and sends it to the online partner
	 * if this player has already received the enemies coin, this method does nothing.
	 * @param coin the result of the coin toss
	 * @author Peer Ole Wachtel, Luca Conte
	 */
	@Override
	public synchronized void receiveCoin(boolean coin) {
		if (!this.hasReceivedCoin) {
			super.socket.send(new SocketPackage("COIN", String.valueOf(coin ? 1 : 0)));
			this.hasReceivedCoin = true;
			this.determineCoinToss();
		}
	}

	@Override
	public synchronized void shoot(Point point) {
		// SHOULD NEVER BE CALLED ON ONLINE PLAYER. ONLY ON HUMAN PLAYER
		return;
	}
}