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

package pp.monopoly.client;

import com.jme3.math.ColorRGBA;

import pp.monopoly.game.client.MonopolyClientConfig;

/**
 * Provides access to the Monopoly application configuration.
 * Extends {@link MonopolyClientConfig} to include additional properties specific to the client,
 * particularly those related to screen settings and visual customization.
 * <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 MonopolyAppConfig extends MonopolyClientConfig {

    /**
     * Converts a string value found in the properties file into an object of the specified type.
     * Extends the superclass method to support conversion to {@link ColorRGBA}.
     *
     * @param value      the string value to be converted
     * @param targetType the target type into which the value string is converted
     * @return the converted object of the specified type
     */
    @Override
    protected Object convertToType(String value, Class<?> targetType) {
        if (targetType == ColorRGBA.class)
            return makeColorRGBA(value);
        return super.convertToType(value, targetType);
    }

    /**
     * Converts the specified string value to a corresponding {@link ColorRGBA} object.
     *
     * @param value the color in the format "red, green, blue, alpha" with all values in the range [0..1]
     * @return a {@link ColorRGBA} object representing the color
     * @throws IllegalArgumentException if the input string is not in the expected format
     */
    private static ColorRGBA makeColorRGBA(String value) {
        String[] split = value.split(",", -1);
        try {
            if (split.length == 4)
                return new ColorRGBA(Float.parseFloat(split[0]),
                                     Float.parseFloat(split[1]),
                                     Float.parseFloat(split[2]),
                                     Float.parseFloat(split[3]));
        }
        catch (NumberFormatException e) {
            // deliberately left empty
        }
        throw new IllegalArgumentException(value + " should consist of exactly 4 numbers");
    }

    /**
     * The width of the game view resolution in pixels.
     */
    @Property("settings.resolution.width") //NON-NLS
    private int resolutionWidth = 1200;

    /**
     * The height of the game view resolution in pixels.
     */
    @Property("settings.resolution.height") //NON-NLS
    private int resolutionHeight = 800;

    /**
     * Specifies whether the game should start in full-screen mode.
     */
    @Property("settings.full-screen") //NON-NLS
    private boolean fullScreen = false;

    /**
     * Specifies whether gamma correction should be enabled.
     * If enabled, the main framebuffer is configured for sRGB colors,
     * and sRGB images are linearized.
     * <p>
     * Requires a GPU that supports GL_ARB_framebuffer_sRGB; otherwise, this setting will be ignored.
     * </p>
     */
    @Property("settings.use-gamma-correction") //NON-NLS
    private boolean useGammaCorrection = true;

    /**
     * Specifies whether full resolution framebuffers should be used on Retina displays.
     * This setting is ignored on non-Retina platforms.
     */
    @Property("settings.use-retina-framebuffer") //NON-NLS
    private boolean useRetinaFrameBuffer = false;

    /**
     * Specifies whether the settings window should be shown for configuring the game.
     */
    @Property("settings.show") //NON-NLS
    private boolean showSettings = false;

    /**
     * Specifies whether the JME statistics window should be shown in the lower left corner of the screen.
     */
    @Property("statistics.show") //NON-NLS
    private boolean showStatistics = false;

    /**
     * The color of the top text during gameplay, represented as a {@link ColorRGBA} object.
     */
    @Property("overlay.top.color") //NON-NLS
    private ColorRGBA topColor = ColorRGBA.White;

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

    /**
     * Returns the width of the game view resolution in pixels.
     *
     * @return the width of the game view resolution in pixels
     */
    public int getResolutionWidth() {
        return resolutionWidth;
    }

    /**
     * Returns the height of the game view resolution in pixels.
     *
     * @return the height of the game view resolution in pixels
     */
    public int getResolutionHeight() {
        return resolutionHeight;
    }

    /**
     * Returns whether the game should start in full-screen mode.
     *
     * @return {@code true} if the game should start in full-screen mode; {@code false} otherwise
     */
    public boolean fullScreen() {
        return fullScreen;
    }

    /**
     * Returns whether gamma correction is enabled.
     * If enabled, the main framebuffer is configured for sRGB colors,
     * and sRGB images are linearized.
     *
     * @return {@code true} if gamma correction is enabled; {@code false} otherwise
     */
    public boolean useGammaCorrection() {
        return useGammaCorrection;
    }

    /**
     * Returns whether full resolution framebuffers should be used on Retina displays.
     * This setting is ignored on non-Retina platforms.
     *
     * @return {@code true} if full resolution framebuffers should be used on Retina displays; {@code false} otherwise
     */
    public boolean useRetinaFrameBuffer() {
        return useRetinaFrameBuffer;
    }

    /**
     * Returns whether the settings window should be shown for configuring the game.
     *
     * @return {@code true} if the settings window should be shown; {@code false} otherwise
     */
    public boolean getShowSettings() {
        return showSettings;
    }

    /**
     * Returns whether the JME statistics window should be shown in the lower left corner of the screen.
     *
     * @return {@code true} if the statistics window should be shown; {@code false} otherwise
     */
    public boolean getShowStatistics() {
        return showStatistics;
    }

    /**
     * Returns the color of the top text during gameplay as a {@link ColorRGBA} object.
     *
     * @return the color of the top text during gameplay
     */
    public ColorRGBA getTopColor() {
        return topColor;
    }
}
