package sfs3.extensions.examples.tictactoe.handlers;

import com.smartfoxserver.bitswarm.data.TransportType;
import com.smartfoxserver.entities.User;
import com.smartfoxserver.entities.data.ISFSObject;
import com.smartfoxserver.entities.data.SFSObject;
import com.smartfoxserver.exceptions.SFSRuntimeException;
import com.smartfoxserver.extensions.BaseClientRequestHandler;
import com.smartfoxserver.extensions.ExtensionLogLevel;

import sfs3.extensions.examples.tictactoe.TicTacToeExtension;
import sfs3.extensions.examples.tictactoe.game.Board;
import sfs3.extensions.examples.tictactoe.game.Mark;

/**
 * This handler receives, validates and dispatches to the other users in the Room a game move sent by the active player.
 */
public class MoveHandler extends BaseClientRequestHandler
{
	@Override
	public void handleClientRequest(User user, ISFSObject params, TransportType type)
	{
		// Request must contain the 'r' and 'c' parameters, indicating which board slot was clicked by the player in turn
		if (!params.containsKey("r") || !params.containsKey("c"))
			throw new SFSRuntimeException("Invalid request, one or more mandatory params are missing; required 'r' and 'c'");
		
		TicTacToeExtension gameExt = (TicTacToeExtension) getParentExtension();
		Board board = gameExt.getGameBoard();
		
		// Extract parameters
		int	row = params.getInt("r");
		int col = params.getInt("c");
		
		gameExt.trace(String.format("Handling move from player %s (%s, %s)", user.getPlayerId(), row, col));
		
		// Game must be started
		if (gameExt.isGameStarted())
		{
			// The player sending the move must be the active one
			if (gameExt.getWhoseTurn() == user)
			{
				// The board slot corresponding to the passed coordinates must be empty
				if (board.getMarkAt(row, col) == Mark.EMPTY)
				{
					// Set game board mark
					board.setMarkAt(row, col, user.getPlayerId() == 1 ? Mark.CROSS : Mark.RING);
					
					// Send move to all users in the Room, including the player who made it
					ISFSObject outParams = new SFSObject();
					outParams.putInt("r", row);
					outParams.putInt("c", col);
					outParams.putInt("t", user.getPlayerId());
					
					send("move", outParams, gameExt.getParentRoom().getUserList());
					
					// Update game state
					gameExt.updateGameState();
				}
				
				// Wrong move
				else
					gameExt.trace(ExtensionLogLevel.WARN, "Wrong move error; slot " + row + "," + col + " is not empty");
			}
			
			// Wrong turn
			else
				gameExt.trace(ExtensionLogLevel.WARN, "Wrong move error; expected turn of player " + gameExt.getWhoseTurn() + ", received move from: " + user);
		}
		
		// Wrong game state
		else
			gameExt.trace(ExtensionLogLevel.WARN, "Wrong move error; game not yet started");
	}
}
