#ifndef ADRICONF_GUI_H
#define ADRICONF_GUI_H

#include "CustomWidget/ComboBoxExtra.h"
#include "Utils/ConfigurationLoaderInterface.h"
#include "Utils/ConfigurationResolverInterface.h"
#include "Utils/WriterInterface.h"
#include "ValueObject/ComboBoxColumn.h"
#include "ValueObject/Device.h"
#include "ValueObject/DriverConfiguration.h"
#include "ValueObject/ShadowProfile.h"

#include <glibmm/i18n.h>
#include <gtkmm.h>

class GUI {
    private:
    LoggerInterface* logger;
    TranslatorInterface* translator;
    ConfigurationLoaderInterface* configLoader;
    ConfigurationResolverInterface* resolver;
    WriterInterface* writer;

    /* GUI-Related */
    Gtk::Window* pWindow;
    Gtk::FlowBox* profileList;
    Gtk::Stack* screenSwitcher;

    /* new Profile Screen */
    Gtk::Button* newProfileSaveButton;
    Gtk::Button* newProfileBackButton;
    Gtk::Entry* newProfileName;
    Gtk::Entry* newProfileExecutable;
    Gtk::CheckButton* newProfileUseRegexCheckButton;
    Gtk::Entry* newProfileSHA1;
    ComboBoxExtra<DriverConfiguration_ptr>* newProfileDriver;

    /* edit Profile Screen */
    Gtk::Button* editProfileSaveButton;
    Gtk::Button* editProfileBackButton;
    Gtk::Button* editProfileRemoveButton;
    std::unique_ptr<Gtk::MessageDialog> confirmDeleteProfileDialog;

    /* State-related */
    std::list<Device_ptr> systemWideConfiguration;
    std::list<DriverConfiguration_ptr> driverConfiguration;
    std::list<Device_ptr> userDefinedConfiguration;
    std::map<Glib::ustring, GPUInfo_ptr> availableGPUs;
    ShadowProfile_ptr currentApp;
    Device_ptr currentDriver;
    std::shared_ptr<ComboBoxExtra<std::pair<Glib::ustring, ProfileOption_ptr>>>
        primeComboBox;
    bool shouldIgnorePrimeComboBoxEvents;
    std::map<Glib::ustring, Gtk::SpinButton*> currentSpinButtons;

    /* Helpers */
    Glib::RefPtr<Gtk::Builder> gladeBuilder;

    void drawApplicationOptions();

    void setupAboutScreen();
    void setupNewProfileScreen();
    void setupEditProfileScreen();

    public:
    GUI(LoggerInterface* logger,
        TranslatorInterface* translator,
        ConfigurationLoaderInterface* configurationLoader,
        ConfigurationResolverInterface* resolver,
        WriterInterface* writer);

    virtual ~GUI();

    Gtk::Window* getWindowPointer();
    void saveProfiles();
    void drawProfileList();

    /* Signal Handlers */
    void onBackToProfileListPressed();
    void onNewApplicationTextFieldChanged();
    void onNewProfileSaveClicked();
    void onEditProfileSaveClicked();
    void onEditProfileRemoveClicked();
    void onApplicationSelected(const Profile_ptr& selectedProfile,
                               Device_ptr selectedProfileDriver);
    void onPrimeComboBoxChanged();
    void onConfirmDeleteProfileDialogResponse(int responseId);
};

#endif
