#ifndef SRC_UI_ROM_SETTINGS_WIDGET_HPP_
#define SRC_UI_ROM_SETTINGS_WIDGET_HPP_

#include <optional>
#include <QFrame>
#include "src/core/settings.hpp"
#include "src/core/sdcard.hpp"
#include "src/core/rom.hpp"

namespace Ui {
	class RomSettingsWidget;
}

class RomSettingsWidget : public QWidget {
	Q_OBJECT

	private:
	Ui::RomSettingsWidget *m_ui;
	bool m_suppressEvents;
	bool m_accurateDepthCompare;
	bool m_suggestOverclock;
	bool m_supportsMouse;
	bool m_showAdvancedOptions;
	std::vector<SdCardInfo> m_sdCards;

	public:
	explicit RomSettingsWidget( QWidget *parent = nullptr );
	virtual ~RomSettingsWidget();

	void reloadHotkeyInfo();
	void setSettings(
		const Uuid &inputMode,
		GfxPlugin gfxPlugin,
		bool overclockCpu,
		bool overclockVi,
		WidescreenMode widescreen,
		bool bigEEPROM,
		bool useInterpreter,
		bool upscaleTexRects,
		bool removeBorders,
		bool emulateFramebuffer,
		bool accurateDepthCompare,
		bool rspEmulation,
		GfxPlugin recommendedPlugin,
		bool suggestOverclock,
		const N64InputTypes &inputTypes,
		const std::optional<bool> &syncSaves,
		const std::string &sdCard
	);

	const Uuid &getInputMode() const;
	GfxPlugin getGraphicsPlugin() const;
	bool overclockCpu() const;
	bool overclockVi() const;
	WidescreenMode widescreen() const;
	bool bigEEPROM() const;
	bool useInterpreter() const;
	bool upscaleTexRects() const;
	bool removeBorders() const;
	bool emulateFramebuffer() const;
	inline bool accurateDepthCompare() const noexcept { return m_accurateDepthCompare; }
	bool glidenRspEmulation() const;
	std::string sdCard() const;

	private:
	void updateWarningVisibility();
	void updateAdvancedOptionsVisibility();
	void updatePluginSettingsVisibility();
	void updatePluginLangterms( GfxPlugin recommendedPlugin );

	public:
	void readjustSize();
	void refreshSdCards();
	bool getAdvancedOptionsVisibility() const;
	void setAdvancedOptionsVisibility( bool visible );

	private slots:
	void inputModeSelectionChanged();
	void overclockCpuToggled( bool checked );
	void overclockViToggled( bool checked );
	void widescreenToggled( bool checked );
	void bigEepromToggled( bool checked );
	void useInterpreterToggled( bool checked );
	void trueWidescreenToggled( bool checked );
	void upscaleTexRectsToggled( bool checked );
	void removeBordersToggled( bool checked );
	void emulateFramebufferToggled( bool checked );
	void accurateDepthCompareToggled( bool checked );
	void rspEmulationToggled( bool checked );
	void saveSyncingToggled( bool checked );
	void pluginChanged();
	void advancedOptionsToggled();
	void sdCardChanged( int index );
	void manageSdCards();

	signals:
	void inputModeChanged();
	void graphicsPluginChanged();
	void overclockCpuChanged( bool );
	void overclockViChanged( bool );
	void widescreenChanged( unsigned char );
	void bigEepromChanged( bool );
	void useInterpreterChanged( bool );
	void upscaleTexRectsChanged( bool );
	void removeBordersChanged( bool );
	void emulateFramebufferChanged( bool );
	void accurateDepthCompareChanged( bool );
	void rspEmulationChanged( bool );
	void showAdvancedOptionsChanged( bool );
	void saveSyncingChanged( bool );
	void activeSdCardChanged( std::string );

};

class RomSettingsWidgetSlot : public QFrame {
	Q_OBJECT

	public:
	RomSettingsWidgetSlot( QWidget *parent = nullptr );
	virtual ~RomSettingsWidgetSlot() {}

	void place( RomSettingsWidget *widget );
	RomSettingsWidget *widget() const;

	inline bool hasWidget() const { return this->widget() != nullptr; }

};

#endif /* SRC_UI_ROM_SETTINGS_WIDGET_HPP_ */
