
#ifndef OSGEARTH_IMGUI_OSGEVENTHANDLER_H
#define OSGEARTH_IMGUI_OSGEVENTHANDLER_H 1

#include <osgEarth/Config>
#include <osgViewer/ViewerEventHandlers>

namespace osg {
    class Camera;
}

struct ImGuiSettingsHandler;

namespace osgEarth { namespace GUI
{
    class GlewInitOperation : public osg::Operation
    {
    public:
        GlewInitOperation()
            : osg::Operation("GlewInitCallback", false)
        {
        }

        void operator()(osg::Object* object) override
        {
            osg::GraphicsContext* context = dynamic_cast<osg::GraphicsContext*>(object);
            if (!context)
            {
                return;
            }

            if (glewInit() != GLEW_OK)
            {
                OSG_FATAL << "glewInit() failed" << std::endl;
            }
        }
    };


    class OsgImGuiHandler : public osgGA::GUIEventHandler
    {
    public:
        OsgImGuiHandler();

        bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) override;

        class RealizeOperation : public osgEarth::GUI::GlewInitOperation
        {
            void operator()(osg::Object* object) override;
        };

        virtual void load(void* section, const std::string& key, const std::string& value) { }

        virtual void save(osgEarth::Config& conf) { }

        virtual void* find(const char* name) { return nullptr; }

    protected:
        // Put your ImGui code inside this function
        virtual void draw(osg::RenderInfo& renderInfo) = 0;
        friend class RealizeOperation;


    private:
        static void init();

        void setCameraCallbacks(osg::Camera* camera);

        void newFrame(osg::RenderInfo& renderInfo);

        void render(osg::RenderInfo& renderInfo);

    private:
        struct ImGuiNewFrameCallback;
        struct ImGuiRenderCallback;

        double time_;
        bool mousePressed_[3];
        bool mouseDoubleClicked_[3];
        float mouseWheel_;
        bool initialized_;
        bool firstFrame_;

        static void* handleStartEntry(
            ImGuiContext* ctx, ImGuiSettingsHandler* handler, const char* name);

        static void handleReadSetting(ImGuiContext* ctx, ImGuiSettingsHandler* handler, void* entry, const char* line);

        static void handleWriteSettings(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* out_buf);

        void installSettingsHandler();
    };
} }

#endif // OSGEARTH_IMGUI_OSGEVENTHANDLER_H
