#ifndef _SR_EVENT_DRIVER_H
#define _SR_EVENT_DRIVER_H

#include "sr_stddef.h"
#include "sr_list.h"

#define EVENT_CSMER_MAX 32 /*!< 每个事件消费者最大数量*/

typedef struct SR_EVT
{
	uint8_t evtId;	  /*!< 事件ID*/
	uint8_t isAssign; /*!< 是否指定某个消费者 0:所有订阅者 非0:指定消费者*/
	uint8_t csmId;	  /*!< 事件消费者ID，范围（0~31），isAssign非0时有效*/

	union /*!< 事件携带的数据*/
	{
		uint32_t evtCode; /*!< 事件码*/
		int s32Data;	  /*!< s32数据*/
		uint32_t u32Data; /*!< u32数据*/
		float f32Data;	  /*!< float数据*/
		void *pData;	  /*!< 数据指针*/
	} data;

} SR_EVT_T;

typedef void (*EvtProcCb)(SR_EVT_T evt, void *args);
/**
 * @brief 事件消费者结构体定义
 *
 */
typedef struct SR_EVT_CSM
{
	uint8_t csmId; /*!< 事件ID*/
	EvtProcCb cb;
	void *args;

} SR_EVT_CSM_T;

/**
 * @brief 事件对象结构体定义
 *
 */
typedef struct SR_EVT_OBJ
{
	uint8_t head;						   /*!< 队列头部位置*/
	uint8_t tail;						   /*!< 队列尾部位置*/
	uint8_t evtNum;						   /*!< 队列当前事件数量，单位：字节*/
	uint8_t queueNum;					   /*!< 队列总的可缓存数量*/
	SR_EVT_T *pQueue;					   /*!< 事件队列缓存*/
	uint32_t *pSubTab;					   /*!< 事件订阅列表*/
	os_slist_node_t list;				   /*!< 链表*/
	SR_EVT_CSM_T *csmTab[EVENT_CSMER_MAX]; /*!< 事件消费者列表*/

#ifdef SR_USE_OS
	SR_MUTX_T mutex; /*!< 互斥锁，用于保护buff的读写操作  1:上锁   0：关锁*/
#endif

	uint8_t subTabSize; /*!< 事件订阅列表大小，必须等于事件的定义数量*/

} SR_EVT_OBJ_T;

// 全局事件ID定义
typedef enum GLB_EVT_ID
{
	GEVT_TEST0 = 0,
	GEVT_TEST1,
	GEVT_TEST2,
	GEVT_TEST3,
	GEVT_TEST4,
	GEVT_TEST5,

	GEVT_MAX

} GLB_EVT_ID_E;

/**
 * @brief 事件对象初始化。
 *
 * @param[in] obj     事件对象指针
 * @param[in] queue   事件队列缓存
 * @param[in] queNum  事件队列缓存项数（即可容纳的事件数量）
 * @param[in] subTab  事件订阅者列表缓存
 * @param[in] tabNum  事件订阅者列表缓存的项数（必须等于事件定义的数量）
 *
 * @return 0：成功   负值：失败
 */
int SR_EvtObjInit(SR_EVT_OBJ_T *obj, SR_EVT_T *queue, uint8_t queNum, uint32_t *subTab, uint8_t tabNum);

/**
 * @brief 事件消费者初始化。
 *
 * @param[in] csm     消费者指针
 * @param[in] csmId   消费者ID号，范围[0,31]。同一事件对象的消费者ID必须唯一，且ID号越大，优先级越高
 * @param[in] cb      事件处理回调
 * @param[in] args    事件处理回调的用户参数
 *
 * @return 0：成功   负值：失败
 */
int SR_EvtCsmInit(SR_EVT_CSM_T *csm, uint8_t csmId, EvtProcCb cb, void *args);

/**
 * @brief 事件发布
 *
 * @param[in] obj     事件对象指针
 * @param[in] evt     事件
 *
 * @return 0：成功   负值：失败
 */
int SR_EvtPub(SR_EVT_OBJ_T *obj, SR_EVT_T evt);

/**
 * @brief 事件订阅
 *
 * @param[in] csm     消费者指针
 * @param[in] obj     事件对象指针
 * @param[in] evtId   事件ID
 *
 * @return 0：成功   负值：失败
 */
int SR_EvtSub(SR_EVT_CSM_T *csm, SR_EVT_OBJ_T *obj, uint8_t evtId);

/**
 * @brief 事件取消订阅
 *
 * @param[in] csm     消费者指针
 * @param[in] obj     事件对象指针
 * @param[in] evtId   事件ID
 *
 * @return 0：成功   负值：失败
 */
int SR_EvtUnsub(SR_EVT_CSM_T *csm, SR_EVT_OBJ_T *obj, uint8_t evtId);

/**
 * @brief 事件分发线程函数
 *        RTOS中以线程方式运行，裸机下需要周期循环执行
 *
 * @param[in] args   用户参数
 *
 */
void SR_EvtDispatch(void *args);

#endif
