
#include "Key.h"

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

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

/*-----�����������������ڡ���λms--------*/
#define KEY_CALL_CYCLE 10U

/*-----------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------*/
typedef struct
{
    uint16_t u16KeyShortPressTime;     /*�̰����ʱ��*/
    uint16_t u16KeyLongPressTime;      /*�������ʱ��*/
    uint32_t u32KeySuperLongPressTime; /*���������ʱ��*/
    uint16_t u16KeyLoosenTime;         /*�ɿ����ʱ��*/

} Key_Parameter_st_t;

typedef struct
{
    Key_Real_Status_en_t enKeyTypeLast;
    uint16_t             u16KeyInvalidTimeCount;
    uint32_t             u32KeyValidTimeCount;
    uint8_t              u8KeyLongPressTrigger;

} Key_Ctr_st_t;
/*------------------------------------------------------------------------------------------*/
#pragma alignvar(8)
static Key_Ctr_st_t stKeyCtrVariate [ KEY_NUM_MAX ];
#pragma alignvar(8)
static Key_Parameter_st_t stKeyParameter;

/*-----------------------------------------------------------------------------------------*/
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(uint32_t u32Time);

/*-----------------------------------------------------*/
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 = stKeyAttribute [ enKeyIndex ].pfnKeyReadStatusCallBack( );

        /*CAN����*/
        if ( stKeyAttribute [ enKeyIndex ].enKeyType == KEY_TYPE_CAN )
        {
            if ( enKeyRealType <= KEY_CAN_LONG_PRESS )
            {
                if ( (stKeyCtrVariate [ enKeyIndex ].enKeyTypeLast == KEY_CAN_NONE) && (enKeyRealType == KEY_CAN_SHORT_PRESS) )
                {
                    if ( stKeyAttribute [ enKeyIndex ].pfnKeyOperationCallBack != 0U )
                    {
                        stKeyAttribute [ enKeyIndex ].pfnKeyOperationCallBack(KEY_EVENT_SHORT_PRESS);
                    }
                }
                if ( (stKeyCtrVariate [ enKeyIndex ].enKeyTypeLast == KEY_CAN_NONE) && (enKeyRealType == KEY_CAN_LONG_PRESS) )
                {
                    if ( stKeyAttribute [ enKeyIndex ].pfnKeyOperationCallBack != 0U )
                    {
                        stKeyAttribute [ enKeyIndex ].pfnKeyOperationCallBack(KEY_EVENT_LONG_PRESS);
                    }
                }

                stKeyCtrVariate [ enKeyIndex ].enKeyTypeLast = enKeyRealType;
            }
            else
            {
                stKeyCtrVariate [ enKeyIndex ].enKeyTypeLast = KEY_CAN_NONE;
            }
        }
        /*Ӳ�߰���*/
        else if ( stKeyAttribute [ enKeyIndex ].enKeyType == KEY_TYPE_LINE )
        {
            if ( enKeyRealType == KEY_LINE_LOOSEN ) /*����*/
            {
                if ( stKeyCtrVariate [ enKeyIndex ].u16KeyInvalidTimeCount <= stKeyParameter.u16KeyLoosenTime )
                {
                    stKeyCtrVariate [ enKeyIndex ].u16KeyInvalidTimeCount += KEY_CALL_CYCLE;
                }
                else
                {
                    stKeyCtrVariate [ enKeyIndex ].u32KeyValidTimeCount = 0U;
                    stKeyCtrVariate [ enKeyIndex ].enKeyTypeLast        = KEY_LINE_LOOSEN;
                    /* call back */
                    if ( stKeyAttribute [ enKeyIndex ].pfnKeyOperationCallBack != 0U )
                    {
                        stKeyAttribute [ enKeyIndex ].pfnKeyOperationCallBack(KEY_EVENT_NONE);
                        stKeyCtrVariate [ enKeyIndex ].u8KeyLongPressTrigger = 0U;
                    }
                }
                if ( (stKeyCtrVariate [ enKeyIndex ].u16KeyInvalidTimeCount >= stKeyParameter.u16KeyLoosenTime) && (stKeyCtrVariate [ enKeyIndex ].u32KeyValidTimeCount >= stKeyParameter.u16KeyShortPressTime) && (stKeyCtrVariate [ enKeyIndex ].u32KeyValidTimeCount < stKeyParameter.u16KeyLongPressTime) )
                {
                    stKeyCtrVariate [ enKeyIndex ].u32KeyValidTimeCount = 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 ].u32KeyValidTimeCount = 0U;
                    /*stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount = 0U;*/
                    stKeyCtrVariate [ enKeyIndex ].enKeyTypeLast = enKeyRealType;
                }
                else
                {
                    if ( stKeyCtrVariate [ enKeyIndex ].u32KeyValidTimeCount < 0xFFFFFFF0U )
                    {
                        stKeyCtrVariate [ enKeyIndex ].u32KeyValidTimeCount += KEY_CALL_CYCLE;
                    }
                    if ( stKeyCtrVariate [ enKeyIndex ].u32KeyValidTimeCount >= stKeyParameter.u16KeyShortPressTime )
                    {
                        stKeyCtrVariate [ enKeyIndex ].u16KeyInvalidTimeCount = 0U;
                    }
                    if ( (stKeyCtrVariate [ enKeyIndex ].u32KeyValidTimeCount >= stKeyParameter.u32KeySuperLongPressTime) )
                    {
                        if ( stKeyAttribute [ enKeyIndex ].pfnKeyOperationCallBack != 0U )
                        {
                            stKeyAttribute [ enKeyIndex ].pfnKeyOperationCallBack(KEY_EVENT_SUPER_LONG_PRESS);
                        }
                    }
                    else if ( (stKeyCtrVariate [ enKeyIndex ].u32KeyValidTimeCount >= stKeyParameter.u16KeyLongPressTime) && (stKeyCtrVariate [ enKeyIndex ].u8KeyLongPressTrigger == 0U) )
                    {
                        if ( stKeyAttribute [ enKeyIndex ].pfnKeyOperationCallBack != 0U )
                        {
                            stKeyAttribute [ enKeyIndex ].pfnKeyOperationCallBack(KEY_EVENT_LONG_PRESS);
                            stKeyCtrVariate [ enKeyIndex ].u8KeyLongPressTrigger = 1U;
                        }
                    }
                }
            }
            else
            {
                /*ERROR*/
                stKeyCtrVariate [ enKeyIndex ].u16KeyInvalidTimeCount = 0U;
                stKeyCtrVariate [ enKeyIndex ].u32KeyValidTimeCount   = 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 ].u32KeyValidTimeCount   = 0U;
        stKeyCtrVariate [ i ].u8KeyLongPressTrigger  = 0U;
    }
    stKeyParameter.u16KeyLoosenTime         = 0U;
    stKeyParameter.u16KeyShortPressTime     = 20U;
    stKeyParameter.u16KeyLongPressTime      = 2000U;
    stKeyParameter.u32KeySuperLongPressTime = 50000U;
}
/*����Ӳ�߰������ԣ��ж϶̰���ʱ�����*/
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.u32KeySuperLongPressTime )
    {
        enKeySetResult = KEY_SET_ERROR;
    }
    else
    {
        stKeyParameter.u16KeyLongPressTime = u16Time;
    }
    return enKeySetResult;
}
/*����Ӳ�߰������ԣ��жϳ�������ʱ�����*/
Key_Set_en_t Key_Parameter_Set_Super_Long_Press_Time(uint32_t u32Time)
{
    Key_Set_en_t enKeySetResult = KEY_SET_OK;
    if ( u32Time < stKeyParameter.u16KeyLongPressTime )
    {
        enKeySetResult = KEY_SET_ERROR;
    }
    else
    {
        stKeyParameter.u32KeySuperLongPressTime = u32Time;
    }
    return enKeySetResult;
}
