////////////////////////////////////////
// Programming project code
// UniBw M, 2022, 2023, 2024
// www.unibw.de/inf2
// (c) Mark Minas (mark.minas@unibw.de)
////////////////////////////////////////

package pp.battleship.game.client;

import pp.battleship.message.client.ShootMessage;
import pp.battleship.message.server.EffectMessage;
import pp.battleship.model.IntPoint;
import pp.battleship.model.Shell;
import pp.battleship.model.ShipMap;
import pp.battleship.notification.Sound;

import java.lang.System.Logger.Level;

/**
 * Represents the state of the client where players take turns to attack each other's ships.
 */
class BattleState extends ClientState {
    private boolean myTurn;

    /**
     * Constructs a new instance of {@link BattleState}.
     *
     * @param logic  the game logic
     * @param myTurn true if it is my turn
     */
    public BattleState(ClientGameLogic logic, boolean myTurn) {
        super(logic);
        this.myTurn = myTurn;
    }

    @Override
    public boolean showBattle() {
        return true;
    }

    @Override
    public void clickOpponentMap(IntPoint pos) {
        if (!myTurn)
            logic.setInfoText("wait.its.not.your.turn");
        else if (logic.getOpponentMap().isValid(pos))
            logic.send(new ShootMessage(pos));
    }

    /**
     * Reports the effect of a shot based on the server message.
     *
     * @param msg the message containing the effect of the shot
     */
    @Override
    public void receivedEffect(EffectMessage msg) {
        ClientGameLogic.LOGGER.log(Level.INFO, "report effect: {0}", msg); //NON-NLS

        myTurn = msg.isMyTurn();
        logic.setInfoText(msg.getInfoTextKey());
        Shell shell = new Shell(msg.getShot());
        affectedMap(msg).add(shell);
        logic.playSound(Sound.SHELL_FLYING);
        logic.setState(new ShootingState(logic, shell, myTurn, msg));
    }

    /**
     * Determines which map (own or opponent's) should be affected by the shot based on the message.
     *
     * @param msg the effect message received from the server
     * @return the map (either the opponent's or player's own map) that is affected by the shot
     */
    private ShipMap affectedMap(EffectMessage msg) {
        return msg.isOwnShot() ? logic.getOpponentMap() : logic.getOwnMap();
    }
}
