/**
 * CAN 控制器封装类
 * 功能：简化 CAN 设备的操作，提供易用的接口
 */

#ifndef CAN_CONTROLLER_H
#define CAN_CONTROLLER_H

#include "../../lib/ControlCAN.h"
#include <string>
#include <vector>
#include <functional>

/**
 * CAN 控制器类
 */
class CANController {
public:
    // 回调函数类型：接收到 CAN 数据时调用
    using ReceiveCallback = std::function<void(const VCI_CAN_OBJ&)>;

    /**
     * 构造函数
     * @param device_type 设备类型（VCI_USBCAN2 = 4）
     * @param device_index 设备索引（第几个设备，从0开始）
     * @param can_index CAN 通道索引（0 或 1）
     */
    CANController(DWORD device_type = VCI_USBCAN2,
                  DWORD device_index = 0,
                  DWORD can_index = 0);

    ~CANController();

    /**
     * 初始化 CAN 设备
     * @param baud_t0 波特率定时器0
     * @param baud_t1 波特率定时器1
     * @param mode 工作模式：0=正常，1=只听，2=自发自收
     * @return 成功返回 true
     */
    bool Initialize(BYTE baud_t0 = 0x00, BYTE baud_t1 = 0x1C, BYTE mode = 0);

    /**
     * 关闭 CAN 设备
     */
    void Close();

    /**
     * 发送标准帧
     * @param can_id CAN ID（11位）
     * @param data 数据指针
     * @param len 数据长度（最大8字节）
     * @return 成功返回 true
     */
    bool SendStandardFrame(UINT can_id, const BYTE* data, BYTE len);

    /**
     * 发送扩展帧
     * @param can_id CAN ID（29位）
     * @param data 数据指针
     * @param len 数据长度（最大8字节）
     * @return 成功返回 true
     */
    bool SendExtendedFrame(UINT can_id, const BYTE* data, BYTE len);

    /**
     * 接收 CAN 数据（非阻塞）
     * @param frames 接收缓冲区
     * @param max_count 最大接收帧数
     * @return 实际接收到的帧数
     */
    DWORD Receive(std::vector<VCI_CAN_OBJ>& frames, DWORD max_count = 2500);

    /**
     * 获取接收缓冲区中的帧数量
     */
    DWORD GetReceiveNum();

    /**
     * 清空接收缓冲区
     */
    bool ClearBuffer();

    /**
     * 读取设备信息
     */
    bool GetDeviceInfo(VCI_BOARD_INFO& info);

    /**
     * 设置接收回调函数
     */
    void SetReceiveCallback(ReceiveCallback callback) {
        m_callback = callback;
    }

    /**
     * 是否已初始化
     */
    bool IsInitialized() const { return m_initialized; }

private:
    DWORD m_device_type;
    DWORD m_device_index;
    DWORD m_can_index;
    bool m_initialized;
    ReceiveCallback m_callback;
};

#endif // CAN_CONTROLLER_H
