#pragma once
/**
 * @file key_type.h
 * @brief 定义键盘按键和鼠标按键的枚举
 *
 * 本文件定义了键盘按键和鼠标按键的枚举值，用于输入事件处理。
 * 鼠标按键使用位标志，允许组合多个按键。
 */

#include <cstdint>
#include "misc/enum_flags.h"

/**
 * @enum key_code
 * @brief 键盘按键码
 *
 * 定义键盘按键的标准代码，基于常见的键盘布局。
 */
enum class key_code : uint16_t {
    // 特殊键
    none    = 0,
    unknown = 0,

    // 功能键
    escape       = 0x01,
    f1           = 0x02,
    f2           = 0x03,
    f3           = 0x04,
    f4           = 0x05,
    f5           = 0x06,
    f6           = 0x07,
    f7           = 0x08,
    f8           = 0x09,
    f9           = 0x0A,
    f10          = 0x0B,
    f11          = 0x0C,
    f12          = 0x0D,
    print_screen = 0x0E,
    scroll_lock  = 0x0F,
    pause        = 0x10,

    // 主键区
    back_quote = 0x11, // `
    num_1      = 0x12,
    num_2      = 0x13,
    num_3      = 0x14,
    num_4      = 0x15,
    num_5      = 0x16,
    num_6      = 0x17,
    num_7      = 0x18,
    num_8      = 0x19,
    num_9      = 0x1A,
    num_0      = 0x1B,
    minus      = 0x1C, // -
    equals     = 0x1D, // =
    backspace  = 0x1E,

    tab           = 0x1F,
    q             = 0x20,
    w             = 0x21,
    e             = 0x22,
    r             = 0x23,
    t             = 0x24,
    y             = 0x25,
    u             = 0x26,
    i             = 0x27,
    o             = 0x28,
    p             = 0x29,
    left_bracket  = 0x2A, // [
    right_bracket = 0x2B, // ]
    backslash     = 0x2C, // \

    caps_lock     = 0x2D,
    a             = 0x2E,
    s             = 0x2F,
    d             = 0x30,
    f             = 0x31,
    g             = 0x32,
    h             = 0x33,
    j             = 0x34,
    k             = 0x35,
    l             = 0x36,
    semicolon     = 0x37, // ;
    apostrophe    = 0x38, // '
    enter         = 0x39,

    left_shift  = 0x3A,
    z           = 0x3B,
    x           = 0x3C,
    c           = 0x3D,
    v           = 0x3E,
    b           = 0x3F,
    n           = 0x40,
    m           = 0x41,
    comma       = 0x42, // ,
    period      = 0x43, // .
    slash       = 0x44, // /
    right_shift = 0x45,

    left_control  = 0x46,
    left_meta     = 0x47, // Windows/Command key
    left_alt      = 0x48,
    space         = 0x49,
    right_alt     = 0x4A,
    right_meta    = 0x4B, // Windows/Command key
    context_menu  = 0x4C,
    right_control = 0x4D,

    // 编辑控制键区
    insert     = 0x4E,
    home       = 0x4F,
    page_up    = 0x50,
    delete_key = 0x51,
    end        = 0x52,
    page_down  = 0x53,

    // 方向键区
    up    = 0x54,
    left  = 0x55,
    down  = 0x56,
    right = 0x57,

    // 小键盘区
    num_lock        = 0x58,
    numpad_divide   = 0x59, // /
    numpad_multiply = 0x5A, // *
    numpad_subtract = 0x5B, // -
    numpad_7        = 0x5C,
    numpad_8        = 0x5D,
    numpad_9        = 0x5E,
    numpad_add      = 0x5F, // +
    numpad_4        = 0x60,
    numpad_5        = 0x61,
    numpad_6        = 0x62,
    numpad_1        = 0x63,
    numpad_2        = 0x64,
    numpad_3        = 0x65,
    numpad_enter    = 0x66,
    numpad_0        = 0x67,
    numpad_decimal  = 0x68, // .

    // 多媒体键
    volume_mute = 0x69,
    volume_down = 0x6A,
    volume_up   = 0x6B,
    media_next  = 0x6C,
    media_prev  = 0x6D,
    media_stop  = 0x6E,
    media_play  = 0x6F,

    // 浏览器键
    browser_back      = 0x70,
    browser_forward   = 0x71,
    browser_refresh   = 0x72,
    browser_stop      = 0x73,
    browser_search    = 0x74,
    browser_favorites = 0x75,
    browser_home      = 0x76,

    // 其他
    max_key_value = 0xFF
};

/**
 * @enum mouse_button
 * @brief 鼠标按钮的位标志
 *
 * 定义鼠标按钮的位标志，支持组合多个按钮。
 */
enum class mouse_button : uint8_t {
    none   = 0,      ///< 无按钮
    left   = 1 << 0, ///< 鼠标左键
    right  = 1 << 1, ///< 鼠标右键
    middle = 1 << 2, ///< 鼠标中键
    x1     = 1 << 3, ///< 鼠标X1键（侧边后退键）
    x2     = 1 << 4, ///< 鼠标X2键（侧边前进键）

    // 常用组合
    all = 0xFF, ///< 所有按钮
};

/**
 * @enum mouse_action
 * @brief 鼠标按钮的动作
 */
enum class mouse_action {
	none,
	press,
	release,
	dbl_click,
	move,
};

// 为鼠标按钮启用位标志功能
DEFINE_ENUM_FLAGS(mouse_button)

/**
 * @enum keyboard_modifier
 * @brief 键盘修饰键状态的位标志
 *
 * 定义键盘修饰键的位标志，支持组合多个修饰键。
 */
enum class keyboard_modifier : uint8_t {
    none  = 0,      ///< 无修饰键
    ctrl  = 1 << 0, ///< Ctrl键
    shift = 1 << 1, ///< Shift键
    alt   = 1 << 2, ///< Alt键
    meta  = 1 << 3, ///< Meta/Win/Command键

    // 常用组合
    all = 0xFF, ///< 所有修饰键
};

// 为键盘修饰键启用位标志功能
DEFINE_ENUM_FLAGS(keyboard_modifier)

/**
 * @brief 从键盘按键获取对应的修饰键标志
 * @param key 键盘按键
 * @return 对应的修饰键标志，如果不是修饰键则返回none
 */
inline keyboard_modifier key_to_modifier(key_code key) {
    switch (key) {
        case key_code::left_control:
        case key_code::right_control:
            return keyboard_modifier::ctrl;

        case key_code::left_shift:
        case key_code::right_shift:
            return keyboard_modifier::shift;

        case key_code::left_alt:
        case key_code::right_alt:
            return keyboard_modifier::alt;

        case key_code::left_meta:
        case key_code::right_meta:
            return keyboard_modifier::meta;

        default:
            return keyboard_modifier::none;
    }
}

/**
 * @enum wheel_type
 * @brief 鼠标滚轮类型
 */
enum class wheel_type : uint8_t {
	none       = 0, ///< 无滚轮事件
	vertical   = 1, ///< 垂直滚轮
	horizontal = 2, ///< 水平滚轮
};

/**
 * @struct wheel_event
 * @brief 鼠标滚轮事件数据
 */
struct wheel_event {
	wheel_type        type      = wheel_type::none;        ///< 滚轮类型
	float             delta_x   = 0.0f;                    ///< 水平滚动量
	float             delta_y   = 0.0f;                    ///< 垂直滚动量
	keyboard_modifier modifiers = keyboard_modifier::none; ///< 同时按下的修饰键
};

/**
 * @brief 将平台特定的键码转换为统一的key_code
 * @param native_key 平台原生键码
 * @return 统一的key_code枚举值
 */
key_code platform_key_to_key_code(int32_t native_key);  // 在平台特定代码中实现

/**
 * @brief 将平台特定的鼠标事件转换为统一的mouse_button
 * @param native_event 平台原生事件类型
 * @param native_param 平台原生事件参数
 * @return 统一的mouse_button枚举值
 */
mouse_button platform_event_to_mouse_button(uint32_t native_event, uintptr_t native_param);  // 在平台特定代码中实现

/**
 * @brief 将平台特定的鼠标事件转换为统一的mouse_action
 * @param native_event 平台原生事件类型
 * @param native_param 平台原生事件参数
 * @return 统一的mouse_action枚举值
*/
mouse_action platform_event_to_mouse_action(uint32_t native_event, uintptr_t native_param);

/**
 * @brief 将平台特定的滚轮事件转换为统一的wheel_event
 * @param native_event 平台原生事件类型
 * @param native_param1 平台原生事件参数1
 * @param native_param2 平台原生事件参数2
 * @return 统一的wheel_event结构
 */
wheel_event platform_event_to_wheel_event(uint32_t native_event, uintptr_t native_param1, intptr_t native_param2);
