#pragma once

#include <robin_hood.h>
#include <vector>

#include <GLFW/glfw3.h>

enum class Input {
    Forward, Backward, Left, Right, Up, Down,
    Mouse, Debug, Throw, Quit
};
enum class Mouse {
    Left = GLFW_MOUSE_BUTTON_LEFT,
    Right = GLFW_MOUSE_BUTTON_RIGHT
};

/// Handle inputs with name to key mapping table
class InputMap {
public:
    InputMap(GLFWwindow*, const std::vector<std::pair<int, int>>& keys = {});
    ~InputMap();

    void saveKeys();

    bool isDown(Input input) const;
    bool wasDown(Input input) const;
    bool isPressing(Input input) const;
    bool isReleasing(Input input) const;

    void toggle(bool &val, Input input) const;

    bool isDown(Mouse input) const;
    bool wasDown(Mouse input) const;
    bool isPressing(Mouse input) const;
    bool isReleasing(Mouse input) const;

    void poll() const;

    void exportKeys(std::vector<std::pair<int, int>>&) const;

private:
    GLFWwindow *window;
    robin_hood::unordered_map<Input, int> map;
    const std::vector<Input> toggles = {
        Input::Mouse, Input::Debug, Input::Throw
    };
    robin_hood::unordered_map<Input, bool> previous;

    bool previousLeft;
    bool previousRight;
};
