#ifndef __GUIMODULECOMMON_H__
#define __GUIMODULECOMMON_H__
#include <iostream>
#include <Ogre.h>
#include <nlohmann/json.hpp>
#include "Components.h"
#include "GameData.h"
namespace ECS
{

struct GUI {
    bool enabled;
    bool grab;
    bool grabChanged;
    bool narrationBox;
    bool mainMenu;
    bool enableActions;
    Ogre::String narrationText;
    std::vector<Ogre::String> choices;
    int narration_answer;
    struct NarrationHandler {
    private:
        Ogre::String mnarrationText;
        std::vector<Ogre::String> mchoices;
        int narration_answer;
        nlohmann::json props;

    private:
        bool complete;
        bool active;
    public:
        bool is_complete()
        {
            return complete;
        }
        bool is_active()
        {
            return active;
        }
        const Ogre::String &getNarrationText() const
        {
            return mnarrationText;
        }
        const std::vector<Ogre::String> &getChoices() const
        {
            return mchoices;
        }
        void progress()
        {
            _event("narration_progress");
        }
        void setNarrationAnswer(int answer)
        {
            narration_answer = answer;
            _event("narration_answered");
        }
        int getNarrationAnswer() const
        {
            return narration_answer;
        }

        NarrationHandler(): complete(false), active(false) {}
    private:
        virtual void finish() = 0;
        virtual void activate() = 0;
        virtual void event(const Ogre::String &event) = 0;
    protected:
        void _activate()
        {
            activate();
            active = true;
        }
        void _finish()
        {
            finish();
            complete = true;
        }
        void _narration(const Ogre::String &text, const std::vector<Ogre::String> &choices)
        {
            mnarrationText = text;
            mchoices = choices;

        }
        void _clear_narration()
        {
            mnarrationText = "";
            mchoices.clear();
        }
    public:
        void _event(const Ogre::String &ev)
        {
            if (!active && !complete)
                _activate();
            event(ev);
        }
        virtual ~NarrationHandler() {}
        void setProperties(const Ogre::String &properties)
        {
            props = nlohmann::json::parse(properties);
        }
        Ogre::String getProperties() const
        {
            return props.dump();
        }
        const nlohmann::json &getPropsJSON() const
        {
            return props;
        }
    };

    static void setWindowGrab(bool g = true)
    {
        ECS::GUI &gui = ECS::get().get_mut<GUI>();
        if (gui.grab != g) {
            gui.grab = g;
            gui.grabChanged = true;
            ECS::get().modified<GUI>();
        }
    }
    static void finish()
    {
        ECS::GUI &gui = ECS::get().get_mut<ECS::GUI>();
        gui.enabled = false;
        gui.mainMenu = false;
        gui.narrationBox = false;
        ECS::get().modified<ECS::GUI>();
        setWindowGrab(true);
    }
    std::vector<NarrationHandler *> narrationHandlers;
    void addNarrationHandler(struct NarrationHandler *handler)
    {
        narrationHandlers.push_back(handler);
    }
    void removeNarrationHandler(struct NarrationHandler *handler)
    {
        auto it = std::find(narrationHandlers.begin(), narrationHandlers.end(), handler);
        narrationHandlers.erase(it);
    }
};
}

#endif // GUIMODULECOMMON_H
