/*
Copyright (C) 2001-2022 The Exult Team

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#ifndef VIDEOOPTIONS_GUMP_H
#define VIDEOOPTIONS_GUMP_H

#include "Modal_gump.h"
#include <array>
#include <memory>
#include <string>
#include "imagewin/imagewin.h"

class Gump_button;

class VideoOptions_gump : public Modal_gump {
	static VideoOptions_gump *video_options_gump;

private:
	uint32 resolution;
	int scaling;
	int scaler;
	int fullscreen;
	uint32 game_resolution;
	std::vector<uint32> resolutions;
	std::vector<uint32> win_resolutions;
	std::vector<uint32> game_resolutions;
	int fill_scaler;
	Image_window::FillMode fill_mode;
	bool has_ac;
	bool share_settings;

	bool o_share_settings;
	uint32 o_resolution;
	int o_scaling;
	int o_scaler;
	uint32 o_game_resolution;
	int o_fill_scaler;
	Image_window::FillMode o_fill_mode;
	bool highdpi;
	bool o_highdpi;

	Image_window::FillMode startup_fill_mode;

	enum button_ids {
	    id_first = 0,
	    id_apply = id_first,
	    id_help,
	    id_cancel,
	    id_fullscreen,
	    id_share_settings,
	    id_high_dpi,
	    id_resolution,  // id_resolution and all past it
	    id_scaler,      // are deleted by rebuild_buttons
	    id_scaling,
	    id_game_resolution,
	    id_fill_scaler,
	    id_fill_mode,
	    id_has_ac,
	    id_count
	};
	std::array<std::unique_ptr<Gump_button>, id_count> buttons;

public:
	VideoOptions_gump();
	static VideoOptions_gump *get_instance() {
		return video_options_gump;
	}

	// Paint it and its contents.
	void paint() override;
	void close() override;

	// Handle events:
	bool mouse_down(int mx, int my, int button) override;
	bool mouse_up(int mx, int my, int button) override;

	void toggle(Gump_button *btn, int state);
	void rebuild_buttons();
	void rebuild_dynamic_buttons();

	void load_settings(bool Fullscreen);
	void save_settings();
	void cancel();
	void help();

	void set_scaling(int scaleVal) {
		scaling = scaleVal;
	}
	void set_scaler(int scalerNum) {
		scaler = scalerNum;
	}
	void set_resolution(uint32 Res) {
		resolution = Res;
	}
	void set_game_resolution(uint32 gRes) {
		game_resolution = gRes;
	}
	void set_fill_scaler(int f_scaler) {
		fill_scaler = f_scaler;
	}
	void set_fill_mode(Image_window::FillMode f_mode) {
		fill_mode = f_mode;
	}

	void toggle_resolution(int state) {
		if (fullscreen) resolution = resolutions[state];
		else resolution = win_resolutions[state];
	}

	void toggle_scaling(int state) {
		scaling = state;
	}

	void toggle_scaler(int state) {
		scaler = state;
		rebuild_dynamic_buttons();
	}

	void toggle_fullscreen(int state) {
		if (share_settings)
			fullscreen = state;
		else {
			load_settings(state); // overwrites old settings
			rebuild_buttons();
		}
	}

	void toggle_game_resolution(int state) {
		game_resolution = game_resolutions[state];
	}

	void toggle_fill_scaler(int state) {
		fill_scaler = state;
	}

	void toggle_fill_mode(int state) {
		if (state == 0) {
			fill_mode = Image_window::Fill;
		} else if (state == 3) {
			fill_mode = startup_fill_mode;
		} else {
			fill_mode = static_cast<Image_window::FillMode>((state << 1) | (has_ac ? 1 : 0));
		}
		rebuild_dynamic_buttons();
	}

	void toggle_aspect_correction(int state) {
		has_ac = state != 0;
		fill_mode = static_cast<Image_window::FillMode>((fill_mode&~1) | (has_ac ? 1 : 0));
	}

	void toggle_share_settings(int state) {
		share_settings = state;
	}

	void toggle_high_dpi(int state) {
		highdpi = state;
	}
};

#endif
