#ifdef NANOGUI_PYTHON

#include "python.h"

struct Key {
    const char *name;
    int value;
};

#define K(name) { #name, GLFW_##name }

static const Key keys[] = {
    K(KEY_UNKNOWN),
    K(KEY_SPACE),
    K(KEY_APOSTROPHE),
    K(KEY_COMMA),
    K(KEY_MINUS),
    K(KEY_PERIOD),
    K(KEY_SLASH),
    K(KEY_0),
    K(KEY_1),
    K(KEY_2),
    K(KEY_3),
    K(KEY_4),
    K(KEY_5),
    K(KEY_6),
    K(KEY_7),
    K(KEY_8),
    K(KEY_9),
    K(KEY_SEMICOLON),
    K(KEY_EQUAL),
    K(KEY_A),
    K(KEY_B),
    K(KEY_C),
    K(KEY_D),
    K(KEY_E),
    K(KEY_F),
    K(KEY_G),
    K(KEY_H),
    K(KEY_I),
    K(KEY_J),
    K(KEY_K),
    K(KEY_L),
    K(KEY_M),
    K(KEY_N),
    K(KEY_O),
    K(KEY_P),
    K(KEY_Q),
    K(KEY_R),
    K(KEY_S),
    K(KEY_T),
    K(KEY_U),
    K(KEY_V),
    K(KEY_W),
    K(KEY_X),
    K(KEY_Y),
    K(KEY_Z),
    K(KEY_LEFT_BRACKET),
    K(KEY_BACKSLASH),
    K(KEY_RIGHT_BRACKET),
    K(KEY_GRAVE_ACCENT),
    K(KEY_WORLD_1),
    K(KEY_WORLD_2),
    K(KEY_ESCAPE),
    K(KEY_ENTER),
    K(KEY_TAB),
    K(KEY_BACKSPACE),
    K(KEY_INSERT),
    K(KEY_DELETE),
    K(KEY_RIGHT),
    K(KEY_LEFT),
    K(KEY_DOWN),
    K(KEY_UP),
    K(KEY_PAGE_UP),
    K(KEY_PAGE_DOWN),
    K(KEY_HOME),
    K(KEY_END),
    K(KEY_CAPS_LOCK),
    K(KEY_SCROLL_LOCK),
    K(KEY_NUM_LOCK),
    K(KEY_PRINT_SCREEN),
    K(KEY_PAUSE),
    K(KEY_F1),
    K(KEY_F2),
    K(KEY_F3),
    K(KEY_F4),
    K(KEY_F5),
    K(KEY_F6),
    K(KEY_F7),
    K(KEY_F8),
    K(KEY_F9),
    K(KEY_F10),
    K(KEY_F11),
    K(KEY_F12),
    K(KEY_F13),
    K(KEY_F14),
    K(KEY_F15),
    K(KEY_F16),
    K(KEY_F17),
    K(KEY_F18),
    K(KEY_F19),
    K(KEY_F20),
    K(KEY_F21),
    K(KEY_F22),
    K(KEY_F23),
    K(KEY_F24),
    K(KEY_F25),
    K(KEY_KP_0),
    K(KEY_KP_1),
    K(KEY_KP_2),
    K(KEY_KP_3),
    K(KEY_KP_4),
    K(KEY_KP_5),
    K(KEY_KP_6),
    K(KEY_KP_7),
    K(KEY_KP_8),
    K(KEY_KP_9),
    K(KEY_KP_DECIMAL),
    K(KEY_KP_DIVIDE),
    K(KEY_KP_MULTIPLY),
    K(KEY_KP_SUBTRACT),
    K(KEY_KP_ADD),
    K(KEY_KP_ENTER),
    K(KEY_KP_EQUAL),
    K(KEY_LEFT_SHIFT),
    K(KEY_LEFT_CONTROL),
    K(KEY_LEFT_ALT),
    K(KEY_LEFT_SUPER),
    K(KEY_RIGHT_SHIFT),
    K(KEY_RIGHT_CONTROL),
    K(KEY_RIGHT_ALT),
    K(KEY_RIGHT_SUPER),
    K(KEY_MENU),
    K(KEY_LAST),
    K(MOD_SHIFT),
    K(MOD_CONTROL),
    K(MOD_ALT),
    K(MOD_SUPER),
    K(MOUSE_BUTTON_1),
    K(MOUSE_BUTTON_2),
    K(MOUSE_BUTTON_3),
    K(MOUSE_BUTTON_4),
    K(MOUSE_BUTTON_5),
    K(MOUSE_BUTTON_6),
    K(MOUSE_BUTTON_7),
    K(MOUSE_BUTTON_8),
    K(MOUSE_BUTTON_LAST),
    K(MOUSE_BUTTON_LEFT),
    K(MOUSE_BUTTON_RIGHT),
    K(MOUSE_BUTTON_MIDDLE),
    K(RELEASE),
    K(PRESS),
    K(REPEAT)
};

#undef K

void register_glfw(nb::module_ &m) {
    /* GLFW constants + functions */
    {
        nb::module_ m2 = m.def_submodule("glfw");
        for (Key k: keys)
            m2.attr(k.name) = k.value;
        m2.def("getTime", &glfwGetTime);
    }
}

#endif
