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

package pp.battleship.game.singlemode;

import pp.battleship.BattleshipConfig;
import pp.battleship.model.IntPoint;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Class providing access to the Battleship client configuration.
 * Extends {@link BattleshipConfig} to include additional properties specific to the client.
 * This class manages configuration settings related to the RobotClient's behavior
 * and the game maps used in single mode.
 * <p>
 * <b>Note:</b> Attributes of this class should not be marked as {@code final}
 * to ensure proper functionality when reading from a properties file.
 * </p>
 */
public class BattleshipClientConfig extends BattleshipConfig {

    /**
     * Array representing the predefined shooting locations for the RobotClient.
     * The array stores coordinates in pairs, where even indices represent x-coordinates
     * and odd indices represent y-coordinates.
     */
    @Property("robot.targets")
    private int[] robotTargets = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

    /**
     * The delay (in milliseconds) between shots fired by the RobotClient.
     */
    @Property("robot.delay")
    private int delay = 750;

    /**
     * Path to the file representing the opponent's map.
     */
    @Property("map.opponent")
    private String opponentMap;

    /**
     * Path to the file representing the player's own map.
     */
    @Property("map.own")
    private String ownMap;

    /**
     * Creates a default {@code BattleshipClientConfig} with predefined values.
     */
    public BattleshipClientConfig() {
        // Default constructor
    }

    /**
     * Returns an iterator of {@link IntPoint} objects representing the predefined
     * shooting locations for the RobotClient.
     *
     * @return an iterator of {@code IntPoint} representing the shooting locations.
     */
    public Iterator<IntPoint> getRobotTargets() {
        List<IntPoint> targets = new ArrayList<>();
        for (int i = 0; i < robotTargets.length; i += 2) {
            int x = robotTargets[i];
            int y = robotTargets[i + 1];
            targets.add(new IntPoint(x, y));
        }
        return targets.iterator();
    }

    /**
     * Returns the delay (in milliseconds) between shots by the RobotClient.
     *
     * @return the delay in milliseconds.
     */
    public int getDelay() {
        return delay;
    }

    /**
     * Returns the file representing the opponent's map.
     *
     * @return the opponent's map file, or {@code null} if not set.
     */
    public File getOpponentMap() {
        return opponentMap == null ? null : new File(opponentMap);
    }

    /**
     * Returns the file representing the player's own map.
     *
     * @return the player's own map file, or {@code null} if not set.
     */
    public File getOwnMap() {
        return ownMap == null ? null : new File(ownMap);
    }

    /**
     * Determines if the game is in single mode based on the presence of an opponent map.
     *
     * @return {@code true} if the opponent map is set, indicating single mode; {@code false} otherwise.
     */
    public boolean isSingleMode() {
        return opponentMap != null;
    }
}
