#include <bind-imgui/glfw-modules.h>

#include <GLFW/glfw3.h>

#define CONST(name) m.attr(#name) = GLFW_##name

namespace py = pybind11;

namespace bindGLFW {

void init_constants(py::module& m)
{
    // Version consts
    CONST(VERSION_MAJOR);
    CONST(VERSION_MINOR);
    CONST(VERSION_REVISION);

    // IO stuff
    CONST(RELEASE);
    CONST(PRESS);
    CONST(REPEAT);

    // Joystick Hat
    CONST(HAT_CENTERED);
    CONST(HAT_UP);
    CONST(HAT_RIGHT);
    CONST(HAT_DOWN);
    CONST(HAT_LEFT);
    CONST(HAT_RIGHT_UP);
    CONST(HAT_RIGHT_DOWN);
    CONST(HAT_LEFT_UP);
    CONST(HAT_LEFT_DOWN);

    // Keyboard
    CONST(KEY_UNKNOWN);

    CONST(KEY_SPACE);
    CONST(KEY_APOSTROPHE);
    CONST(KEY_COMMA);
    CONST(KEY_MINUS);
    CONST(KEY_PERIOD);
    CONST(KEY_SLASH);
    CONST(KEY_0);
    CONST(KEY_1);
    CONST(KEY_2);
    CONST(KEY_3);
    CONST(KEY_4);
    CONST(KEY_5);
    CONST(KEY_6);
    CONST(KEY_7);
    CONST(KEY_8);
    CONST(KEY_9);
    CONST(KEY_SEMICOLON);
    CONST(KEY_EQUAL);
    CONST(KEY_A);
    CONST(KEY_B);
    CONST(KEY_C);
    CONST(KEY_D);
    CONST(KEY_E);
    CONST(KEY_F);
    CONST(KEY_G);
    CONST(KEY_H);
    CONST(KEY_I);
    CONST(KEY_J);
    CONST(KEY_K);
    CONST(KEY_L);
    CONST(KEY_M);
    CONST(KEY_N);
    CONST(KEY_O);
    CONST(KEY_P);
    CONST(KEY_Q);
    CONST(KEY_R);
    CONST(KEY_S);
    CONST(KEY_T);
    CONST(KEY_U);
    CONST(KEY_V);
    CONST(KEY_W);
    CONST(KEY_X);
    CONST(KEY_Y);
    CONST(KEY_Z);
    CONST(KEY_LEFT_BRACKET);
    CONST(KEY_BACKSLASH);
    CONST(KEY_RIGHT_BRACKET);
    CONST(KEY_GRAVE_ACCENT);
    CONST(KEY_WORLD_1);
    CONST(KEY_WORLD_2);

    CONST(KEY_ESCAPE);
    CONST(KEY_ENTER);
    CONST(KEY_TAB);
    CONST(KEY_BACKSPACE);
    CONST(KEY_INSERT);
    CONST(KEY_DELETE);
    CONST(KEY_RIGHT);
    CONST(KEY_LEFT);
    CONST(KEY_DOWN);
    CONST(KEY_UP);
    CONST(KEY_PAGE_UP);
    CONST(KEY_PAGE_DOWN);
    CONST(KEY_HOME);
    CONST(KEY_END);
    CONST(KEY_CAPS_LOCK);
    CONST(KEY_SCROLL_LOCK);
    CONST(KEY_NUM_LOCK);
    CONST(KEY_PRINT_SCREEN);
    CONST(KEY_PAUSE);
    CONST(KEY_F1);
    CONST(KEY_F2);
    CONST(KEY_F3);
    CONST(KEY_F4);
    CONST(KEY_F5);
    CONST(KEY_F6);
    CONST(KEY_F7);
    CONST(KEY_F8);
    CONST(KEY_F9);
    CONST(KEY_F10);
    CONST(KEY_F11);
    CONST(KEY_F12);
    CONST(KEY_F13);
    CONST(KEY_F14);
    CONST(KEY_F15);
    CONST(KEY_F16);
    CONST(KEY_F17);
    CONST(KEY_F18);
    CONST(KEY_F19);
    CONST(KEY_F20);
    CONST(KEY_F21);
    CONST(KEY_F22);
    CONST(KEY_F23);
    CONST(KEY_F24);
    CONST(KEY_F25);
    CONST(KEY_KP_0);
    CONST(KEY_KP_1);
    CONST(KEY_KP_2);
    CONST(KEY_KP_3);
    CONST(KEY_KP_4);
    CONST(KEY_KP_5);
    CONST(KEY_KP_6);
    CONST(KEY_KP_7);
    CONST(KEY_KP_8);
    CONST(KEY_KP_9);
    CONST(KEY_KP_DECIMAL);
    CONST(KEY_KP_DIVIDE);
    CONST(KEY_KP_MULTIPLY);
    CONST(KEY_KP_SUBTRACT);
    CONST(KEY_KP_ADD);
    CONST(KEY_KP_ENTER);
    CONST(KEY_KP_EQUAL);
    CONST(KEY_LEFT_SHIFT);
    CONST(KEY_LEFT_CONTROL);
    CONST(KEY_LEFT_ALT);
    CONST(KEY_LEFT_SUPER);
    CONST(KEY_RIGHT_SHIFT);
    CONST(KEY_RIGHT_CONTROL);
    CONST(KEY_RIGHT_ALT);
    CONST(KEY_RIGHT_SUPER);
    CONST(KEY_MENU);

    // Modifier keys
    CONST(MOD_SHIFT);
    CONST(MOD_CONTROL);
    CONST(MOD_ALT);
    CONST(MOD_SUPER);
    CONST(MOD_CAPS_LOCK);
    CONST(MOD_NUM_LOCK);

    // Mouse buttons
    CONST(MOUSE_BUTTON_1);
    CONST(MOUSE_BUTTON_2);
    CONST(MOUSE_BUTTON_3);
    CONST(MOUSE_BUTTON_4);
    CONST(MOUSE_BUTTON_5);
    CONST(MOUSE_BUTTON_6);
    CONST(MOUSE_BUTTON_7);
    CONST(MOUSE_BUTTON_8);
    CONST(MOUSE_BUTTON_LEFT);
    CONST(MOUSE_BUTTON_RIGHT);
    CONST(MOUSE_BUTTON_MIDDLE);

    // Joysticks
    CONST(JOYSTICK_1);
    CONST(JOYSTICK_2);
    CONST(JOYSTICK_3);
    CONST(JOYSTICK_4);
    CONST(JOYSTICK_5);
    CONST(JOYSTICK_6);
    CONST(JOYSTICK_7);
    CONST(JOYSTICK_8);
    CONST(JOYSTICK_9);
    CONST(JOYSTICK_10);
    CONST(JOYSTICK_11);
    CONST(JOYSTICK_12);
    CONST(JOYSTICK_13);
    CONST(JOYSTICK_14);
    CONST(JOYSTICK_15);
    CONST(JOYSTICK_16);

    // Gamepad buttons
    CONST(GAMEPAD_BUTTON_A);
    CONST(GAMEPAD_BUTTON_B);
    CONST(GAMEPAD_BUTTON_X);
    CONST(GAMEPAD_BUTTON_Y);
    CONST(GAMEPAD_BUTTON_LEFT_BUMPER);
    CONST(GAMEPAD_BUTTON_RIGHT_BUMPER);
    CONST(GAMEPAD_BUTTON_BACK);
    CONST(GAMEPAD_BUTTON_START);
    CONST(GAMEPAD_BUTTON_GUIDE);
    CONST(GAMEPAD_BUTTON_LEFT_THUMB);
    CONST(GAMEPAD_BUTTON_RIGHT_THUMB);
    CONST(GAMEPAD_BUTTON_DPAD_UP);
    CONST(GAMEPAD_BUTTON_DPAD_RIGHT);
    CONST(GAMEPAD_BUTTON_DPAD_DOWN);
    CONST(GAMEPAD_BUTTON_DPAD_LEFT);
    CONST(GAMEPAD_BUTTON_CROSS);
    CONST(GAMEPAD_BUTTON_CIRCLE);
    CONST(GAMEPAD_BUTTON_SQUARE);
    CONST(GAMEPAD_BUTTON_TRIANGLE);

    // Gamepad Axes
    CONST(GAMEPAD_AXIS_LEFT_X);
    CONST(GAMEPAD_AXIS_LEFT_Y);
    CONST(GAMEPAD_AXIS_RIGHT_X);
    CONST(GAMEPAD_AXIS_RIGHT_Y);
    CONST(GAMEPAD_AXIS_LEFT_TRIGGER);
    CONST(GAMEPAD_AXIS_RIGHT_TRIGGER);

    // Error codes
    CONST(NO_ERROR);
    CONST(NOT_INITIALIZED);
    CONST(NO_CURRENT_CONTEXT);
    CONST(INVALID_ENUM);
    CONST(INVALID_VALUE);
    CONST(OUT_OF_MEMORY);
    CONST(API_UNAVAILABLE);
    CONST(VERSION_UNAVAILABLE);
    CONST(PLATFORM_ERROR);
    CONST(FORMAT_UNAVAILABLE);
    CONST(NO_WINDOW_CONTEXT);

    // Window flags
    CONST(FOCUSED);
    CONST(ICONIFIED);
    CONST(RESIZABLE);
    CONST(VISIBLE);
    CONST(DECORATED);
    CONST(AUTO_ICONIFY);
    CONST(FLOATING);
    CONST(MAXIMIZED);
    CONST(CENTER_CURSOR);
    CONST(TRANSPARENT_FRAMEBUFFER);
    CONST(HOVERED);
    CONST(FOCUS_ON_SHOW);

    // Framebuffer
    CONST(RED_BITS);
    CONST(GREEN_BITS);
    CONST(BLUE_BITS);
    CONST(ALPHA_BITS);
    CONST(DEPTH_BITS);
    CONST(STENCIL_BITS);
    CONST(ACCUM_RED_BITS);
    CONST(ACCUM_GREEN_BITS);
    CONST(ACCUM_BLUE_BITS);
    CONST(ACCUM_ALPHA_BITS);
    CONST(AUX_BUFFERS);
    CONST(STEREO);
    CONST(SAMPLES);
    CONST(SRGB_CAPABLE);
    CONST(REFRESH_RATE);
    CONST(DOUBLEBUFFER);

    // Context client API
    CONST(CLIENT_API);
    CONST(CONTEXT_VERSION_MAJOR);
    CONST(CONTEXT_VERSION_MINOR);
    CONST(CONTEXT_REVISION);
    CONST(CONTEXT_ROBUSTNESS);
    CONST(OPENGL_FORWARD_COMPAT);
    CONST(OPENGL_DEBUG_CONTEXT);
    CONST(OPENGL_PROFILE);
    CONST(CONTEXT_RELEASE_BEHAVIOR);
    CONST(CONTEXT_NO_ERROR);
    CONST(CONTEXT_CREATION_API);
    CONST(SCALE_TO_MONITOR);
    CONST(COCOA_RETINA_FRAMEBUFFER);
    CONST(COCOA_FRAME_NAME);
    CONST(COCOA_GRAPHICS_SWITCHING);
    CONST(X11_CLASS_NAME);
    CONST(X11_INSTANCE_NAME);

    // Other
    CONST(NO_API);
    CONST(OPENGL_API);
    CONST(OPENGL_ES_API);
    CONST(NO_ROBUSTNESS);
    CONST(NO_RESET_NOTIFICATION);
    CONST(LOSE_CONTEXT_ON_RESET);
    CONST(OPENGL_ANY_PROFILE);
    CONST(OPENGL_CORE_PROFILE);
    CONST(OPENGL_COMPAT_PROFILE);
    CONST(CURSOR);
    CONST(STICKY_KEYS);
    CONST(STICKY_MOUSE_BUTTONS);
    CONST(LOCK_KEY_MODS);
    CONST(RAW_MOUSE_MOTION);
    CONST(CURSOR_NORMAL);
    CONST(CURSOR_HIDDEN);
    CONST(CURSOR_DISABLED);
    CONST(ANY_RELEASE_BEHAVIOR);
    CONST(RELEASE_BEHAVIOR_FLUSH);
    CONST(RELEASE_BEHAVIOR_NONE);
    CONST(NATIVE_CONTEXT_API);
    CONST(EGL_CONTEXT_API);
    CONST(OSMESA_CONTEXT_API);
    CONST(CONNECTED);
    CONST(DISCONNECTED);
    CONST(JOYSTICK_HAT_BUTTONS);
    CONST(COCOA_CHDIR_RESOURCES);
    CONST(COCOA_MENUBAR);
    CONST(DONT_CARE);

    // cursors
    CONST(ARROW_CURSOR);
    CONST(IBEAM_CURSOR);
    CONST(CROSSHAIR_CURSOR);
    CONST(HAND_CURSOR);
    CONST(HRESIZE_CURSOR);
    CONST(VRESIZE_CURSOR);
}

} //namespace bindGLFW