
#include "Key.h"

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

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

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

/*-----------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------*/
typedef struct
{
	uint16_t u16KeyShortPressTime;	   /*短按检测时间*/
	uint16_t u16KeyLongPressTime;	   /*长按检测时间*/
	uint16_t u16KeySuperLongPressTime; /*超长按检测时间*/
	uint16_t u16KeyLoosenTime;		   /*松开检测时间*/

} Key_Parameter_st_t;

typedef struct
{
	Key_Real_Status_en_t enKeyTypeLast;
	uint16_t u16KeyInvalidTimeCount;
	uint16_t u16KeyValidTimeCount;

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

static Key_Ctr_st_t stKeyCtrVariate[KEY_NUM_MAX];
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(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 = 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].u16KeyValidTimeCount = 0U;
					stKeyCtrVariate[enKeyIndex].enKeyTypeLast = KEY_LINE_LOOSEN;
				}
				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].u16KeyInvalidTimeCount = 0U;*/
					stKeyCtrVariate[enKeyIndex].enKeyTypeLast = enKeyRealType;
				}
				else
				{
					if (stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount < 0xFFF0U)
					{
						stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount += KEY_CALL_CYCLE;
					}
					if (stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount >= stKeyParameter.u16KeyShortPressTime)
					{
						stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount = 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
			{
				/*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;
	}
	stKeyParameter.u16KeyLoosenTime = 0U;
	stKeyParameter.u16KeyShortPressTime = 50;
	stKeyParameter.u16KeyLongPressTime = 2000U;
	stKeyParameter.u16KeySuperLongPressTime = 30000U;
}
/*对于硬线按键而言，判断短按的时间参数*/
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;
}
