/**
 * @file        Popup_Lib.c
 * @brief       报警库
 * @details     包括：报警插入，按优先级排序，申请内存等
 * @author      myliu
 * @date        2022.05.12
 * @version     V1.0
 * @copyright   myliu
 */
#ifndef _POPUP_LIB_H
#define _POPUP_LIB_H

/*
Platform_32Bit
Platform_16Bit
*/

#ifdef Platform_16Bit
#define Popuplib_uint8_t unsigned char
#define Popuplib_uint16_t unsigned int
#define Popuplib_uint32_t unsigned long
#else
#define Popuplib_uint8_t unsigned char
#define Popuplib_uint16_t unsigned short
#define Popuplib_uint32_t unsigned int
#define Popuplib_uint64_t unsigned long long
#endif

#ifndef POPUPLIB_NULL
#define POPUPLIB_NULL 0u
#endif /* NULL */

#define POPUP_LIB_OK 0u
#define POPUP_LIB_CBK_ERR 1u
#define POPUP_LIB_MEM_ERR 2u

typedef void (*PopupLib_IRQ_Enable)(void);
typedef void (*PopupLib_IRQ_Disable)(void);

typedef struct
{
    Popuplib_uint8_t data[8];
} CommMemBuf_t;

struct PopupList
{
    Popuplib_uint8_t PopupID;
    Popuplib_uint8_t Status;
    Popuplib_uint16_t Timer; /*Unit = 100ms， 最大值25s*/
    struct PopupList *next;
};

typedef struct
{
    Popuplib_uint8_t Type;             /**<报警类型*/
    Popuplib_uint8_t Priority;         /**<主优先级*/
    Popuplib_uint8_t SubPriority;      /**<次优先级*/
    Popuplib_uint8_t IGNStatus;        /**<报警工作的电源状态*/
    Popuplib_uint8_t Class;           /**<报警类：比如门开*/
    const Popuplib_uint8_t *pMbrList; /**<类成员*/
    Popuplib_uint8_t MbrCnt;          /**<类成员数量*/
    Popuplib_uint8_t Message;         /**<对应报警文字*/
    Popuplib_uint8_t DispMode;        /**<显示类型，单次/多次*/
    Popuplib_uint8_t Snd;             /**<关联的声音*/
    Popuplib_uint8_t SndMode;          /**<声音类型，单次/多次*/
    Popuplib_uint8_t MinDispTime;      /**<最大显示时间 Unit = 100ms */
    Popuplib_uint16_t MaxDispTime;      /**<最小显示时间 Unit = 100ms */
} Popup_Attribute_t;

typedef struct
{
    const Popup_Attribute_t *pPopupAttributeTable; /**<报警属性表*/
    CommMemBuf_t *CommMemBuf;                      /**<二维数组，用来分配功能库内存*/
    Popuplib_uint16_t MaxCommMenSize;              /**<分配内存大小*/
    PopupLib_IRQ_Enable IRQ_Enable;                /**<开中断回调函数，请填写函数名*/
    PopupLib_IRQ_Disable IRQ_Disable;              /**<关中断回调函数，请填写函数名*/
} PopupList_Opt_t;

/**
 * @brief 报警链表初始化
 * @param[in] pPopupListOpt 详见PopupList_Opt_t
 *
 * @warning pPopupListOpt此参数必须定义为全局变量
 *
 * @since 1.0.0
 */
Popuplib_uint8_t PopupList_Init(PopupList_Opt_t *pPopupListOpt);

/**
 * @brief   为链表申请内存
 * @return  NULL  申请失败，内存已使用完
 * @return  Head  申请成功的链表地址
 *
 * @warning NONE
 *
 * @since 1.0.0
 */
struct PopupList *PopupList_Malloc(void);

/**
 * @brief 查询某报警是否存在于某个链表中
 * @param[in] head 查询的链表头
 * @param[in] pPopupID 查询的报警ID
 *
 * @return  NULL  pPopupID不在head链表中
 * @return  Head  pPopupID在head链表中
 *
 * @warning NONE
 *
 * @since 1.0.0
 */
struct PopupList *PopupList_Select(struct PopupList *head, Popuplib_uint16_t *pPopupID);

/**
 * @brief 申请加入链表
 * @param[in] head 原链表
 * @param[in] newList 需要加入head的新成员
 *
 * @return  包含新的链表，其中已包含新申请加入的成员
 *
 * @warning NONE
 *
 * @since 1.0.0
 */
struct PopupList *PopupList_Insert(struct PopupList *head, struct PopupList *newList);

/**
 * @brief 删除链表中某个报警ID
 * @param[in] head 原链表
 * @param[in] PopupID 需要删除的报警ID
 *
 * @return  包含新的链表，其中已删除PopupID
 *
 * @warning NONE
 *
 * @since 1.0.0
 */
struct PopupList *PopupList_Delete(struct PopupList *head, Popuplib_uint16_t PopupID);

/**
 * @brief 销毁某个链表
 * @param[in] head 需要销毁的链表
 *
 * @return  NULL  已被销毁的链表，地址为NULL
 *
 * @warning NONE
 *
 * @since 1.0.0
 */
struct PopupList *PopupList_Destroy(struct PopupList *head);

/**
 * @brief   获取链表版本号
 * @return  版本号 1.01
 * @since 1.0.1
 */
Popuplib_uint8_t *Get_PopupLib_Version(void);

#endif
