#ifndef INPUT_SYSTEM_H
#define INPUT_SYSTEM_H

#include <stddef.h>
#include <stdint.h>

enum KeyboardKeys
{
	KEY_UNKNOWN = 0,
	KEY_SPACE = 32,
	KEY_APOSTROPHE = 39, /* ' */
	KEY_COMMA = 44, /* , */
	KEY_MINUS = 45, /* - */
	KEY_PERIOD = 46, /* . */
	KEY_SLASH = 47, /* / */
	KEY_0 = 48,
	KEY_1 = 49,
	KEY_2 = 50,
	KEY_3 = 51,
	KEY_4 = 52,
	KEY_5 = 53,
	KEY_6 = 54,
	KEY_7 = 55,
	KEY_8 = 56,
	KEY_9 = 57,
	KEY_SEMICOLON = 59, /* ; */
	KEY_EQUAL = 61, /* = */
	KEY_A = 65,
	KEY_B = 66,
	KEY_C = 67,
	KEY_D = 68,
	KEY_E = 69,
	KEY_F = 70,
	KEY_G = 71,
	KEY_H = 72,
	KEY_I = 73,
	KEY_J = 74,
	KEY_K = 75,
	KEY_L = 76,
	KEY_M = 77,
	KEY_N = 78,
	KEY_O = 79,
	KEY_P = 80,
	KEY_Q = 81,
	KEY_R = 82,
	KEY_S = 83,
	KEY_T = 84,
	KEY_U = 85,
	KEY_V = 86,
	KEY_W = 87,
	KEY_X = 88,
	KEY_Y = 89,
	KEY_Z = 90,
	KEY_LEFT_BRACKET = 91, /* [ */
	KEY_BACKSLASH = 92, /* \ */
	KEY_RIGHT_BRACKET = 93, /* ] */
	KEY_GRAVE_ACCENT = 96, /* ` */
	KEY_WORLD_1 = 161, /* non-US #1 */
	KEY_WORLD_2 = 162, /* non-US #2 */
	KEY_ESCAPE = 256,
	KEY_ENTER = 257,
	KEY_TAB = 258,
	KEY_BACKSPACE = 259,
	KEY_INSERT = 260,
	KEY_DELETE = 261,
	KEY_RIGHT = 262,
	KEY_LEFT = 263,
	KEY_DOWN = 264,
	KEY_UP = 265,
	KEY_PAGE_UP = 266,
	KEY_PAGE_DOWN = 267,
	KEY_HOME = 268,
	KEY_END = 269,
	KEY_CAPS_LOCK = 280,
	KEY_SCROLL_LOCK = 281,
	KEY_NUM_LOCK = 282,
	KEY_PRINT_SCREEN = 283,
	KEY_PAUSE = 284,
	KEY_F1 = 290,
	KEY_F2 = 291,
	KEY_F3 = 292,
	KEY_F4 = 293,
	KEY_F5 = 294,
	KEY_F6 = 295,
	KEY_F7 = 296,
	KEY_F8 = 297,
	KEY_F9 = 298,
	KEY_F10 = 299,
	KEY_F11 = 300,
	KEY_F12 = 301,
	KEY_F13 = 302,
	KEY_F14 = 303,
	KEY_F15 = 304,
	KEY_F16 = 305,
	KEY_F17 = 306,
	KEY_F18 = 307,
	KEY_F19 = 308,
	KEY_F20 = 309,
	KEY_F21 = 310,
	KEY_F22 = 311,
	KEY_F23 = 312,
	KEY_F24 = 313,
	KEY_F25 = 314,
	KEY_KP_0 = 320,
	KEY_KP_1 = 321,
	KEY_KP_2 = 322,
	KEY_KP_3 = 323,
	KEY_KP_4 = 324,
	KEY_KP_5 = 325,
	KEY_KP_6 = 326,
	KEY_KP_7 = 327,
	KEY_KP_8 = 328,
	KEY_KP_9 = 329,
	KEY_KP_DECIMAL = 330,
	KEY_KP_DIVIDE = 331,
	KEY_KP_MULTIPLY = 332,
	KEY_KP_SUBTRACT = 333,
	KEY_KP_ADD = 334,
	KEY_KP_ENTER = 335,
	KEY_KP_EQUAL = 336,
	KEY_LEFT_SHIFT = 340,
	KEY_LEFT_CONTROL = 341,
	KEY_LEFT_ALT = 342,
	KEY_LEFT_SUPER = 343,
	KEY_RIGHT_SHIFT = 344,
	KEY_RIGHT_CONTROL = 345,
	KEY_RIGHT_ALT = 346,
	KEY_RIGHT_SUPER = 347,
	KEY_MENU = 348,

	KEY_MAX
};

typedef KeyboardKeys	scanCode_t;
typedef uint8_t			mouseButton_t;

enum mouseButton_
{
	mouseButton_Left	= 1,
	mouseButton_Middle	,
	mouseButton_Right	,

	mouseButton_LastNamed = mouseButton_Right
};
#define GetNamelessMouseButtonIndex(buttonNum) mouseButton_t(mouseButton_LastNamed + buttonNum)

enum Action_
{
	Action_Forward,
	Action_Backward,
	Action_Left,
	Action_Right,
	Action_Fire,
	Action_Use,
	Action_Max
};
typedef uint32_t Action;

class IInputSystem 
{
public:
	virtual ~IInputSystem() {}

	virtual void Init() = 0;
	virtual void Shutdown() = 0;
	virtual void Update() = 0;

	virtual size_t GetMaxScancode	() const = 0;
	virtual size_t GetMaxMouseButton() const = 0;

	virtual char   TranslateScancode(scanCode_t scancode) const = 0;

	virtual void OnKeyDown		(scanCode_t scancode) = 0;
	virtual void OnKeyUp		(scanCode_t scancode) = 0;
	virtual void OnMouseKeyDown	(mouseButton_t mousebutton) = 0;
	virtual void OnMouseKeyUp	(mouseButton_t mousebutton) = 0;
	virtual void OnMouseMove	(int32_t x, int32_t y) = 0;
	virtual void OnMouseWheel	(int32_t x, int32_t y) = 0;

	virtual bool IsKeyPressed			(scanCode_t scancode) const = 0;
	virtual bool IsMouseButtonPressed	(mouseButton_t mousebutton) const = 0;

	virtual void GetMousePosition		(int32_t* x, int32_t* y) const = 0;
	virtual void GetMouseWheelPosition	(int32_t* x, int32_t* y) const = 0;

	virtual const char* ActionToString	(Action action) const = 0;
	virtual void		BindKey			(Action action, scanCode_t scancode) = 0;
	virtual bool		IsActionActive	(Action action) const = 0;
	virtual void		UnBindKey		(Action action) = 0;
	virtual void		UnBindAll		() = 0;
};

extern IInputSystem* g_inputSystem;

IInputSystem* CreateInputSystem(void* wndHandle);
void DestroyInputSystem(IInputSystem* pInstance);

#endif // !INPUT_SYSTEM_H
