#ifndef GAMINGCORE_WINDOW_MANAGER_HPP
#define GAMINGCORE_WINDOW_MANAGER_HPP

#include <core/Types.hpp>
#include <core/Vector.hpp>

namespace Core::Window {
    using RunHandler = bool (*)(void* data);
    using TickHandler = void (*)(void* data);
    using RenderHandler = void (*)(void* data, float lag);

    struct Options {
        IntVector2 size{};
        bool fullscreen = false;
        const char* name = "Unknown";
    };

    bool open(const Options& options);
    void close();
    void show();
    void trapCursor();
    void freeCursor();
    bool isCursorTrapped();
    const IntVector2& getSize();
    bool hasSizeChanged();
    bool shouldClose();

    void setRunHandler(RunHandler wr, void* data);
    void setTickHandler(TickHandler t, void* data);
    void setRenderHandler(RenderHandler r, void* data);
    void setNanosPerTick(i64 nanos);
    void run();
    float getTicksPerSecond();
    float getFramesPerSecond();

    void setInputLimit(size_t limit);
    void resetInput();
    void enableInput();
    void disableInput();
    bool isInputEnabled();
    void fillInput(const char* s);
    size_t getInputCursor();
    void setInputCursor(size_t index);
    const char* getInputString();

    using Button = size_t;

    Button addButton(const char* name);
    void bindKeyToButton(Button b, Button key);
    void bindGamepadToButton(Button b, Button gamepadButton);
    void bindMouseToButton(Button b, Button mouseButton);

    Vector2 getLastMousePosition();
    Vector2 getMousePosition();
    Vector2 getLeftGamepadAxis();
    Vector2 getRightGamepadAxis();
    float getLeftGamepadTrigger();
    float getRightGamepadTrigger();

    bool isButtonDown(Button b);
    int getButtonDownTime(Button b);
    bool wasButtonReleased(Button b);
    const char* getButtonName(Button b);
}

#endif