#pragma once


#include "INPUT_COMMON.h"

/* TODO: button remapping */
#define INPUT_LEFT_KEY_COUNT 2
static const KeyboardKeyType INPUT_LEFT_KEYS[INPUT_LEFT_KEY_COUNT] =
{
	KEYBOARD_KEY_LEFT,
	KEYBOARD_KEY_A
};

static const KeyboardInputEntry INPUT_KEYBOARD_LEFT_ENTRY = 
{
	.types = (KeyboardKeyType*)INPUT_LEFT_KEYS,
	.count = INPUT_LEFT_KEY_COUNT
};

static const MouseInputEntry INPUT_MOUSE_LEFT_ENTRY = 
{
	.types = NULL,
	.count = 0
};

#define INPUT_RIGHT_KEY_COUNT 2
static const KeyboardKeyType INPUT_RIGHT_KEYS[INPUT_RIGHT_KEY_COUNT] =
{
	KEYBOARD_KEY_RIGHT,
	KEYBOARD_KEY_D
};

static const KeyboardInputEntry INPUT_KEYBOARD_RIGHT_ENTRY = 
{
	.types = (KeyboardKeyType*)INPUT_RIGHT_KEYS,
	.count = INPUT_RIGHT_KEY_COUNT
};

static const MouseInputEntry INPUT_MOUSE_RIGHT_ENTRY = 
{
	.types = NULL,
	.count = 0
};

#define INPUT_UP_KEY_COUNT 2
static const KeyboardKeyType INPUT_UP_KEYS[INPUT_UP_KEY_COUNT] =
{
	KEYBOARD_KEY_UP,
	KEYBOARD_KEY_W
};

static const KeyboardInputEntry INPUT_KEYBOARD_UP_ENTRY = 
{
	.types = (KeyboardKeyType*)INPUT_UP_KEYS,
	.count = INPUT_UP_KEY_COUNT
};

static const MouseInputEntry INPUT_MOUSE_UP_ENTRY = 
{
	.types = NULL,
	.count = 0
};

#define INPUT_DOWN_KEY_COUNT 2
static const KeyboardKeyType INPUT_DOWN_KEYS[INPUT_DOWN_KEY_COUNT] =
{
	KEYBOARD_KEY_DOWN,
	KEYBOARD_KEY_S
};

static const KeyboardInputEntry INPUT_KEYBOARD_DOWN_ENTRY = 
{
	.types = (KeyboardKeyType*)INPUT_DOWN_KEYS,
	.count = INPUT_DOWN_KEY_COUNT
};

static const MouseInputEntry INPUT_MOUSE_DOWN_ENTRY = 
{
	.types = NULL,
	.count = 0
};

#define INPUT_SHOOT_KEY_COUNT 1
#define INPUT_SHOOT_MOUSE_BUTTON_COUNT 1
static const KeyboardKeyType INPUT_SHOOT_KEYS[INPUT_SHOOT_KEY_COUNT] =
{
	KEYBOARD_KEY_SPACE,
};

static const KeyboardInputEntry INPUT_KEYBOARD_SHOOT_ENTRY = 
{
	.types = (KeyboardKeyType*)INPUT_SHOOT_KEYS,
	.count = INPUT_SHOOT_KEY_COUNT
};

static const MouseButtonType INPUT_SHOOT_MOUSE_BUTTONS[INPUT_SHOOT_MOUSE_BUTTON_COUNT] = 
{
	MOUSE_BUTTON_LEFT
};

static const MouseInputEntry INPUT_MOUSE_SHOOT_ENTRY = 
{
	.types = (MouseButtonType*)INPUT_SHOOT_MOUSE_BUTTONS,
	.count = INPUT_SHOOT_MOUSE_BUTTON_COUNT
};

#define INPUT_SWING_KEY_COUNT 1
static const KeyboardKeyType INPUT_SWING_KEYS[INPUT_SWING_KEY_COUNT] =
{
	KEYBOARD_KEY_E,
};

static const KeyboardInputEntry INPUT_KEYBOARD_SWING_ENTRY = 
{
	.types = (KeyboardKeyType*)INPUT_SWING_KEYS,
	.count = INPUT_SWING_KEY_COUNT
};

static const MouseInputEntry INPUT_MOUSE_SWING_ENTRY = 
{
	.types = NULL,
	.count = 0
};

#define INPUT_REDIRECT_KEY_COUNT 1
#define INPUT_REDIRECT_MOUSE_BUTTON_COUNT 1
static const KeyboardKeyType INPUT_REDIRECT_KEYS[INPUT_REDIRECT_KEY_COUNT] =
{
	KEYBOARD_KEY_R,
};

static const KeyboardInputEntry INPUT_KEYBOARD_REDIRECT_ENTRY = 
{
	.types = (KeyboardKeyType*)INPUT_REDIRECT_KEYS,
	.count = INPUT_REDIRECT_KEY_COUNT
};

static const MouseButtonType INPUT_REDIRECT_MOUSE_BUTTONS[INPUT_REDIRECT_MOUSE_BUTTON_COUNT] = 
{
	MOUSE_BUTTON_RIGHT
};

static const MouseInputEntry INPUT_MOUSE_REDIRECT_ENTRY = 
{
	.types = (MouseButtonType*)INPUT_REDIRECT_MOUSE_BUTTONS,
	.count = INPUT_REDIRECT_MOUSE_BUTTON_COUNT
};

#define INPUT_LOCK_KEY_COUNT 1
#define INPUT_LOCK_MOUSE_BUTTON_COUNT 1
static const KeyboardKeyType INPUT_LOCK_KEYS[INPUT_LOCK_KEY_COUNT] =
{
	KEYBOARD_KEY_Q,
};

static const KeyboardInputEntry INPUT_KEYBOARD_LOCK_ENTRY = 
{
	.types = (KeyboardKeyType*)INPUT_LOCK_KEYS,
	.count = INPUT_LOCK_KEY_COUNT
};

static const MouseButtonType INPUT_LOCK_MOUSE_BUTTONS[INPUT_LOCK_MOUSE_BUTTON_COUNT] = 
{
	MOUSE_BUTTON_MIDDLE
};

static const MouseInputEntry INPUT_MOUSE_LOCK_ENTRY = 
{
	.types = (MouseButtonType*)INPUT_LOCK_MOUSE_BUTTONS,
	.count = INPUT_LOCK_MOUSE_BUTTON_COUNT
};

#define INPUT_RECALL_KEY_COUNT 2
static const KeyboardKeyType INPUT_RECALL_KEYS[INPUT_RECALL_KEY_COUNT] =
{
	KEYBOARD_KEY_LSHIFT,
	KEYBOARD_KEY_RSHIFT
};

static const KeyboardInputEntry INPUT_KEYBOARD_RECALL_ENTRY = 
{
	.types = (KeyboardKeyType*)INPUT_RECALL_KEYS,
	.count = INPUT_RECALL_KEY_COUNT
};

static const MouseInputEntry INPUT_MOUSE_RECALL_ENTRY = 
{
	.types = NULL,
	.count = 0
};

#define INPUT_HEART_KEY_COUNT 1
static const KeyboardKeyType INPUT_HEART_KEYS[INPUT_HEART_KEY_COUNT] =
{
	KEYBOARD_KEY_TAB
};

static const KeyboardInputEntry INPUT_KEYBOARD_HEART_ENTRY = 
{
	.types = (KeyboardKeyType*)INPUT_HEART_KEYS,
	.count = INPUT_HEART_KEY_COUNT
};

static const MouseInputEntry INPUT_MOUSE_HEART_ENTRY = 
{
	.types = NULL,
	.count = 0
};

#define INPUT_SELECT_KEY_COUNT 1
#define INPUT_SELECT_MOUSE_BUTTON_COUNT 1
static const KeyboardKeyType INPUT_SELECT_KEYS[INPUT_SELECT_KEY_COUNT] =
{
	KEYBOARD_KEY_SPACE,
};

static const KeyboardInputEntry INPUT_KEYBOARD_SELECT_ENTRY = 
{
	.types = (KeyboardKeyType*)INPUT_SELECT_KEYS,
	.count = INPUT_SELECT_KEY_COUNT
};

static const MouseButtonType INPUT_SELECT_MOUSE_BUTTONS[INPUT_SELECT_MOUSE_BUTTON_COUNT] = 
{
	MOUSE_BUTTON_LEFT
};

static const MouseInputEntry INPUT_MOUSE_SELECT_ENTRY = 
{
	.types = (MouseButtonType*)INPUT_SELECT_MOUSE_BUTTONS,
	.count = INPUT_SELECT_MOUSE_BUTTON_COUNT
};

#define INPUT_PAUSE_KEY_COUNT 1
static const KeyboardKeyType INPUT_PAUSE_KEYS[INPUT_PAUSE_KEY_COUNT] =
{
	KEYBOARD_KEY_P,
};

static const KeyboardInputEntry INPUT_KEYBOARD_PAUSE_ENTRY = 
{
	.types = (KeyboardKeyType*)INPUT_PAUSE_KEYS,
	.count = INPUT_PAUSE_KEY_COUNT
};

static const MouseInputEntry INPUT_MOUSE_PAUSE_ENTRY = 
{
	.types = NULL,
	.count = 0
};

static const KeyboardInputEntry INPUT_KEYBOARD_ENTRIES[INPUT_COUNT] =
{
	INPUT_KEYBOARD_LEFT_ENTRY,
	INPUT_KEYBOARD_RIGHT_ENTRY,
	INPUT_KEYBOARD_UP_ENTRY,
	INPUT_KEYBOARD_DOWN_ENTRY,
	INPUT_KEYBOARD_SHOOT_ENTRY,
	INPUT_KEYBOARD_SWING_ENTRY,
	INPUT_KEYBOARD_REDIRECT_ENTRY,
	INPUT_KEYBOARD_LOCK_ENTRY,
	INPUT_KEYBOARD_RECALL_ENTRY,
	INPUT_KEYBOARD_HEART_ENTRY,
	INPUT_KEYBOARD_SELECT_ENTRY,
	INPUT_KEYBOARD_PAUSE_ENTRY,
};

static const MouseInputEntry INPUT_MOUSE_ENTRIES[INPUT_COUNT] =
{
	INPUT_MOUSE_LEFT_ENTRY,
	INPUT_MOUSE_RIGHT_ENTRY,
	INPUT_MOUSE_UP_ENTRY,
	INPUT_MOUSE_DOWN_ENTRY,
	INPUT_MOUSE_SHOOT_ENTRY,
	INPUT_MOUSE_SWING_ENTRY,
	INPUT_MOUSE_REDIRECT_ENTRY,
	INPUT_MOUSE_LOCK_ENTRY,
	INPUT_MOUSE_RECALL_ENTRY,
	INPUT_MOUSE_HEART_ENTRY,
	INPUT_MOUSE_SELECT_ENTRY,
	INPUT_MOUSE_PAUSE_ENTRY
};

void input_init(Input* self);
void input_update(Input* self);
bool input_press(Input* self, InputType type);
bool input_held(Input* self, InputType type);
bool input_release(Input* self, InputType type);
