#include "misc/key_type/key_type.h"

#include <unordered_map>
#include <Windows.h>

key_code platform_key_to_key_code(int32_t native_key) {
	switch (native_key) {
		// 字母键 (A-Z)
		case 'A': return key_code::a;
		case 'B': return key_code::b;
		case 'C': return key_code::c;
		case 'D': return key_code::d;
		case 'E': return key_code::e;
		case 'F': return key_code::f;
		case 'G': return key_code::g;
		case 'H': return key_code::h;
		case 'I': return key_code::i;
		case 'J': return key_code::j;
		case 'K': return key_code::k;
		case 'L': return key_code::l;
		case 'M': return key_code::m;
		case 'N': return key_code::n;
		case 'O': return key_code::o;
		case 'P': return key_code::p;
		case 'Q': return key_code::q;
		case 'R': return key_code::r;
		case 'S': return key_code::s;
		case 'T': return key_code::t;
		case 'U': return key_code::u;
		case 'V': return key_code::v;
		case 'W': return key_code::w;
		case 'X': return key_code::x;
		case 'Y': return key_code::y;
		case 'Z': return key_code::z;

		// 数字键 (0-9)
		case '0': return key_code::num_0;
		case '1': return key_code::num_1;
		case '2': return key_code::num_2;
		case '3': return key_code::num_3;
		case '4': return key_code::num_4;
		case '5': return key_code::num_5;
		case '6': return key_code::num_6;
		case '7': return key_code::num_7;
		case '8': return key_code::num_8;
		case '9': return key_code::num_9;

		// 功能键 (F1-F12)
		case VK_F1: return key_code::f1;
		case VK_F2: return key_code::f2;
		case VK_F3: return key_code::f3;
		case VK_F4: return key_code::f4;
		case VK_F5: return key_code::f5;
		case VK_F6: return key_code::f6;
		case VK_F7: return key_code::f7;
		case VK_F8: return key_code::f8;
		case VK_F9: return key_code::f9;
		case VK_F10: return key_code::f10;
		case VK_F11: return key_code::f11;
		case VK_F12: return key_code::f12;

		// 特殊键
		case VK_ESCAPE: return key_code::escape;
		case VK_TAB: return key_code::tab;
		case VK_CAPITAL: return key_code::caps_lock;
		case VK_SHIFT: return key_code::left_shift;
		case VK_LSHIFT: return key_code::left_shift;
		case VK_RSHIFT: return key_code::right_shift;
		case VK_CONTROL: return key_code::left_control;
		case VK_LCONTROL: return key_code::left_control;
		case VK_RCONTROL: return key_code::right_control;
		case VK_MENU: return key_code::left_alt;
		case VK_LMENU: return key_code::left_alt;
		case VK_RMENU: return key_code::right_alt;
		case VK_LWIN: return key_code::left_meta;
		case VK_RWIN: return key_code::right_meta;
		case VK_APPS: return key_code::context_menu;
		case VK_SPACE: return key_code::space;
		case VK_RETURN: return key_code::enter;
		case VK_BACK: return key_code::backspace;
		case VK_DELETE: return key_code::delete_key;

		// 导航键
		case VK_INSERT: return key_code::insert;
		case VK_HOME: return key_code::home;
		case VK_END: return key_code::end;
		case VK_PRIOR: return key_code::page_up;
		case VK_NEXT: return key_code::page_down;
		case VK_UP: return key_code::up;
		case VK_DOWN: return key_code::down;
		case VK_LEFT: return key_code::left;
		case VK_RIGHT: return key_code::right;

		// 符号键
		case VK_OEM_3: return key_code::back_quote;    // `
		case VK_OEM_MINUS: return key_code::minus;     // -
		case VK_OEM_PLUS: return key_code::equals;     // =
		case VK_OEM_4: return key_code::left_bracket;  // [
		case VK_OEM_6: return key_code::right_bracket; // ]
		case VK_OEM_5: return key_code::backslash;     // 左斜杠
		case VK_OEM_1: return key_code::semicolon;     // ;
		case VK_OEM_7: return key_code::apostrophe;    // '
		case VK_OEM_COMMA: return key_code::comma;     // ,
		case VK_OEM_PERIOD: return key_code::period;   // .
		case VK_OEM_2: return key_code::slash;         // /

		// 小键盘
		case VK_NUMLOCK: return key_code::num_lock;
		case VK_NUMPAD0: return key_code::numpad_0;
		case VK_NUMPAD1: return key_code::numpad_1;
		case VK_NUMPAD2: return key_code::numpad_2;
		case VK_NUMPAD3: return key_code::numpad_3;
		case VK_NUMPAD4: return key_code::numpad_4;
		case VK_NUMPAD5: return key_code::numpad_5;
		case VK_NUMPAD6: return key_code::numpad_6;
		case VK_NUMPAD7: return key_code::numpad_7;
		case VK_NUMPAD8: return key_code::numpad_8;
		case VK_NUMPAD9: return key_code::numpad_9;
		case VK_MULTIPLY: return key_code::numpad_multiply;
		case VK_ADD: return key_code::numpad_add;
		case VK_SUBTRACT: return key_code::numpad_subtract;
		case VK_DECIMAL: return key_code::numpad_decimal;
		case VK_DIVIDE: return key_code::numpad_divide;

		// 系统/媒体键
		case VK_SNAPSHOT: return key_code::print_screen;
		case VK_SCROLL: return key_code::scroll_lock;
		case VK_PAUSE: return key_code::pause;
		case VK_VOLUME_MUTE: return key_code::volume_mute;
		case VK_VOLUME_DOWN: return key_code::volume_down;
		case VK_VOLUME_UP: return key_code::volume_up;
		case VK_MEDIA_PLAY_PAUSE: return key_code::media_play;
		case VK_MEDIA_STOP: return key_code::media_stop;
		case VK_MEDIA_PREV_TRACK: return key_code::media_prev;
		case VK_MEDIA_NEXT_TRACK: return key_code::media_next;

		// 未识别的键
		default: return key_code::unknown;
	}
}

mouse_button platform_event_to_mouse_button(uint32_t native_event, uintptr_t native_param) {
	switch (native_event) {
		case WM_LBUTTONDOWN:
		case WM_LBUTTONUP:
		case WM_LBUTTONDBLCLK: return mouse_button::left;

		case WM_RBUTTONDOWN:
		case WM_RBUTTONUP:
		case WM_RBUTTONDBLCLK: return mouse_button::right;

		case WM_MBUTTONDOWN:
		case WM_MBUTTONUP:
		case WM_MBUTTONDBLCLK: return mouse_button::middle;

		case WM_XBUTTONDOWN:
		case WM_XBUTTONUP:
		case WM_XBUTTONDBLCLK:
			// 高位字节指示X按钮
			return HIWORD(native_param) == XBUTTON1 ? mouse_button::x1 : mouse_button::x2;
		default: ;
	}

	return mouse_button::none;
}

mouse_action platform_event_to_mouse_action(uint32_t native_event, uintptr_t native_param) {
	switch (native_event) {
		case WM_LBUTTONDOWN:
		case WM_RBUTTONDOWN:
		case WM_MBUTTONDOWN:
		case WM_XBUTTONDOWN: return mouse_action::press;

		case WM_LBUTTONUP:
		case WM_RBUTTONUP:
		case WM_MBUTTONUP:
		case WM_XBUTTONUP: return mouse_action::release;

		case WM_LBUTTONDBLCLK:
		case WM_RBUTTONDBLCLK:
		case WM_MBUTTONDBLCLK:
		case WM_XBUTTONDBLCLK: return mouse_action::dbl_click;

		case WM_MOUSEMOVE: return mouse_action::move;
		default: ;
	}

	return mouse_action::none;
}

wheel_event platform_event_to_wheel_event(uint32_t native_event, uintptr_t native_param1, intptr_t native_param2) {
	wheel_event result;

	// 获取当前修饰键状态
	if (GetKeyState(VK_CONTROL) & 0x8000) {
		result.modifiers |= keyboard_modifier::ctrl;
	}
	if (GetKeyState(VK_SHIFT) & 0x8000) {
		result.modifiers |= keyboard_modifier::shift;
	}
	if (GetKeyState(VK_MENU) & 0x8000) {
		result.modifiers |= keyboard_modifier::alt;
	}
	if ((GetKeyState(VK_LWIN) & 0x8000) || (GetKeyState(VK_RWIN) & 0x8000)) {
		result.modifiers |= keyboard_modifier::meta;
	}

	switch (native_event) {
		case WM_MOUSEWHEEL:
			result.type = wheel_type::vertical;
		result.delta_y = static_cast<float>(GET_WHEEL_DELTA_WPARAM(native_param1)) / WHEEL_DELTA;
		break;

		case WM_MOUSEHWHEEL:
			result.type = wheel_type::horizontal;
		result.delta_x = static_cast<float>(GET_WHEEL_DELTA_WPARAM(native_param1)) / WHEEL_DELTA;
		break;

		default:
			break;
	}

	return result;
}

