/******************************************************************************
�� �� ����Key.c
����������������⺯�����ļ�
��    �ߣ�����
��    ����V1.0
��    �ڣ�2016.11.21
******************************************************************************/

#include "Key.h"

uint8_t KEY_RIGHT_TURN;     
uint8_t KEY_LEFT_TURN ;   
RotateKeyAttrStruct KeyMenu ;


uint8_t KeyDelaytimer1 ;    //20MS 
uint8_t KeyDelaytimer2 ;    //20MS 

KeyDetectStruct  KeyStatus[KEY_TOTAL_NUMBER];

/******************************************************************************
��������Key_Status_Init
��  �ܣ���ʼ����ת����״̬   
��  ������
����ֵ����
******************************************************************************/
void Key_Status_Init(void)
{
  uint8_t i;
  
  for (i = 0; i < KEY_TOTAL_NUMBER; i++)
  {
    KeyStatus[i].UpdateEnable  = 1;
    KeyStatus[i].Timer         = 0;
    KeyStatus[i].IdleTimer     = 0;
    KeyStatus[i].FinalStatus   = KEY_IDLE;
    KeyStatus[i].CurrentStatus = KEY_IDLE;
  }

}

/******************************************************************************
��������Key_Status_Detect_Service
��  �ܣ�������������,���ڼ�Ⲣ���°�����״̬
��  ������
����ֵ����
******************************************************************************
ע  �⣺�÷���������ÿ20ms������һ��
******************************************************************************/
void Key_Status_Detect_Service(void)
{
  uint8_t   i;
  volatile  uint8_t   *pSig;

  for (i = 0; i < KEY_TOTAL_NUMBER; i++)
  {
    pSig = KeyAttrTable[i].pInputSignal;

    if (*pSig)
    {
      if (KeyStatus[i].Timer < 0xFFFF)
        KeyStatus[i].Timer++;

      switch (KeyAttrTable[i].HoldDetMode)
      {
      case KEY_HOLD_DISABLE     :
        if (KeyAttrTable[i].DoubleDetEn)
        {
          if (KeyStatus[i].IdleTimer)
          {
            KeyStatus[i].CurrentStatus = KEY_DOUBLE;
            if (KeyStatus[i].UpdateEnable)
            {
              KeyStatus[i].FinalStatus  = KEY_DOUBLE;
              KeyStatus[i].UpdateEnable = 0;
            }
          }
          else
            KeyStatus[i].CurrentStatus = KEY_PRESS;
        }
        else
        {
          KeyStatus[i].CurrentStatus = KEY_PRESS;
          if (KeyStatus[i].UpdateEnable)
          {
            KeyStatus[i].FinalStatus  = KEY_PRESS;
            KeyStatus[i].UpdateEnable = 0;
          }
        }
        break;

      case KEY_HOLD_ONLY        :
        if (KeyStatus[i].Timer < KEY_HOLD_THRESHOLD / 20)
        {
          if (KeyStatus[i].IdleTimer)
            KeyStatus[i].CurrentStatus = KEY_DOUBLE;
          else
            KeyStatus[i].CurrentStatus = KEY_PRESS;
        }
        else
        {
          KeyStatus[i].CurrentStatus = KEY_HOLD;
          if (KeyStatus[i].UpdateEnable)
          {
            KeyStatus[i].FinalStatus  = KEY_HOLD;
            KeyStatus[i].UpdateEnable = 0;
          }
        }
        break;

      case KEY_STUCK_ONLY       :
        if (KeyStatus[i].Timer < KEY_STUCK_THRESHOLD / 20)
        {
          if (KeyStatus[i].IdleTimer)
            KeyStatus[i].CurrentStatus = KEY_DOUBLE;
          else
            KeyStatus[i].CurrentStatus = KEY_PRESS;
        }
        else
        {
          KeyStatus[i].CurrentStatus = KEY_STUCK;
          if (KeyStatus[i].UpdateEnable)
          {
            KeyStatus[i].FinalStatus  = KEY_STUCK;
            KeyStatus[i].UpdateEnable = 0;
          }
        }
        break;

      case KEY_HOLD_STUCK       :
        if (KeyStatus[i].Timer < KEY_HOLD_THRESHOLD / 20)
        {
          if (KeyStatus[i].IdleTimer)
            KeyStatus[i].CurrentStatus = KEY_DOUBLE;
          else
            KeyStatus[i].CurrentStatus = KEY_PRESS;
        }
        else if (KeyStatus[i].Timer < KEY_STUCK_THRESHOLD / 20)
        {
          KeyStatus[i].CurrentStatus = KEY_HOLD;
        }
        else
        {
          KeyStatus[i].CurrentStatus = KEY_STUCK;
          if (KeyStatus[i].UpdateEnable)
          {
            KeyStatus[i].FinalStatus  = KEY_STUCK;
            KeyStatus[i].UpdateEnable = 0;
          }
        }
        break;

      case KEY_HOLD_LONG        :
        if (KeyStatus[i].Timer < KEY_HOLD_THRESHOLD / 20)
        {
          if (KeyStatus[i].IdleTimer)
            KeyStatus[i].CurrentStatus = KEY_DOUBLE;
          else
            KeyStatus[i].CurrentStatus = KEY_PRESS;
        }
        else if (KeyStatus[i].Timer < KEY_LONG_THRESHOLD / 20)
        {
          KeyStatus[i].CurrentStatus = KEY_HOLD;
        }
        else
        {
          KeyStatus[i].CurrentStatus = KEY_LONG;
          if (KeyStatus[i].UpdateEnable)
          {
            KeyStatus[i].FinalStatus  = KEY_LONG;
            KeyStatus[i].UpdateEnable = 0;
          }
        }

        break;

      case KEY_HOLD_LONG_STUCK  :
        if (KeyStatus[i].Timer < KEY_HOLD_THRESHOLD / 20)
        {
          if (KeyStatus[i].IdleTimer)
            KeyStatus[i].CurrentStatus = KEY_DOUBLE;
          else
            KeyStatus[i].CurrentStatus = KEY_PRESS;
        }
        else if (KeyStatus[i].Timer < KEY_LONG_THRESHOLD / 20)
        {
          KeyStatus[i].CurrentStatus = KEY_HOLD;
        }
        else if (KeyStatus[i].Timer < KEY_STUCK_THRESHOLD / 20)
        {
          KeyStatus[i].CurrentStatus = KEY_LONG;
        }
        else
        {
          KeyStatus[i].CurrentStatus = KEY_STUCK;
          if (KeyStatus[i].UpdateEnable)
          {
            KeyStatus[i].FinalStatus  = KEY_STUCK;
            KeyStatus[i].UpdateEnable = 0;
          }
        }
        break;

      default                    :
        break;
      }
    }
    else
    {
      if (KeyAttrTable[i].DoubleDetEn)
      {
        if (KeyStatus[i].CurrentStatus == KEY_PRESS)
        {
          if (KeyStatus[i].Timer)
            KeyStatus[i].IdleTimer = KEY_DOUBLE_INTERVAL / 20;
        }
        else
          KeyStatus[i].IdleTimer = 0;

        if (KeyStatus[i].IdleTimer)
          KeyStatus[i].IdleTimer--;
        else
        {
          if ((KeyStatus[i].CurrentStatus != KEY_IDLE) && (KeyStatus[i].UpdateEnable != 0))
            KeyStatus[i].FinalStatus = KeyStatus[i].CurrentStatus;
          KeyStatus[i].CurrentStatus = KEY_IDLE;
          KeyStatus[i].UpdateEnable = 1;
        }
      }
      else
      {
        if ((KeyStatus[i].CurrentStatus != KEY_IDLE) && (KeyStatus[i].UpdateEnable != 0))
          KeyStatus[i].FinalStatus = KeyStatus[i].CurrentStatus;
        KeyStatus[i].CurrentStatus = KEY_IDLE;
        KeyStatus[i].UpdateEnable = 1;
      }
      KeyStatus[i].Timer = 0;
    }
  }
}

/******************************************************************************
��������Reset_Key_Status
��  �ܣ���λijһ�����İ������״̬
��  ����Key����Ҫ��λ�İ���
����ֵ����
******************************************************************************/
void Reset_Key_Status(uint8_t Key)
{
  KeyStatus[Key].UpdateEnable  = 1;
  KeyStatus[Key].Timer         = 0;
  KeyStatus[Key].IdleTimer     = 0;
  KeyStatus[Key].FinalStatus   = KEY_IDLE;
  KeyStatus[Key].CurrentStatus = KEY_IDLE;
}

/******************************************************************************
��������Key_Get_Status
��  �ܣ���ȡijһ�����ļ����
        �����ļ�����ڰ�����״̬���Ա�ȷ��ʱ����
        ���ɴ˺�����ȡ�������,������������Զ������KEY_IDLE״̬
��  ����Key����Ҫ��ȡ����İ���
����ֵ����
******************************************************************************/
KeyStatusEnum Key_Get_Status(uint8_t Key)
{
  KeyStatusEnum   Status;
  Status = KeyStatus[Key].FinalStatus;
  KeyStatus[Key].FinalStatus = KEY_IDLE;
  return Status;
}

/******************************************************************************
��������Key_Get_Current_Status
��  �ܣ���ȡijһ�����ĵ�ǰ״̬
        ���صĽ����ӳ������ǰ������״̬,�����ж�����������״̬,�ڰ�������ijһ
        ״̬������ʱʵʱ�仯Ϊ��״̬(���������ͷź�ָ�ΪKEY_IDLE״̬)
��  ����Key����Ҫ��ȡ״̬�İ���
����ֵ����
******************************************************************************/
KeyStatusEnum Key_Get_Current_Status(uint8_t Key)
{
  return KeyStatus[Key].CurrentStatus;
}
/*****************************************************************************
��������Key_Knob
��  �ܣ���ȡijһ��ť�����ĵ�ǰ״̬
        ���صĽ����ӳ������ǰ������״̬,�����ж�����������״̬,�ڰ�������ijһ
        ״̬������ʱʵʱ�仯Ϊ��״̬()
��  ����KnobSwitch.Key_Step����ǰ��ť�IJ���

����ֵ����
*******************************************************************************/
void RotaryKey_Status_Detect_Service(RotateKeyAttrStruct *KeyMenu)
{	
#if 0
  if(!RotaryKEY0_In1 && !RotaryKEY0_In2)	
	{
	    KeyMenu->RotateState = keep_local;//Ĭ��
	    KeyMenu->RotateValid = 1;
	}
	
	if((RotaryKEY0_In1 && RotaryKEY0_In2)&&(KeyMenu->RotateValid == 1))  
	{
			KeyMenu->RotateValid = 0;
			
			if( KeyMenu->Rotary2Old == 0 ) 
			{
			    KeyDelaytimer1++ ; 
			    KEY_LEFT_TURN = 1 ;
			}   
			else if( KeyMenu->Rotary1Old == 0 ) 
			{
			    KeyDelaytimer2++ ;    
			    KEY_RIGHT_TURN = 1; 
			}
	}
	KeyMenu->Rotary1Old = RotaryKEY0_In1;
	KeyMenu->Rotary2Old = RotaryKEY0_In2;  	
#endif				   
}