#include "Key.h"

/*------------------------------------------------------------------------------------------*/

/*---------------------------------------------------------------------*/

/*-----按键服务函数调用周期。单位ms--------*/
#define KEY_CALL_CYCLE 10U

/*-----------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------*/
typedef struct
{
    uint16_t u16KeyShortPressTime;     /*¶Ì°´¼ì²âʱ¼ä*/
    uint16_t u16KeyLongPressTime;      /*³¤°´¼ì²âʱ¼ä*/
    uint16_t u16KeySuperLongPressTime; /*³¬³¤°´¼ì²âʱ¼ä*/
    uint16_t u16KeyLoosenTime;         /*ËÉ¿ª¼ì²âʱ¼ä*/
    uint16_t u16KeyValidOFFTime;       /*ÓÐЧOFF¼ì²âʱ¼ä*/
    uint16_t u16KeyValidONTime;        /*ÓÐЧON¼ì²âʱ¼ä*/

} Key_Parameter_st_t;

typedef struct
{
    Key_Real_Status_en_t enKeyTypeLast;
    uint16_t u16KeyInvalidTimeCount;
    uint16_t u16KeyValidTimeCount;
    uint16_t u16KeyFirstIGNTimeRecord;
    Key_IGN_en_t enKeyIGNFirstStatus;
    Key_IGN_en_t enKeyIGNStatusLast;
    uint8_t u8KeyIGNChangeFlag;
    uint16_t u16KeyIGNTimeCount;

} Key_Ctr_st_t;
/*------------------------------------------------------------------------------------------*/

#pragma ghs section bss = ".myNonInitArea"
static Key_Parameter_st_t stKeyParameter;
#pragma ghs section bss = default

static Key_Ctr_st_t stKeyCtrVariate[KEY_NUM_MAX];
// static Key_IGN_en_t enKeyIGNFirstStatus = KEY_IG_INVALID;
// static Key_IGN_en_t enKeyIGNStatusLast = KEY_IG_INVALID;
// static uint8_t u8KeyIGNChangeFlag = 0U;
// static uint16_t u16KeyIGNTimeCount;

/*-----------------------------------------------------------------------------------------*/
static void Key_Process(Key_Num_en_t enKeyIndex);
void Key_Service(void);
void Key_Init(void);
Key_Set_en_t Key_Parameter_Set_Short_Press_Time(uint16_t u16Time);
Key_Set_en_t Key_Parameter_Set_Long_Press_Time(uint16_t u16Time);
Key_Set_en_t Key_Parameter_Set_Super_Long_Press_Time(uint16_t u16Time);
Key_Set_en_t Key_Parameter_Set_OFF_Press_Time(uint16_t u16Time);
Key_Set_en_t Key_Parameter_Set_ON_Press_Time(uint16_t u16Time);

/*-----------------------------------------------------*/
static void Key_Process(Key_Num_en_t enKeyIndex)
{
    if (enKeyIndex < KEY_NUM_MAX)
    {
        /*Key_Real_Status_en_t enKeyRealType = (*stKeyAttribute[enKeyIndex].penKeyRealStatus);*/
        Key_Real_Status_en_t enKeyRealType = KEY_CAN_NONE;
        Key_IGN_en_t enKeyIGNRealStatus = Key_Get_IGN_Status();

        if (stKeyAttribute[enKeyIndex].pfnKeyReadStatusCallBack != 0U)
        {
            enKeyRealType = stKeyAttribute[enKeyIndex].pfnKeyReadStatusCallBack();
        }
        /*CAN°´¼ü*/
        if (stKeyAttribute[enKeyIndex].enKeyType == KEY_NO_DEBOUNCE_RISE)
        {
            if (enKeyRealType <= KEY_CAN_LONG_PRESS_NOT_RELEASE)
            {
                if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U)
                {
                    if ((stKeyCtrVariate[enKeyIndex].enKeyTypeLast == KEY_CAN_NONE) &&
                            (enKeyRealType == KEY_CAN_SHORT_PRESS))
                    {
                        stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_SHORT_PRESS);
                    }
                    else if ((stKeyCtrVariate[enKeyIndex].enKeyTypeLast == KEY_CAN_NONE) &&
                             (enKeyRealType == KEY_CAN_LONG_PRESS))
                    {
                        stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_LONG_PRESS);
                    }
                    else if ((stKeyCtrVariate[enKeyIndex].enKeyTypeLast == KEY_CAN_NONE) &&
                             (enKeyRealType == KEY_CAN_LONG_PRESS_NOT_RELEASE))
                    {
                        stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_SUPER_LONG_PRESS);
                    }
                    else
                    {
                        stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_NONE);
                    }
                }

                stKeyCtrVariate[enKeyIndex].enKeyTypeLast = enKeyRealType;
            }
            else
            {
                stKeyCtrVariate[enKeyIndex].enKeyTypeLast = KEY_CAN_NONE;
            }
        }
        else if (stKeyAttribute[enKeyIndex].enKeyType == KEY_NO_DEBOUNCE_FALL)
        {
            if (enKeyRealType <= KEY_CAN_LONG_PRESS_NOT_RELEASE)
            {
                if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U)
                {
                    if ((stKeyCtrVariate[enKeyIndex].enKeyTypeLast == KEY_CAN_SHORT_PRESS) &&
                            (enKeyRealType == KEY_CAN_NONE))
                    {
                        stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_SHORT_PRESS);
                    }
                    else if ((stKeyCtrVariate[enKeyIndex].enKeyTypeLast == KEY_CAN_LONG_PRESS) &&
                             (enKeyRealType == KEY_CAN_NONE))
                    {
                        stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_LONG_PRESS);
                    }
                    else if ((stKeyCtrVariate[enKeyIndex].enKeyTypeLast == KEY_CAN_LONG_PRESS_NOT_RELEASE) &&
                             (enKeyRealType == KEY_CAN_NONE))
                    {
                        stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_SUPER_LONG_PRESS);
                    }
                    else
                    {
                        stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_NONE);
                    }
                }

                stKeyCtrVariate[enKeyIndex].enKeyTypeLast = enKeyRealType;
            }
            else
            {
                stKeyCtrVariate[enKeyIndex].enKeyTypeLast = KEY_CAN_NONE;
            }
        }
        /*Ó²Ïß°´¼ü*/
        else if (stKeyAttribute[enKeyIndex].enKeyType == KEY_NEED_DEBOUNCE_NORMAL)
        {
            if (enKeyRealType == KEY_LINE_LOOSEN) /*空闲*/
            {
                if (stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount <= stKeyParameter.u16KeyLoosenTime)
                {
                    stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount += KEY_CALL_CYCLE;
                }
                else
                {
                    stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount = 0U;
                    stKeyCtrVariate[enKeyIndex].enKeyTypeLast = KEY_LINE_LOOSEN;
                    stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord = 0U;
                    stKeyCtrVariate[enKeyIndex].enKeyIGNFirstStatus = KEY_IG_INVALID;
                    stKeyCtrVariate[enKeyIndex].enKeyIGNStatusLast = KEY_IG_INVALID;
                    stKeyCtrVariate[enKeyIndex].u8KeyIGNChangeFlag = 0U;
                    stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount = 0U;
                }
                if ((stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount >= stKeyParameter.u16KeyLoosenTime) &&
                        (stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount >= stKeyParameter.u16KeyShortPressTime) &&
                        (stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount < stKeyParameter.u16KeyLongPressTime))
                {
                    stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount = 0U;
                    /* call back */
                    if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U)
                    {
                        stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_SHORT_PRESS);
                    }
                }
            }
            else if (enKeyRealType == KEY_LINE_PRESS) /*按键按下*/
            {
                if (stKeyCtrVariate[enKeyIndex].enKeyTypeLast != enKeyRealType)
                {
                    stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount = 0U;
                    stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord = 0U;
                    stKeyCtrVariate[enKeyIndex].enKeyTypeLast = enKeyRealType;
                    stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount = 0U;

                    stKeyCtrVariate[enKeyIndex].enKeyIGNFirstStatus = enKeyIGNRealStatus;

                    stKeyCtrVariate[enKeyIndex].enKeyIGNStatusLast = enKeyIGNRealStatus;
                }
                else
                {
                    if (stKeyCtrVariate[enKeyIndex].enKeyIGNStatusLast != enKeyIGNRealStatus)
                    {
                        stKeyCtrVariate[enKeyIndex].enKeyIGNStatusLast = enKeyIGNRealStatus;
                        if (stKeyCtrVariate[enKeyIndex].enKeyIGNFirstStatus != enKeyIGNRealStatus)
                        {
                            stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord = stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount;
                        }

                        stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount = 0U;
                    }
                    else
                    {
                        if (stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount < 0xFFF0U)
                        {
                            stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount += KEY_CALL_CYCLE;
                        }
                    }

                    if (stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount < 0xFFF0U)
                    {
                        stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount += KEY_CALL_CYCLE;
                    }
                    if (stKeyCtrVariate[enKeyIndex].enKeyIGNFirstStatus != enKeyIGNRealStatus)
                    {
                        stKeyCtrVariate[enKeyIndex].u8KeyIGNChangeFlag = 1U;
                    }

                    if (stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount >= stKeyParameter.u16KeyShortPressTime)
                    {
                        // stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount = 0U;
                    }
                    stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount = 0U;

                    if (stKeyCtrVariate[enKeyIndex].u8KeyIGNChangeFlag == 0U)
                    {
                        if (stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount >= stKeyParameter.u16KeySuperLongPressTime)
                        {
                            if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U)
                            {
                                stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_SUPER_LONG_PRESS);
                            }
                        }
                        else if (stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount >= stKeyParameter.u16KeyLongPressTime)
                        {
                            if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U)
                            {
                                stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_LONG_PRESS);
                            }
                        }
                    }
                    else
                    {
                        if (stKeyCtrVariate[enKeyIndex].enKeyIGNFirstStatus == KEY_IG_OFF)
                        {
                            if (enKeyIGNRealStatus == KEY_IG_ON)
                            {
                                if ((stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord >= stKeyParameter.u16KeyValidOFFTime) &&
                                        (stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount >= stKeyParameter.u16KeyValidONTime))
                                {
                                    if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U)
                                    {
                                        stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_OFF_TO_ON);
                                    }
                                    stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord = 0U;
                                }
                            }
                        }
                        else if (stKeyCtrVariate[enKeyIndex].enKeyIGNFirstStatus == KEY_IG_ON)
                        {
                            if (enKeyIGNRealStatus == KEY_IG_OFF)
                            {
                                if ((stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord >= stKeyParameter.u16KeyValidONTime) &&
                                        (stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount >= stKeyParameter.u16KeyValidOFFTime))
                                {
                                    if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U)
                                    {
                                        stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_ON_TO_OFF);
                                    }
                                    stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord = 0U;
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                /*ERROR*/
                stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount = 0U;
                stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount = 0U;
                stKeyCtrVariate[enKeyIndex].enKeyTypeLast = (Key_Real_Status_en_t)0U;
            }
        }
        else
        {
        }
    }
}
/*10ms调用一次*/
void Key_Service(void)
{
    uint8_t i = 0U;
    for (i = 0U; i < KEY_NUM_MAX; i++)
    {
        Key_Process((Key_Num_en_t)i); /*Key_Num_en_t*/
    }
}
/*首次上电时调用一次即可*/
void Key_Init(void)
{
    uint8_t i = 0U;
    for (i = 0U; i < KEY_NUM_MAX; i++)
    {
        stKeyCtrVariate[i].enKeyTypeLast = KEY_CAN_NONE;
        stKeyCtrVariate[i].u16KeyInvalidTimeCount = 0U;
        stKeyCtrVariate[i].u16KeyValidTimeCount = 0U;
        stKeyCtrVariate[i].u16KeyFirstIGNTimeRecord = 0U;
        stKeyCtrVariate[i].enKeyIGNFirstStatus = KEY_IG_INVALID;
        stKeyCtrVariate[i].enKeyIGNStatusLast = KEY_IG_INVALID;
        stKeyCtrVariate[i].u8KeyIGNChangeFlag = 0U;
        stKeyCtrVariate[i].u16KeyIGNTimeCount = 0U;
    }
    /*按键动作时间*/
    /*342 4.1 短按/长按操作的判断标准(判定时间):短按;40ms以上,未到800ms,长按;800ms以上*/
    stKeyParameter.u16KeyLoosenTime = 100U;
    stKeyParameter.u16KeyShortPressTime = 40U;
    stKeyParameter.u16KeyLongPressTime = 1000U;
    stKeyParameter.u16KeySuperLongPressTime = 10000U;
    stKeyParameter.u16KeyValidOFFTime = 200U; /*按键动作时间*/
    stKeyParameter.u16KeyValidONTime = 1000U;
}
/*对于硬线按键而言,判断短按的时间参数*/
Key_Set_en_t Key_Parameter_Set_Short_Press_Time(uint16_t u16Time)
{
    Key_Set_en_t enKeySetResult = KEY_SET_OK;
    if (u16Time < stKeyParameter.u16KeyLoosenTime)
    {
        enKeySetResult = KEY_SET_ERROR;
    }
    else if (u16Time > stKeyParameter.u16KeyLongPressTime)
    {
        enKeySetResult = KEY_SET_ERROR;
    }
    else
    {
        stKeyParameter.u16KeyShortPressTime = u16Time;
    }

    return enKeySetResult;
}
/*对于硬线按键而言,判断长按的时间参数*/
Key_Set_en_t Key_Parameter_Set_Long_Press_Time(uint16_t u16Time)
{
    Key_Set_en_t enKeySetResult = KEY_SET_OK;
    if (u16Time < stKeyParameter.u16KeyShortPressTime)
    {
        enKeySetResult = KEY_SET_ERROR;
    }
    else if (u16Time > stKeyParameter.u16KeySuperLongPressTime)
    {
        enKeySetResult = KEY_SET_ERROR;
    }
    else
    {
        stKeyParameter.u16KeyLongPressTime = u16Time;
    }
    return enKeySetResult;
}
/*对于硬线按键而言,判断超长按的时间参数*/
Key_Set_en_t Key_Parameter_Set_Super_Long_Press_Time(uint16_t u16Time)
{
    Key_Set_en_t enKeySetResult = KEY_SET_OK;
    if (u16Time < stKeyParameter.u16KeyLongPressTime)
    {
        enKeySetResult = KEY_SET_ERROR;
    }
    else
    {
        stKeyParameter.u16KeySuperLongPressTime = u16Time;
    }
    return enKeySetResult;
}