/******************************************************************************
*	File		-	key_codes.h
*	Author		-	Joey Pollack
*	Date		-	2019/11/14 (y/m/d)
*	Mod Date	-	2021/09/08 (y/m/d)
*	Description	-	Key code definitions using GLFW
*
******************************************************************************/

#ifndef KEY_CODES_H_
#define KEY_CODES_H_

#include "window.h"
#include <vector>
#include <map>

namespace lunarium
{
	enum KeyCode
	{
		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',

		NUM_0 = '0',
		NUM_1 = '1',
		NUM_2 = '2',
		NUM_3 = '3',
		NUM_4 = '4',
		NUM_5 = '5',
		NUM_6 = '6',
		NUM_7 = '7',
		NUM_8 = '8',
		NUM_9 = '9',

		F1 = GLFW_KEY_F1,
		F2 = GLFW_KEY_F2,
		F3 = GLFW_KEY_F3,
		F4 = GLFW_KEY_F4,
		F5 = GLFW_KEY_F5,
		F6 = GLFW_KEY_F6,
		F7 = GLFW_KEY_F7,
		F8 = GLFW_KEY_F8,
		F9 = GLFW_KEY_F9,
		F10 = GLFW_KEY_F10,
		F11 = GLFW_KEY_F11,
		F12 = GLFW_KEY_F12,

		LSHIFT = GLFW_KEY_LEFT_SHIFT,
		RSHIFT = GLFW_KEY_RIGHT_SHIFT,
		LCONTROL = GLFW_KEY_LEFT_CONTROL,
		RCONTROL = GLFW_KEY_RIGHT_CONTROL,
		LALT = GLFW_KEY_LEFT_ALT,
		RALT = GLFW_KEY_RIGHT_ALT,

		SPACE = GLFW_KEY_SPACE,

		// Left Arrow Key
		LEFT = GLFW_KEY_LEFT,

		// Up Arrow Key
		UP = GLFW_KEY_UP,

		// Right Arrow Key
		RIGHT = GLFW_KEY_RIGHT,

		// Down Arrow Key
		DOWN = GLFW_KEY_DOWN,

		// DELETE
		DEL = GLFW_KEY_DELETE,

		// ENTER
		RETURN  = GLFW_KEY_ENTER,

		BACKSPACE = GLFW_KEY_BACKSPACE,
		TAB  = GLFW_KEY_TAB,

		ESCAPE = GLFW_KEY_ESCAPE,

		PAGE_UP = GLFW_KEY_PAGE_UP,
		PAGE_DOWN = GLFW_KEY_PAGE_DOWN,

		// Punctuation
		SEMICOLON = GLFW_KEY_SEMICOLON,			// ';:' for US
		EQUALS = GLFW_KEY_EQUAL,				// '+' any country
		COMMA = GLFW_KEY_COMMA,					// ',' any country
		DASH = GLFW_KEY_MINUS,					// '-' any country
		DOT = GLFW_KEY_PERIOD,					// '.' any country
		FORWARD_SLASH = GLFW_KEY_SLASH,   		// '/?' for US
		TILDE = GLFW_KEY_GRAVE_ACCENT,			// '`~' for US

		OPEN_BRACKET = GLFW_KEY_LEFT_BRACKET,	//  '[{' for US
		BACKSLASH = GLFW_KEY_BACKSLASH,			//  '\|' for US
		CLOSE_BRACKET = GLFW_KEY_RIGHT_BRACKET,	//  ']}' for US
		QUOTE = GLFW_KEY_APOSTROPHE,			//  ''"' for US

		// MOUSE BUTTONS
		MOUSE_LEFT_BUTTON = GLFW_MOUSE_BUTTON_LEFT,
		MOUSE_RIGHT_BUTTON = GLFW_MOUSE_BUTTON_RIGHT,
		MOUSE_MIDDLE_BUTTON = GLFW_MOUSE_BUTTON_MIDDLE,

		// NOTE: Not sure about these
		MOUSE_X1_BUTTON = GLFW_MOUSE_BUTTON_4,
		MOUSE_X2_BUTTON = GLFW_MOUSE_BUTTON_5,

		// ALTERNATE NAMES
		SHIFT = GLFW_KEY_LEFT_SHIFT,
		CONTROL = GLFW_KEY_LEFT_CONTROL,
		ALT = GLFW_KEY_LEFT_ALT,

		KEY_UNKNOWN = 0xFFFF
	};

	static std::vector<KeyCode> KeyCodeList = {
		KeyCode::A,
		KeyCode::B,
		KeyCode::C,
		KeyCode::D,
		KeyCode::E,
		KeyCode::F,
		KeyCode::G,
		KeyCode::H,
		KeyCode::I,
		KeyCode::J,
		KeyCode::K,
		KeyCode::L,
		KeyCode::M,
		KeyCode::N,
		KeyCode::O,
		KeyCode::P,
		KeyCode::Q,
		KeyCode::R,
		KeyCode::S,
		KeyCode::T,
		KeyCode::U,
		KeyCode::V,
		KeyCode::W,
		KeyCode::X,
		KeyCode::Y,
		KeyCode::Z,

		KeyCode::NUM_0,
		KeyCode::NUM_1,
		KeyCode::NUM_2,
		KeyCode::NUM_3,
		KeyCode::NUM_4,
		KeyCode::NUM_5,
		KeyCode::NUM_6,
		KeyCode::NUM_7,
		KeyCode::NUM_8,
		KeyCode::NUM_9,

		KeyCode::F1,
		KeyCode::F2,
		KeyCode::F3,
		KeyCode::F4,
		KeyCode::F5,
		KeyCode::F6,
		KeyCode::F7,
		KeyCode::F8,
		KeyCode::F9,
		KeyCode::F10,
		KeyCode::F11,
		KeyCode::F12,

		KeyCode::LSHIFT,
		KeyCode::RSHIFT,
		KeyCode::LCONTROL,
		KeyCode::RCONTROL,
		KeyCode::LALT,
		KeyCode::RALT,
		KeyCode::SPACE,
		KeyCode::LEFT,
		KeyCode::UP,
		KeyCode::RIGHT,
		KeyCode::DOWN,
		KeyCode::DEL,
		KeyCode::RETURN,
		KeyCode::BACKSPACE,
		KeyCode::TAB,
		KeyCode::ESCAPE,
		KeyCode::PAGE_UP,
		KeyCode::PAGE_DOWN,
		KeyCode::SEMICOLON,		
		KeyCode::EQUALS,			
		KeyCode::COMMA,					
		KeyCode::DASH,					
		KeyCode::DOT,					
		KeyCode::FORWARD_SLASH,   		
		KeyCode::TILDE,			
		KeyCode::OPEN_BRACKET,	
		KeyCode::BACKSLASH,			
		KeyCode::CLOSE_BRACKET,	
		KeyCode::QUOTE,			
		KeyCode::MOUSE_LEFT_BUTTON,
		KeyCode::MOUSE_RIGHT_BUTTON,
		KeyCode::MOUSE_MIDDLE_BUTTON,
		KeyCode::MOUSE_X1_BUTTON,
		KeyCode::MOUSE_X2_BUTTON
	};

	static std::map<std::string, KeyCode> KeyCodeMap = 
	{
		std::pair<std::string, KeyCode> {"A", KeyCode::A},
		std::pair<std::string, KeyCode> {"B", KeyCode::B},
		std::pair<std::string, KeyCode> {"C", KeyCode::C},
		std::pair<std::string, KeyCode> {"D", KeyCode::D},
		std::pair<std::string, KeyCode> {"E", KeyCode::E},
		std::pair<std::string, KeyCode> {"F", KeyCode::F},
		std::pair<std::string, KeyCode> {"G", KeyCode::G},
		std::pair<std::string, KeyCode> {"H", KeyCode::H},
		std::pair<std::string, KeyCode> {"I", KeyCode::I},
		std::pair<std::string, KeyCode> {"J", KeyCode::J},
		std::pair<std::string, KeyCode> {"K", KeyCode::K},
		std::pair<std::string, KeyCode> {"L", KeyCode::L},
		std::pair<std::string, KeyCode> {"M", KeyCode::M},
		std::pair<std::string, KeyCode> {"N", KeyCode::N},
		std::pair<std::string, KeyCode> {"O", KeyCode::O},
		std::pair<std::string, KeyCode> {"P", KeyCode::P},
		std::pair<std::string, KeyCode> {"Q", KeyCode::Q},
		std::pair<std::string, KeyCode> {"R", KeyCode::R},
		std::pair<std::string, KeyCode> {"S", KeyCode::S},
		std::pair<std::string, KeyCode> {"T", KeyCode::T},
		std::pair<std::string, KeyCode> {"U", KeyCode::U},
		std::pair<std::string, KeyCode> {"V", KeyCode::V},
		std::pair<std::string, KeyCode> {"W", KeyCode::W},
		std::pair<std::string, KeyCode> {"X", KeyCode::X},
		std::pair<std::string, KeyCode> {"Y", KeyCode::Y},
		std::pair<std::string, KeyCode> {"Z", KeyCode::Z},
		
		std::pair<std::string, KeyCode> {"NUM_0", KeyCode::NUM_0},
		std::pair<std::string, KeyCode> {"NUM_1", KeyCode::NUM_1},
		std::pair<std::string, KeyCode> {"NUM_2", KeyCode::NUM_2},
		std::pair<std::string, KeyCode> {"NUM_3", KeyCode::NUM_3},
		std::pair<std::string, KeyCode> {"NUM_4", KeyCode::NUM_4},
		std::pair<std::string, KeyCode> {"NUM_5", KeyCode::NUM_5},
		std::pair<std::string, KeyCode> {"NUM_6", KeyCode::NUM_6},
		std::pair<std::string, KeyCode> {"NUM_7", KeyCode::NUM_7},
		std::pair<std::string, KeyCode> {"NUM_8", KeyCode::NUM_8},
		std::pair<std::string, KeyCode> {"NUM_9", KeyCode::NUM_9},
		
		std::pair<std::string, KeyCode> {"F1", KeyCode::F1},
		std::pair<std::string, KeyCode> {"F2", KeyCode::F2},
		std::pair<std::string, KeyCode> {"F3", KeyCode::F3},
		std::pair<std::string, KeyCode> {"F4", KeyCode::F4},
		std::pair<std::string, KeyCode> {"F5", KeyCode::F5},
		std::pair<std::string, KeyCode> {"F6", KeyCode::F6},
		std::pair<std::string, KeyCode> {"F7", KeyCode::F7},
		std::pair<std::string, KeyCode> {"F8", KeyCode::F8},
		std::pair<std::string, KeyCode> {"F9", KeyCode::F9},
		std::pair<std::string, KeyCode> {"F10", KeyCode::F10},
		std::pair<std::string, KeyCode> {"F11", KeyCode::F11},
		std::pair<std::string, KeyCode> {"F12", KeyCode::F12},
		
		std::pair<std::string, KeyCode> {"LSHIFT", KeyCode::LSHIFT},
		std::pair<std::string, KeyCode> {"RSHIFT", KeyCode::RSHIFT},
		std::pair<std::string, KeyCode> {"LCONTROL", KeyCode::LCONTROL},
		std::pair<std::string, KeyCode> {"RCONTROL", KeyCode::RCONTROL},
		std::pair<std::string, KeyCode> {"LALT", KeyCode::LALT},
		std::pair<std::string, KeyCode> {"RALT", KeyCode::RALT},
		std::pair<std::string, KeyCode> {"SPACE", KeyCode::SPACE},
		std::pair<std::string, KeyCode> {"LEFT", KeyCode::LEFT},
		std::pair<std::string, KeyCode> {"UP", KeyCode::UP},
		std::pair<std::string, KeyCode> {"RIGHT", KeyCode::RIGHT},
		std::pair<std::string, KeyCode> {"DOWN", KeyCode::DOWN},
		std::pair<std::string, KeyCode> {"DEL", KeyCode::DEL},
		std::pair<std::string, KeyCode> {"RETURN", KeyCode::RETURN},
		std::pair<std::string, KeyCode> {"BACKSPACE", KeyCode::BACKSPACE},
		std::pair<std::string, KeyCode> {"TAB", KeyCode::TAB},
		std::pair<std::string, KeyCode> {"ESCAPE", KeyCode::ESCAPE},
		std::pair<std::string, KeyCode> {"PAGE_UP", KeyCode::PAGE_UP},
		std::pair<std::string, KeyCode> {"PAGE_DOWN", KeyCode::PAGE_DOWN},
		std::pair<std::string, KeyCode> {"SEMICOLON", KeyCode::SEMICOLON},		
		std::pair<std::string, KeyCode> {"EQUALS", KeyCode::EQUALS},			
		std::pair<std::string, KeyCode> {"COMMA", KeyCode::COMMA},					
		std::pair<std::string, KeyCode> {"DASH", KeyCode::DASH},					
		std::pair<std::string, KeyCode> {"DOT", KeyCode::DOT},					
		std::pair<std::string, KeyCode> {"FORWARD_SLASH", KeyCode::FORWARD_SLASH},   		
		std::pair<std::string, KeyCode> {"TILDE", KeyCode::TILDE},			
		std::pair<std::string, KeyCode> {"OPEN_BRACKET", KeyCode::OPEN_BRACKET},	
		std::pair<std::string, KeyCode> {"BACKSLASH", KeyCode::BACKSLASH},			
		std::pair<std::string, KeyCode> {"CLOSE_BRACKET", KeyCode::CLOSE_BRACKET},	
		std::pair<std::string, KeyCode> {"QUOTE", KeyCode::QUOTE},			
		std::pair<std::string, KeyCode> {"MOUSE_LEFT_BUTTON", KeyCode::MOUSE_LEFT_BUTTON},
		std::pair<std::string, KeyCode> {"MOUSE_RIGHT_BUTTON", KeyCode::MOUSE_RIGHT_BUTTON},
		std::pair<std::string, KeyCode> {"MOUSE_MIDDLE_BUTTON", KeyCode::MOUSE_MIDDLE_BUTTON},
		std::pair<std::string, KeyCode> {"MOUSE_X1_BUTTON", KeyCode::MOUSE_X1_BUTTON},
		std::pair<std::string, KeyCode> {"MOUSE_X2_BUTTON", KeyCode::MOUSE_X2_BUTTON}
	};
}


#endif	// KEY_CODES_H_