package sdl2


SCANCODE_MASK :: 1<<30
SCANCODE_TO_KEYCODE :: #force_inline proc "c" (X: Scancode) -> Keycode {
	return Keycode(i32(X) | SCANCODE_MASK)
}

Keycode :: enum i32 {
	UNKNOWN = 0,

	RETURN = '\r',
	ESCAPE = '\x1B',
	BACKSPACE = '\b',
	TAB = '\t',
	SPACE = ' ',
	EXCLAIM = '!',
	QUOTEDBL = '"',
	HASH = '#',
	PERCENT = '%',
	DOLLAR = '$',
	AMPERSAND = '&',
	QUOTE = '\'',
	LEFTPAREN = '(',
	RIGHTPAREN = ')',
	ASTERISK = '*',
	PLUS = '+',
	COMMA = ',',
	MINUS = '-',
	PERIOD = '.',
	SLASH = '/',
	NUM0 = '0',
	NUM1 = '1',
	NUM2 = '2',
	NUM3 = '3',
	NUM4 = '4',
	NUM5 = '5',
	NUM6 = '6',
	NUM7 = '7',
	NUM8 = '8',
	NUM9 = '9',
	COLON = ':',
	SEMICOLON = ';',
	LESS = '<',
	EQUALS = '=',
	GREATER = '>',
	QUESTION = '?',
	AT = '@',

	/*
	   Skip uppercase letters
	 */

	LEFTBRACKET = '[',
	BACKSLASH = '\\',
	RIGHTBRACKET = ']',
	CARET = '^',
	UNDERSCORE = '_',
	BACKQUOTE = '`',
	a = 'a',
	b = 'b',
	c = 'c',
	d = 'd',
	e = 'e',
	f = 'f',
	g = 'g',
	h = 'h',
	i = 'i',
	j = 'j',
	k = 'k',
	l = 'l',
	m = 'm',
	n = 'n',
	o = 'o',
	p = 'p',
	q = 'q',
	r = 'r',
	s = 's',
	t = 't',
	u = 'u',
	v = 'v',
	w = 'w',
	x = 'x',
	y = 'y',
	z = 'z',

	A = a,
	B = b,
	C = c,
	D = d,
	E = e,
	F = f,
	G = g,
	H = h,
	I = i,
	J = j,
	K = k,
	L = l,
	M = m,
	N = n,
	O = o,
	P = p,
	Q = q,
	R = r,
	S = s,
	T = t,
	U = u,
	V = v,
	W = w,
	X = x,
	Y = y,
	Z = z,

	CAPSLOCK = auto_cast (Scancode.CAPSLOCK|SCANCODE_MASK),

	F1 = auto_cast (Scancode.F1|SCANCODE_MASK),
	F2 = auto_cast (Scancode.F2|SCANCODE_MASK),
	F3 = auto_cast (Scancode.F3|SCANCODE_MASK),
	F4 = auto_cast (Scancode.F4|SCANCODE_MASK),
	F5 = auto_cast (Scancode.F5|SCANCODE_MASK),
	F6 = auto_cast (Scancode.F6|SCANCODE_MASK),
	F7 = auto_cast (Scancode.F7|SCANCODE_MASK),
	F8 = auto_cast (Scancode.F8|SCANCODE_MASK),
	F9 = auto_cast (Scancode.F9|SCANCODE_MASK),
	F10 = auto_cast (Scancode.F10|SCANCODE_MASK),
	F11 = auto_cast (Scancode.F11|SCANCODE_MASK),
	F12 = auto_cast (Scancode.F12|SCANCODE_MASK),

	PRINTSCREEN = auto_cast (Scancode.PRINTSCREEN|SCANCODE_MASK),
	SCROLLLOCK = auto_cast (Scancode.SCROLLLOCK|SCANCODE_MASK),
	PAUSE = auto_cast (Scancode.PAUSE|SCANCODE_MASK),
	INSERT = auto_cast (Scancode.INSERT|SCANCODE_MASK),
	HOME = auto_cast (Scancode.HOME|SCANCODE_MASK),
	PAGEUP = auto_cast (Scancode.PAGEUP|SCANCODE_MASK),
	DELETE = '\x7F',
	END = auto_cast (Scancode.END|SCANCODE_MASK),
	PAGEDOWN = auto_cast (Scancode.PAGEDOWN|SCANCODE_MASK),
	RIGHT = auto_cast (Scancode.RIGHT|SCANCODE_MASK),
	LEFT = auto_cast (Scancode.LEFT|SCANCODE_MASK),
	DOWN = auto_cast (Scancode.DOWN|SCANCODE_MASK),
	UP = auto_cast (Scancode.UP|SCANCODE_MASK),

	NUMLOCKCLEAR = auto_cast (Scancode.NUMLOCKCLEAR|SCANCODE_MASK),
	KP_DIVIDE = auto_cast (Scancode.KP_DIVIDE|SCANCODE_MASK),
	KP_MULTIPLY = auto_cast (Scancode.KP_MULTIPLY|SCANCODE_MASK),
	KP_MINUS = auto_cast (Scancode.KP_MINUS|SCANCODE_MASK),
	KP_PLUS = auto_cast (Scancode.KP_PLUS|SCANCODE_MASK),
	KP_ENTER = auto_cast (Scancode.KP_ENTER|SCANCODE_MASK),
	KP_1 = auto_cast (Scancode.KP_1|SCANCODE_MASK),
	KP_2 = auto_cast (Scancode.KP_2|SCANCODE_MASK),
	KP_3 = auto_cast (Scancode.KP_3|SCANCODE_MASK),
	KP_4 = auto_cast (Scancode.KP_4|SCANCODE_MASK),
	KP_5 = auto_cast (Scancode.KP_5|SCANCODE_MASK),
	KP_6 = auto_cast (Scancode.KP_6|SCANCODE_MASK),
	KP_7 = auto_cast (Scancode.KP_7|SCANCODE_MASK),
	KP_8 = auto_cast (Scancode.KP_8|SCANCODE_MASK),
	KP_9 = auto_cast (Scancode.KP_9|SCANCODE_MASK),
	KP_0 = auto_cast (Scancode.KP_0|SCANCODE_MASK),
	KP_PERIOD = auto_cast (Scancode.KP_PERIOD|SCANCODE_MASK),

	APPLICATION = auto_cast (Scancode.APPLICATION|SCANCODE_MASK),
	POWER = auto_cast (Scancode.POWER|SCANCODE_MASK),
	KP_EQUALS = auto_cast (Scancode.KP_EQUALS|SCANCODE_MASK),
	F13 = auto_cast (Scancode.F13|SCANCODE_MASK),
	F14 = auto_cast (Scancode.F14|SCANCODE_MASK),
	F15 = auto_cast (Scancode.F15|SCANCODE_MASK),
	F16 = auto_cast (Scancode.F16|SCANCODE_MASK),
	F17 = auto_cast (Scancode.F17|SCANCODE_MASK),
	F18 = auto_cast (Scancode.F18|SCANCODE_MASK),
	F19 = auto_cast (Scancode.F19|SCANCODE_MASK),
	F20 = auto_cast (Scancode.F20|SCANCODE_MASK),
	F21 = auto_cast (Scancode.F21|SCANCODE_MASK),
	F22 = auto_cast (Scancode.F22|SCANCODE_MASK),
	F23 = auto_cast (Scancode.F23|SCANCODE_MASK),
	F24 = auto_cast (Scancode.F24|SCANCODE_MASK),
	EXECUTE = auto_cast (Scancode.EXECUTE|SCANCODE_MASK),
	HELP = auto_cast (Scancode.HELP|SCANCODE_MASK),
	MENU = auto_cast (Scancode.MENU|SCANCODE_MASK),
	SELECT = auto_cast (Scancode.SELECT|SCANCODE_MASK),
	STOP = auto_cast (Scancode.STOP|SCANCODE_MASK),
	AGAIN = auto_cast (Scancode.AGAIN|SCANCODE_MASK),
	UNDO = auto_cast (Scancode.UNDO|SCANCODE_MASK),
	CUT = auto_cast (Scancode.CUT|SCANCODE_MASK),
	COPY = auto_cast (Scancode.COPY|SCANCODE_MASK),
	PASTE = auto_cast (Scancode.PASTE|SCANCODE_MASK),
	FIND = auto_cast (Scancode.FIND|SCANCODE_MASK),
	MUTE = auto_cast (Scancode.MUTE|SCANCODE_MASK),
	VOLUMEUP = auto_cast (Scancode.VOLUMEUP|SCANCODE_MASK),
	VOLUMEDOWN = auto_cast (Scancode.VOLUMEDOWN|SCANCODE_MASK),
	KP_COMMA = auto_cast (Scancode.KP_COMMA|SCANCODE_MASK),
	KP_EQUALSAS400 = auto_cast (Scancode.KP_EQUALSAS400|SCANCODE_MASK),

	ALTERASE = auto_cast (Scancode.ALTERASE|SCANCODE_MASK),
	SYSREQ = auto_cast (Scancode.SYSREQ|SCANCODE_MASK),
	CANCEL = auto_cast (Scancode.CANCEL|SCANCODE_MASK),
	CLEAR = auto_cast (Scancode.CLEAR|SCANCODE_MASK),
	PRIOR = auto_cast (Scancode.PRIOR|SCANCODE_MASK),
	RETURN2 = auto_cast (Scancode.RETURN2|SCANCODE_MASK),
	SEPARATOR = auto_cast (Scancode.SEPARATOR|SCANCODE_MASK),
	OUT = auto_cast (Scancode.OUT|SCANCODE_MASK),
	OPER = auto_cast (Scancode.OPER|SCANCODE_MASK),
	CLEARAGAIN = auto_cast (Scancode.CLEARAGAIN|SCANCODE_MASK),
	CRSEL = auto_cast (Scancode.CRSEL|SCANCODE_MASK),
	EXSEL = auto_cast (Scancode.EXSEL|SCANCODE_MASK),

	KP_00 = auto_cast (Scancode.KP_00|SCANCODE_MASK),
	KP_000 = auto_cast (Scancode.KP_000|SCANCODE_MASK),
	THOUSANDSSEPARATOR = auto_cast (Scancode.THOUSANDSSEPARATOR|SCANCODE_MASK),
	DECIMALSEPARATOR = auto_cast (Scancode.DECIMALSEPARATOR|SCANCODE_MASK),
	CURRENCYUNIT = auto_cast (Scancode.CURRENCYUNIT|SCANCODE_MASK),
	CURRENCYSUBUNIT = auto_cast (Scancode.CURRENCYSUBUNIT|SCANCODE_MASK),
	KP_LEFTPAREN = auto_cast (Scancode.KP_LEFTPAREN|SCANCODE_MASK),
	KP_RIGHTPAREN = auto_cast (Scancode.KP_RIGHTPAREN|SCANCODE_MASK),
	KP_LEFTBRACE = auto_cast (Scancode.KP_LEFTBRACE|SCANCODE_MASK),
	KP_RIGHTBRACE = auto_cast (Scancode.KP_RIGHTBRACE|SCANCODE_MASK),
	KP_TAB = auto_cast (Scancode.KP_TAB|SCANCODE_MASK),
	KP_BACKSPACE = auto_cast (Scancode.KP_BACKSPACE|SCANCODE_MASK),
	KP_A = auto_cast (Scancode.KP_A|SCANCODE_MASK),
	KP_B = auto_cast (Scancode.KP_B|SCANCODE_MASK),
	KP_C = auto_cast (Scancode.KP_C|SCANCODE_MASK),
	KP_D = auto_cast (Scancode.KP_D|SCANCODE_MASK),
	KP_E = auto_cast (Scancode.KP_E|SCANCODE_MASK),
	KP_F = auto_cast (Scancode.KP_F|SCANCODE_MASK),
	KP_XOR = auto_cast (Scancode.KP_XOR|SCANCODE_MASK),
	KP_POWER = auto_cast (Scancode.KP_POWER|SCANCODE_MASK),
	KP_PERCENT = auto_cast (Scancode.KP_PERCENT|SCANCODE_MASK),
	KP_LESS = auto_cast (Scancode.KP_LESS|SCANCODE_MASK),
	KP_GREATER = auto_cast (Scancode.KP_GREATER|SCANCODE_MASK),
	KP_AMPERSAND = auto_cast (Scancode.KP_AMPERSAND|SCANCODE_MASK),
	KP_DBLAMPERSAND = auto_cast (Scancode.KP_DBLAMPERSAND|SCANCODE_MASK),
	KP_VERTICALBAR = auto_cast (Scancode.KP_VERTICALBAR|SCANCODE_MASK),
	KP_DBLVERTICALBAR = auto_cast (Scancode.KP_DBLVERTICALBAR|SCANCODE_MASK),
	KP_COLON = auto_cast (Scancode.KP_COLON|SCANCODE_MASK),
	KP_HASH = auto_cast (Scancode.KP_HASH|SCANCODE_MASK),
	KP_SPACE = auto_cast (Scancode.KP_SPACE|SCANCODE_MASK),
	KP_AT = auto_cast (Scancode.KP_AT|SCANCODE_MASK),
	KP_EXCLAM = auto_cast (Scancode.KP_EXCLAM|SCANCODE_MASK),
	KP_MEMSTORE = auto_cast (Scancode.KP_MEMSTORE|SCANCODE_MASK),
	KP_MEMRECALL = auto_cast (Scancode.KP_MEMRECALL|SCANCODE_MASK),
	KP_MEMCLEAR = auto_cast (Scancode.KP_MEMCLEAR|SCANCODE_MASK),
	KP_MEMADD = auto_cast (Scancode.KP_MEMADD|SCANCODE_MASK),
	KP_MEMSUBTRACT = auto_cast (Scancode.KP_MEMSUBTRACT|SCANCODE_MASK),
	KP_MEMMULTIPLY = auto_cast (Scancode.KP_MEMMULTIPLY|SCANCODE_MASK),
	KP_MEMDIVIDE = auto_cast (Scancode.KP_MEMDIVIDE|SCANCODE_MASK),
	KP_PLUSMINUS = auto_cast (Scancode.KP_PLUSMINUS|SCANCODE_MASK),
	KP_CLEAR = auto_cast (Scancode.KP_CLEAR|SCANCODE_MASK),
	KP_CLEARENTRY = auto_cast (Scancode.KP_CLEARENTRY|SCANCODE_MASK),
	KP_BINARY = auto_cast (Scancode.KP_BINARY|SCANCODE_MASK),
	KP_OCTAL = auto_cast (Scancode.KP_OCTAL|SCANCODE_MASK),
	KP_DECIMAL = auto_cast (Scancode.KP_DECIMAL|SCANCODE_MASK),
	KP_HEXADECIMAL = auto_cast (Scancode.KP_HEXADECIMAL|SCANCODE_MASK),

	LCTRL = auto_cast (Scancode.LCTRL|SCANCODE_MASK),
	LSHIFT = auto_cast (Scancode.LSHIFT|SCANCODE_MASK),
	LALT = auto_cast (Scancode.LALT|SCANCODE_MASK),
	LGUI = auto_cast (Scancode.LGUI|SCANCODE_MASK),
	RCTRL = auto_cast (Scancode.RCTRL|SCANCODE_MASK),
	RSHIFT = auto_cast (Scancode.RSHIFT|SCANCODE_MASK),
	RALT = auto_cast (Scancode.RALT|SCANCODE_MASK),
	RGUI = auto_cast (Scancode.RGUI|SCANCODE_MASK),

	MODE = auto_cast (Scancode.MODE|SCANCODE_MASK),

	AUDIONEXT = auto_cast (Scancode.AUDIONEXT|SCANCODE_MASK),
	AUDIOPREV = auto_cast (Scancode.AUDIOPREV|SCANCODE_MASK),
	AUDIOSTOP = auto_cast (Scancode.AUDIOSTOP|SCANCODE_MASK),
	AUDIOPLAY = auto_cast (Scancode.AUDIOPLAY|SCANCODE_MASK),
	AUDIOMUTE = auto_cast (Scancode.AUDIOMUTE|SCANCODE_MASK),
	MEDIASELECT = auto_cast (Scancode.MEDIASELECT|SCANCODE_MASK),
	WWW = auto_cast (Scancode.WWW|SCANCODE_MASK),
	MAIL = auto_cast (Scancode.MAIL|SCANCODE_MASK),
	CALCULATOR = auto_cast (Scancode.CALCULATOR|SCANCODE_MASK),
	COMPUTER = auto_cast (Scancode.COMPUTER|SCANCODE_MASK),
	AC_SEARCH = auto_cast (Scancode.AC_SEARCH|SCANCODE_MASK),
	AC_HOME = auto_cast (Scancode.AC_HOME|SCANCODE_MASK),
	AC_BACK = auto_cast (Scancode.AC_BACK|SCANCODE_MASK),
	AC_FORWARD = auto_cast (Scancode.AC_FORWARD|SCANCODE_MASK),
	AC_STOP = auto_cast (Scancode.AC_STOP|SCANCODE_MASK),
	AC_REFRESH = auto_cast (Scancode.AC_REFRESH|SCANCODE_MASK),
	AC_BOOKMARKS = auto_cast (Scancode.AC_BOOKMARKS|SCANCODE_MASK),

	BRIGHTNESSDOWN = auto_cast (Scancode.BRIGHTNESSDOWN|SCANCODE_MASK),
	BRIGHTNESSUP = auto_cast (Scancode.BRIGHTNESSUP|SCANCODE_MASK),
	DISPLAYSWITCH = auto_cast (Scancode.DISPLAYSWITCH|SCANCODE_MASK),
	KBDILLUMTOGGLE = auto_cast (Scancode.KBDILLUMTOGGLE|SCANCODE_MASK),
	KBDILLUMDOWN = auto_cast (Scancode.KBDILLUMDOWN|SCANCODE_MASK),
	KBDILLUMUP = auto_cast (Scancode.KBDILLUMUP|SCANCODE_MASK),
	EJECT = auto_cast (Scancode.EJECT|SCANCODE_MASK),
	SLEEP = auto_cast (Scancode.SLEEP|SCANCODE_MASK),
	APP1 = auto_cast (Scancode.APP1|SCANCODE_MASK),
	APP2 = auto_cast (Scancode.APP2|SCANCODE_MASK),

	AUDIOREWIND = auto_cast (Scancode.AUDIOREWIND|SCANCODE_MASK),
	AUDIOFASTFORWARD = auto_cast (Scancode.AUDIOFASTFORWARD|SCANCODE_MASK),
}

KeymodFlag :: enum u16 {
	LSHIFT   = 0x0,
	RSHIFT   = 0x1,
	LCTRL    = 0x6,
	RCTRL    = 0x7,
	LALT     = 0x8,
	RALT     = 0x9,
	LGUI     = 0xa,
	RGUI     = 0xb,
	NUM      = 0xc,
	CAPS     = 0xd,
	MODE     = 0xe,
	RESERVED = 0xf,
}

Keymod :: distinct bit_set[KeymodFlag; u16]

KMOD_NONE     :: Keymod{}
KMOD_LSHIFT   :: Keymod{.LSHIFT}
KMOD_RSHIFT   :: Keymod{.RSHIFT}
KMOD_LCTRL    :: Keymod{.LCTRL}
KMOD_RCTRL    :: Keymod{.RCTRL}
KMOD_LALT     :: Keymod{.LALT}
KMOD_RALT     :: Keymod{.RALT}
KMOD_LGUI     :: Keymod{.LGUI}
KMOD_RGUI     :: Keymod{.RGUI}
KMOD_NUM      :: Keymod{.NUM}
KMOD_CAPS     :: Keymod{.CAPS}
KMOD_MODE     :: Keymod{.MODE}
KMOD_RESERVED :: Keymod{.RESERVED}
KMOD_CTRL     :: Keymod{.LCTRL, .RCTRL}
KMOD_SHIFT    :: Keymod{.LSHIFT, .RSHIFT}
KMOD_ALT      :: Keymod{.LALT, .RALT}
KMOD_GUI      :: Keymod{.LGUI, .RGUI};