#if defined(WITH_GLFW)

#include "GlfwInputManager.h"

#pragma push_macro("DELETE")
#undef DELETE

namespace nCine
{
	KeySym GlfwKeys::keySymValueToEnum(int keysym)
	{
		// clang-format off
		switch (keysym) {
			case GLFW_KEY_UNKNOWN:			return KeySym::UNKNOWN;
			case GLFW_KEY_BACKSPACE:		return KeySym::BACKSPACE;
			case GLFW_KEY_TAB:				return KeySym::TAB;
			case GLFW_KEY_ENTER:			return KeySym::RETURN;
			case GLFW_KEY_ESCAPE:			return KeySym::ESCAPE;
			case GLFW_KEY_SPACE:			return KeySym::SPACE;
			case GLFW_KEY_APOSTROPHE:		return KeySym::QUOTE;
			case GLFW_KEY_EQUAL:			return KeySym::PLUS;
			case GLFW_KEY_COMMA:			return KeySym::COMMA;
			case GLFW_KEY_MINUS:			return KeySym::MINUS;
			case GLFW_KEY_PERIOD:			return KeySym::PERIOD;
			case GLFW_KEY_SLASH:			return KeySym::SLASH;
			case GLFW_KEY_0:				return KeySym::N0;
			case GLFW_KEY_1:				return KeySym::N1;
			case GLFW_KEY_2:				return KeySym::N2;
			case GLFW_KEY_3:				return KeySym::N3;
			case GLFW_KEY_4:				return KeySym::N4;
			case GLFW_KEY_5:				return KeySym::N5;
			case GLFW_KEY_6:				return KeySym::N6;
			case GLFW_KEY_7:				return KeySym::N7;
			case GLFW_KEY_8:				return KeySym::N8;
			case GLFW_KEY_9:				return KeySym::N9;
			case GLFW_KEY_SEMICOLON:		return KeySym::SEMICOLON;

			case GLFW_KEY_LEFT_BRACKET:		return KeySym::LEFTBRACKET;
			case GLFW_KEY_BACKSLASH:		return KeySym::BACKSLASH;
			case GLFW_KEY_RIGHT_BRACKET:	 return KeySym::RIGHTBRACKET;
			case GLFW_KEY_GRAVE_ACCENT:		return KeySym::BACKQUOTE;
			case GLFW_KEY_WORLD_1:			return KeySym::WORLD1;
			case GLFW_KEY_WORLD_2:			return KeySym::WORLD2;
			case GLFW_KEY_A:				return KeySym::A;
			case GLFW_KEY_B:				return KeySym::B;
			case GLFW_KEY_C:				return KeySym::C;
			case GLFW_KEY_D:				return KeySym::D;
			case GLFW_KEY_E:				return KeySym::E;
			case GLFW_KEY_F:				return KeySym::F;
			case GLFW_KEY_G:				return KeySym::G;
			case GLFW_KEY_H:				return KeySym::H;
			case GLFW_KEY_I:				return KeySym::I;
			case GLFW_KEY_J:				return KeySym::J;
			case GLFW_KEY_K:				return KeySym::K;
			case GLFW_KEY_L:				return KeySym::L;
			case GLFW_KEY_M:				return KeySym::M;
			case GLFW_KEY_N:				return KeySym::N;
			case GLFW_KEY_O:				return KeySym::O;
			case GLFW_KEY_P:				return KeySym::P;
			case GLFW_KEY_Q:				return KeySym::Q;
			case GLFW_KEY_R:				return KeySym::R;
			case GLFW_KEY_S:				return KeySym::S;
			case GLFW_KEY_T:				return KeySym::T;
			case GLFW_KEY_U:				return KeySym::U;
			case GLFW_KEY_V:				return KeySym::V;
			case GLFW_KEY_W:				return KeySym::W;
			case GLFW_KEY_X:				return KeySym::X;
			case GLFW_KEY_Y:				return KeySym::Y;
			case GLFW_KEY_Z:				return KeySym::Z;
			case GLFW_KEY_DELETE:			return KeySym::Delete;

			case GLFW_KEY_KP_0:				return KeySym::KP0;
			case GLFW_KEY_KP_1:				return KeySym::KP1;
			case GLFW_KEY_KP_2:				return KeySym::KP2;
			case GLFW_KEY_KP_3:				return KeySym::KP3;
			case GLFW_KEY_KP_4:				return KeySym::KP4;
			case GLFW_KEY_KP_5:				return KeySym::KP5;
			case GLFW_KEY_KP_6:				return KeySym::KP6;
			case GLFW_KEY_KP_7:				return KeySym::KP7;
			case GLFW_KEY_KP_8:				return KeySym::KP8;
			case GLFW_KEY_KP_9:				return KeySym::KP9;
			case GLFW_KEY_KP_DECIMAL:		return KeySym::KP_PERIOD;
			case GLFW_KEY_KP_DIVIDE:		return KeySym::KP_DIVIDE;
			case GLFW_KEY_KP_MULTIPLY:		return KeySym::KP_MULTIPLY;
			case GLFW_KEY_KP_SUBTRACT:		return KeySym::KP_MINUS;
			case GLFW_KEY_KP_ADD:			return KeySym::KP_PLUS;
			case GLFW_KEY_KP_ENTER:			return KeySym::KP_ENTER;
			case GLFW_KEY_KP_EQUAL:			return KeySym::KP_EQUALS;

			case GLFW_KEY_UP:				return KeySym::UP;
			case GLFW_KEY_DOWN:				return KeySym::DOWN;
			case GLFW_KEY_RIGHT:			return KeySym::RIGHT;
			case GLFW_KEY_LEFT:				return KeySym::LEFT;
			case GLFW_KEY_INSERT:			return KeySym::INSERT;
			case GLFW_KEY_HOME:				return KeySym::HOME;
			case GLFW_KEY_END:				return KeySym::END;
			case GLFW_KEY_PAGE_UP:			return KeySym::PAGEUP;
			case GLFW_KEY_PAGE_DOWN:		return KeySym::PAGEDOWN;

			case GLFW_KEY_F1:				return KeySym::F1;
			case GLFW_KEY_F2:				return KeySym::F2;
			case GLFW_KEY_F3:				return KeySym::F3;
			case GLFW_KEY_F4:				return KeySym::F4;
			case GLFW_KEY_F5:				return KeySym::F5;
			case GLFW_KEY_F6:				return KeySym::F6;
			case GLFW_KEY_F7:				return KeySym::F7;
			case GLFW_KEY_F8:				return KeySym::F8;
			case GLFW_KEY_F9:				return KeySym::F9;
			case GLFW_KEY_F10:				return KeySym::F10;
			case GLFW_KEY_F11:				return KeySym::F11;
			case GLFW_KEY_F12:				return KeySym::F12;
			case GLFW_KEY_F13:				return KeySym::F13;
			case GLFW_KEY_F14:				return KeySym::F14;
			case GLFW_KEY_F15:				return KeySym::F15;

			case GLFW_KEY_NUM_LOCK:			return KeySym::NUM_LOCK;
			case GLFW_KEY_CAPS_LOCK:		return KeySym::CAPS_LOCK;
			case GLFW_KEY_SCROLL_LOCK:		return KeySym::SCROLL_LOCK;
			case GLFW_KEY_RIGHT_SHIFT:		return KeySym::RSHIFT;
			case GLFW_KEY_LEFT_SHIFT:		return KeySym::LSHIFT;
			case GLFW_KEY_RIGHT_CONTROL:	return KeySym::RCTRL;
			case GLFW_KEY_LEFT_CONTROL:		return KeySym::LCTRL;
			case GLFW_KEY_RIGHT_ALT:		return KeySym::RALT;
			case GLFW_KEY_LEFT_ALT:			return KeySym::LALT;
			case GLFW_KEY_RIGHT_SUPER:		return KeySym::RSUPER;
			case GLFW_KEY_LEFT_SUPER:		return KeySym::LSUPER;

			case GLFW_KEY_PRINT_SCREEN:		return KeySym::PRINTSCREEN;
			case GLFW_KEY_PAUSE:			return KeySym::PAUSE;
			case GLFW_KEY_MENU:				return KeySym::MENU;

			default:						return KeySym::UNKNOWN;
		}
		// clang-format on
	}

	int GlfwKeys::keyModMaskToEnumMask(int keymod)
	{
		int result = 0;

		if (keymod != 0) {
			result |= ((keymod & GLFW_MOD_SHIFT) != 0 ? KeyMod::LSHIFT : 0);
			result |= ((keymod & GLFW_MOD_CONTROL) != 0 ? KeyMod::LCTRL : 0);
			result |= ((keymod & GLFW_MOD_ALT) != 0 ? KeyMod::LALT : 0);
			result |= ((keymod & GLFW_MOD_SUPER) != 0 ? KeyMod::LSUPER : 0);
		}

		return result;
	}

	int GlfwKeys::enumToKeySymValue(KeySym keysym)
	{
		// clang-format off
		switch (keysym) {
			case KeySym::UNKNOWN:				return GLFW_KEY_UNKNOWN;
			case KeySym::BACKSPACE:				return GLFW_KEY_BACKSPACE;
			case KeySym::TAB:					return GLFW_KEY_TAB;
			case KeySym::RETURN:				return GLFW_KEY_ENTER;
			case KeySym::ESCAPE:				return GLFW_KEY_ESCAPE;
			case KeySym::SPACE:					return GLFW_KEY_SPACE;
			case KeySym::QUOTE:					return GLFW_KEY_APOSTROPHE;
			case KeySym::PLUS:					return GLFW_KEY_EQUAL;
			case KeySym::COMMA:					return GLFW_KEY_COMMA;
			case KeySym::MINUS:					return GLFW_KEY_MINUS;
			case KeySym::PERIOD:				return GLFW_KEY_PERIOD;
			case KeySym::SLASH:					return GLFW_KEY_SLASH;
			case KeySym::N0:					return GLFW_KEY_0;
			case KeySym::N1:					return GLFW_KEY_1;
			case KeySym::N2:					return GLFW_KEY_2;
			case KeySym::N3:					return GLFW_KEY_3;
			case KeySym::N4:					return GLFW_KEY_4;
			case KeySym::N5:					return GLFW_KEY_5;
			case KeySym::N6:					return GLFW_KEY_6;
			case KeySym::N7:					return GLFW_KEY_7;
			case KeySym::N8:					return GLFW_KEY_8;
			case KeySym::N9:					return GLFW_KEY_9;
			case KeySym::SEMICOLON:				return GLFW_KEY_SEMICOLON;

			case KeySym::LEFTBRACKET:			return GLFW_KEY_LEFT_BRACKET;
			case KeySym::BACKSLASH:				return GLFW_KEY_BACKSLASH;
			case KeySym::RIGHTBRACKET:			return GLFW_KEY_RIGHT_BRACKET;
			case KeySym::BACKQUOTE:				return GLFW_KEY_GRAVE_ACCENT;
			case KeySym::WORLD1:				return GLFW_KEY_WORLD_1;
			case KeySym::WORLD2:				return GLFW_KEY_WORLD_2;
			case KeySym::A:						return GLFW_KEY_A;
			case KeySym::B:						return GLFW_KEY_B;
			case KeySym::C:						return GLFW_KEY_C;
			case KeySym::D:						return GLFW_KEY_D;
			case KeySym::E:						return GLFW_KEY_E;
			case KeySym::F:						return GLFW_KEY_F;
			case KeySym::G:						return GLFW_KEY_G;
			case KeySym::H:						return GLFW_KEY_H;
			case KeySym::I:						return GLFW_KEY_I;
			case KeySym::J:						return GLFW_KEY_J;
			case KeySym::K:						return GLFW_KEY_K;
			case KeySym::L:						return GLFW_KEY_L;
			case KeySym::M:						return GLFW_KEY_M;
			case KeySym::N:						return GLFW_KEY_N;
			case KeySym::O:						return GLFW_KEY_O;
			case KeySym::P:						return GLFW_KEY_P;
			case KeySym::Q:						return GLFW_KEY_Q;
			case KeySym::R:						return GLFW_KEY_R;
			case KeySym::S:						return GLFW_KEY_S;
			case KeySym::T:						return GLFW_KEY_T;
			case KeySym::U:						return GLFW_KEY_U;
			case KeySym::V:						return GLFW_KEY_V;
			case KeySym::W:						return GLFW_KEY_W;
			case KeySym::X:						return GLFW_KEY_X;
			case KeySym::Y:						return GLFW_KEY_Y;
			case KeySym::Z:						return GLFW_KEY_Z;
			case KeySym::Delete:				return GLFW_KEY_DELETE;

			case KeySym::KP0:					return GLFW_KEY_KP_0;
			case KeySym::KP1:					return GLFW_KEY_KP_1;
			case KeySym::KP2:					return GLFW_KEY_KP_2;
			case KeySym::KP3:					return GLFW_KEY_KP_3;
			case KeySym::KP4:					return GLFW_KEY_KP_4;
			case KeySym::KP5:					return GLFW_KEY_KP_5;
			case KeySym::KP6:					return GLFW_KEY_KP_6;
			case KeySym::KP7:					return GLFW_KEY_KP_7;
			case KeySym::KP8:					return GLFW_KEY_KP_8;
			case KeySym::KP9:					return GLFW_KEY_KP_9;
			case KeySym::KP_PERIOD:				return GLFW_KEY_KP_DECIMAL;
			case KeySym::KP_DIVIDE:				return GLFW_KEY_KP_DIVIDE;
			case KeySym::KP_MULTIPLY:			return GLFW_KEY_KP_MULTIPLY;
			case KeySym::KP_MINUS:				return GLFW_KEY_KP_SUBTRACT;
			case KeySym::KP_PLUS:				return GLFW_KEY_KP_ADD;
			case KeySym::KP_ENTER:				return GLFW_KEY_KP_ENTER;
			case KeySym::KP_EQUALS:				return GLFW_KEY_KP_EQUAL;

			case KeySym::UP:					return GLFW_KEY_UP;
			case KeySym::DOWN:					return GLFW_KEY_DOWN;
			case KeySym::RIGHT:					return GLFW_KEY_RIGHT;
			case KeySym::LEFT:					return GLFW_KEY_LEFT;
			case KeySym::INSERT:				return GLFW_KEY_INSERT;
			case KeySym::HOME:					return GLFW_KEY_HOME;
			case KeySym::END:					return GLFW_KEY_END;
			case KeySym::PAGEUP:				return GLFW_KEY_PAGE_UP;
			case KeySym::PAGEDOWN:				return GLFW_KEY_PAGE_DOWN;

			case KeySym::F1:					return GLFW_KEY_F1;
			case KeySym::F2:					return GLFW_KEY_F2;
			case KeySym::F3:					return GLFW_KEY_F3;
			case KeySym::F4:					return GLFW_KEY_F4;
			case KeySym::F5:					return GLFW_KEY_F5;
			case KeySym::F6:					return GLFW_KEY_F6;
			case KeySym::F7:					return GLFW_KEY_F7;
			case KeySym::F8:					return GLFW_KEY_F8;
			case KeySym::F9:					return GLFW_KEY_F9;
			case KeySym::F10:					return GLFW_KEY_F10;
			case KeySym::F11:					return GLFW_KEY_F11;
			case KeySym::F12:					return GLFW_KEY_F12;
			case KeySym::F13:					return GLFW_KEY_F13;
			case KeySym::F14:					return GLFW_KEY_F14;
			case KeySym::F15:					return GLFW_KEY_F15;

			case KeySym::NUM_LOCK:				return GLFW_KEY_NUM_LOCK;
			case KeySym::CAPS_LOCK:				return GLFW_KEY_CAPS_LOCK;
			case KeySym::SCROLL_LOCK:			return GLFW_KEY_SCROLL_LOCK;
			case KeySym::RSHIFT:				return GLFW_KEY_RIGHT_SHIFT;
			case KeySym::LSHIFT:				return GLFW_KEY_LEFT_SHIFT;
			case KeySym::RCTRL:					return GLFW_KEY_RIGHT_CONTROL;
			case KeySym::LCTRL:					return GLFW_KEY_LEFT_CONTROL;
			case KeySym::RALT:					return GLFW_KEY_RIGHT_ALT;
			case KeySym::LALT:					return GLFW_KEY_LEFT_ALT;
			case KeySym::RSUPER:				return GLFW_KEY_RIGHT_SUPER;
			case KeySym::LSUPER:				return GLFW_KEY_LEFT_SUPER;

			case KeySym::PRINTSCREEN:			return GLFW_KEY_PRINT_SCREEN;
			case KeySym::PAUSE:					return GLFW_KEY_PAUSE;
			case KeySym::MENU:					return GLFW_KEY_MENU;

			default:							return GLFW_KEY_UNKNOWN;
		}
		// clang-format on
	}
}

#pragma pop_macro("DELETE")

#endif