/**
  **********************************************************************************************************************
  * @file    cot_key.h
  * @brief   该文件提供按键动作识别功能函数原型
  * @author  const_zpc    any question please send mail to const_zpc@163.com
  * @version V1.0.0
  * @date    2023-11-05
  **********************************************************************************************************************
  *
  **********************************************************************************************************************
  */

/* Define to prevent recursive inclusion -----------------------------------------------------------------------------*/
#ifndef _COT_KEY_H_
#define _COT_KEY_H_

/* Includes ----------------------------------------------------------------------------------------------------------*/
//#include <stdint.h>
#include <stddef.h>
//#include <stdbool.h>
#include "type_def.h"

// 添加布尔值定义
#ifndef FALSE
#define FALSE   0
#endif

#ifndef TRUE
#define TRUE    1
#endif
/**
  * @brief 定义宏：启动按键新配置延迟更新替换
  *        只有在按键空闲的状态下才真正更新配置信息，防止上层应用程序在某些场景更新时出现意想不到的问题
  * @note  如果上层应用程序只有在初始化时才更新配置，那么可以关闭该功能，降低内存占用
  */
#define _CONFIG_DELAY_UPDATE_

/* Exported types ----------------------------------------------------------------------------------------------------*/

/** 触发方式定义 */
#define COT_KEY_TRIGGER_WAY_PRESS           0x01  // 按下触发 - 按键按下时触发回调
#define COT_KEY_TRIGGER_WAY_LOSSEN          0x02  // 松开触发 - 按键松开时触发回调

/**
  * @brief  按键状态枚举定义
  * @note   用于表示按键的物理状态
  */
typedef enum{
    COT_KEY_OFF = 0,                         	/*!< (0)断开(无动作) - 按键未被按下 */
    COT_KEY_ON = !COT_KEY_OFF                   /*!< (1)闭合(有动作) - 按键被按下 */
} cotKeyState_e;

/** 按键相关类型定义 */
typedef uint16_t cotKey_t;                       // 按键索引类型
typedef cotKeyState_e (*cotKeyState_f)(void);    // 按键状态获取函数类型
typedef void (*cotKeyListen_f)(cotKey_t);        // 按键事件回调函数类型

/**
  * @brief  按键配置信息结构体
  * @note   用于配置按键的工作模式和触发方式
  */
typedef struct
{
    uint8_t mode;                               /*!< 按键模式:
                                                    KEY_MODE_NORMAL(0) - 普通模式
                                                    KEY_MODE_LONG_PRESS(1) - 长按模式
                                                    KEY_MODE_CLICK(2) - 连击模式
                                                    KEY_MODE_CLICK_COMP(3) - 连击复合模式 */
    uint8_t triggerWay;                         /*!< 按键事件触发回调函数的触发条件:
                                                    COT_KEY_TRIGGER_WAY_PRESS - 按下触发
                                                    COT_KEY_TRIGGER_WAY_LOSSEN - 松开触发 */
    uint16_t triggerInterval;                   /*!< 长时间按下时触发回调函数的间隔时间(ms)
                                                    0:不重复触发, >0:按指定间隔重复触发 */
    uint16_t longTime;                          /*!< 区分短按和长按的时间阈值(ms)
                                                    用于长按模式和连击复合模式 */
    cotKeyListen_f pfnEventCallback;            /*!< 按键事件触发回调函数
                                                    当按键动作满足触发条件时调用 */
} cotKeyInfo_t;

/**
  * @brief 按键处理信息结构体定义
  * @note  用于记录按键的实时状态和处理过程
  */
typedef struct
{
    cotKeyState_e eKeyStateBak;                 /*!< 按键上次开关状态 - 用于检测状态变化 */
    cotKeyState_e eKeyState;                    /*!< 按键当前开关状态 - 当前物理状态 */
    uint8_t clickCnt;                           /*!< 指定所选按键的连击次数 - 用于连击模式 */
    uint16_t uiPressTic;                        /*!< 按键按下累计时间(ms) - 用于长按检测 */
    uint16_t uiLossenTic;                       /*!< 按键松开累计时间(ms) - 用于连击间隔检测 */
    uint8_t state;                              /*!< 按键状态机状态:
                                                    KEY_STATE_IDLE(0) - 空闲
                                                    KEY_STATE_PRESS(1) - 按下
                                                    KEY_STATE_LOSSEN(2) - 松开
                                                    KEY_STATE_LONG_PRESS(3) - 长按
                                                    KEY_STATE_LONG_LOSSEN(4) - 长按松开 */
    cotKeyInfo_t curConfig;                     /*!< 按键当前配置 - 当前生效的配置 */
#if defined(_CONFIG_DELAY_UPDATE_)
    cotKeyInfo_t newConfig;                     /*!< 按键新的配置 - 待更新的配置
                                                    只在按键空闲时更新到curConfig */
#endif
} cotKeyProc_t;

/**
  * @brief  按键配置结构体
  * @note   用于初始化按键模块时的配置信息
  */
typedef struct
{
    cotKeyProc_t proc;                          // 按键处理信息
    cotKeyState_f pfnKeyState;                  // 按键状态获取函数 - 需要用户实现
} cotKeyCfg_t;

/* Exported constants ------------------------------------------------------------------------------------------------*/
/* Exported macro ----------------------------------------------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------------------------------------------------*/

// 初始化按键模块
extern int cotKey_Init(cotKeyCfg_t pCfgTable[], size_t num);

// 注册按键事件回调函数
extern int cotKey_Listen(cotKey_t eKey, cotKeyListen_f pfnKeyFun);

// 配置按键模式
extern int cotKey_ResetDefaultConfig(cotKey_t eKey);
extern int cotKey_ConfigNormalMode(cotKey_t eKey, uint8_t triggerWay, uint16_t triggerInterval);
extern int cotKey_ConfigLongPressMode(cotKey_t eKey, uint16_t longPressTime, uint16_t triggerInterval); 
extern int cotKey_ConfigClickMode(cotKey_t eKey, uint16_t triggerInterval);
extern int cotKey_ConfigClickCompMode(cotKey_t eKey, uint16_t triggerInterval, uint16_t pressMaxTime, uint8_t triggerWay);

// 获取按键状态
extern uint8_t cotKey_GetClickCount(cotKey_t eKey);
extern uint8_t cotKey_IsClickCount(cotKey_t eKey, uint8_t count);
extern uint8_t cotKey_IsLongPress(cotKey_t eKey);
extern uint8_t cotKey_IsTriggerWayMet(cotKey_t eKey, uint8_t triggerWay);
extern uint8_t cotKey_IsPressTimeMet(cotKey_t eKey, uint8_t triggerWay, uint16_t time);
extern uint8_t cotKey_IsLossenTimeMet(cotKey_t eKey, uint8_t triggerWay, uint16_t time);

// 按键扫描处理函数(需要周期调用)
extern int cotKey_Scan(uint32_t sysTime);



#endif
