/*
 * CMD 模块 V2 - 类型定义
 * 统一的输入/输出抽象层
 */
#pragma once

#include <stdint.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

/* ========================================================================== */
/*                              错误码定义                                      */
/* ========================================================================== */
#define CMD_OK           (0)
#define CMD_ERR_NULL     (-1)
#define CMD_ERR_MODE     (-2)
#define CMD_ERR_SOURCE   (-3)
#define CMD_ERR_NO_INPUT (-4)

/* ========================================================================== */
/*                            输入源配置宏表                                    */
/* ========================================================================== */
/* 
 * 使用方法：在config中定义需要启用的输入源
 * 格式: X(枚举名, 优先级, 适配器初始化函数, 获取数据函数)
 */
#define CMD_INPUT_SOURCE_TABLE(X) \
    X(RC,  0, CMD_RC_AdapterInit,  CMD_RC_GetInput)  \
    X(PC,  1, CMD_PC_AdapterInit,  CMD_PC_GetInput)  \
    X(NUC, 2, CMD_NUC_AdapterInit, CMD_NUC_GetInput) \
    X(REF, 3, CMD_REF_AdapterInit, CMD_REF_GetInput)

/* 输出模块配置宏表 */
#define CMD_OUTPUT_MODULE_TABLE(X) \
    X(CHASSIS, Chassis_CMD_t, chassis) \
    X(GIMBAL,  Gimbal_CMD_t,  gimbal)  \
    X(SHOOT,   Shoot_CMD_t,   shoot)

/* ========================================================================== */
/*                            统一输入数据结构                                  */
/* ========================================================================== */

/* 摇杆数据 - 统一为-1.0 ~ 1.0 */
typedef struct {
    float x;
    float y;
} CMD_Joystick_t;

/* 开关位置 */
typedef enum {
    CMD_SW_ERR = 0,
    CMD_SW_UP,
    CMD_SW_MID,
    CMD_SW_DOWN,
} CMD_SwitchPos_t;

/* 鼠标数据 */
typedef struct {
    int16_t x;      /* 鼠标X轴移动速度 */
    int16_t y;      /* 鼠标Y轴移动速度 */
    int16_t z;      /* 鼠标滚轮 */
    bool l_click;   /* 左键 */
    bool r_click;   /* 右键 */
    bool m_click;   /* 中键 */
} CMD_Mouse_t;

/* 键盘数据 - 最多支持32个按键 */
typedef struct {
    uint32_t bitmap;  /* 按键位图 */
} CMD_Keyboard_t;

/* 键盘按键索引 */
typedef enum {
    CMD_KEY_W = 0, CMD_KEY_S, CMD_KEY_A, CMD_KEY_D,
    CMD_KEY_SHIFT, CMD_KEY_CTRL, CMD_KEY_Q, CMD_KEY_E,
    CMD_KEY_R, CMD_KEY_F, CMD_KEY_G, CMD_KEY_Z,
    CMD_KEY_X, CMD_KEY_C, CMD_KEY_V, CMD_KEY_B,
    CMD_KEY_NUM
} CMD_KeyIndex_t;

/* 裁判系统数据 */
typedef struct {
    uint8_t game_status;       /* 比赛状态 */
} CMD_Referee_t;

/* 统一的原始输入结构 - 所有设备适配后都转换成这个格式 */
typedef struct {
    bool online;
    
    /* 遥控器部分 */
    CMD_Joystick_t joy_left;   /* 左摇杆 */
    CMD_Joystick_t joy_right;  /* 右摇杆 */
    CMD_SwitchPos_t sw[4];     /* 最多4个拨杆 */
    float dial;                /* 拨轮 */
    
    /* PC部分 */
    CMD_Mouse_t mouse;
    CMD_Keyboard_t keyboard;
    
    /* NUC部分 */
    /* 暂无定义，预留扩展 */
    
    /* REF部分 - 裁判系统数据 */
    CMD_Referee_t referee;
} CMD_RawInput_t;

/* ========================================================================== */
/*                              输入源枚举                                      */
/* ========================================================================== */
#define ENUM_INPUT_SOURCE(name, ...) CMD_SRC_##name,
typedef enum {
    CMD_INPUT_SOURCE_TABLE(ENUM_INPUT_SOURCE)
    CMD_SRC_NUM
} CMD_InputSource_t;
#undef ENUM_INPUT_SOURCE

/* ========================================================================== */
/*                              模块掩码                                        */
/* ========================================================================== */
typedef enum {
    CMD_MODULE_NONE    = 0,
    CMD_MODULE_CHASSIS = (1 << 0),
    CMD_MODULE_GIMBAL  = (1 << 1),
    CMD_MODULE_SHOOT   = (1 << 2),
    CMD_MODULE_ALL     = 0x07
} CMD_ModuleMask_t;

/* ========================================================================== */
/*                              行为定义                                        */
/* ========================================================================== */
/* 行为-按键映射宏表 */
#define CMD_BEHAVIOR_TABLE(X) \
    X(FORE,           CMD_KEY_W,     CMD_ACTIVE_PRESSED,      CMD_MODULE_CHASSIS) \
    X(BACK,           CMD_KEY_S,     CMD_ACTIVE_PRESSED,      CMD_MODULE_CHASSIS) \
    X(LEFT,           CMD_KEY_A,     CMD_ACTIVE_PRESSED,      CMD_MODULE_CHASSIS) \
    X(RIGHT,          CMD_KEY_D,     CMD_ACTIVE_PRESSED,      CMD_MODULE_CHASSIS) \
    X(ACCELERATE,     CMD_KEY_SHIFT, CMD_ACTIVE_PRESSED,      CMD_MODULE_CHASSIS) \
    X(DECELERATE,     CMD_KEY_CTRL,  CMD_ACTIVE_PRESSED,      CMD_MODULE_CHASSIS) \
    X(FIRE,           CMD_KEY_NONE,  CMD_ACTIVE_PRESSED,      CMD_MODULE_SHOOT)   \
    X(FIRE_MODE,      CMD_KEY_B,     CMD_ACTIVE_RISING_EDGE,  CMD_MODULE_SHOOT)   \
    X(ROTOR,          CMD_KEY_E,     CMD_ACTIVE_RISING_EDGE,  CMD_MODULE_CHASSIS) \
    X(AUTOAIM,        CMD_KEY_R,     CMD_ACTIVE_RISING_EDGE,  CMD_MODULE_GIMBAL | CMD_MODULE_SHOOT)

/* 触发类型 */
typedef enum {
    CMD_ACTIVE_PRESSED,       /* 按住时触发 */
    CMD_ACTIVE_RISING_EDGE,   /* 按下瞬间触发 */
    CMD_ACTIVE_FALLING_EDGE,  /* 松开瞬间触发 */
} CMD_TriggerType_t;

/* 特殊按键值 */
#define CMD_KEY_NONE      0xFF
#define CMD_KEY_L_CLICK   0xFE
#define CMD_KEY_R_CLICK   0xFD
#define CMD_KEY_M_CLICK   0xFC

/* 行为枚举 - 由宏表自动生成 */
#define ENUM_BEHAVIOR(name, key, trigger, mask) CMD_BEHAVIOR_##name,
typedef enum {
    CMD_BEHAVIOR_TABLE(ENUM_BEHAVIOR)
    CMD_BEHAVIOR_NUM
} CMD_Behavior_t;
#undef ENUM_BEHAVIOR

/* ========================================================================== */
/*                           键盘辅助宏                                         */
/* ========================================================================== */
#define CMD_KEY_PRESSED(kb, key)   (((kb)->bitmap >> (key)) & 1)
#define CMD_KEY_SET(kb, key)       ((kb)->bitmap |= (1 << (key)))
#define CMD_KEY_CLEAR(kb, key)     ((kb)->bitmap &= ~(1 << (key)))

#ifdef __cplusplus
}
#endif
