/*********************************************************************************************************
*
*********************************************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "delay.h"
#include "nrf_delay.h"
#include "button.h"
#include "power.h"
#include "rotation.h"
#include "wireless.h"
//#include "led.h"
#include "bsp.h"

//#include "ledGam.h"
#if KEY_SWITCH_MODE == KEY_SWITCH_SEPERATE_MOD
#endif
//#include "trackGam.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
uint8_t convertKeyNumToMotion(KEY_NUM_ENUM key_num, uint8_t *pin_no);
void init_BTN_DET_TIMEOUT_STRUCT(void);
//根据按钮计时判断按钮类型：短按、长按、其它
//button_action		:按钮动作输出
uint8_t judge_button_type_by_times(uint16_t times, uint8_t *button_action);



/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
ROLL_DETECT_QUEUE_STRUCT btnDetQue;
static uint8_t button_action_all_now[KEY_NUM_MAX];		//存储所有按钮最新状态
static uint8_t button_action_all_last[KEY_NUM_MAX];		//存储所有按钮上一次状态

BTN_DET_TIMEOUT_STRUCT btn_det_timeout;					/*按键超时控制数据结构*/


/************************************************************************************/
void clear_button_action_all(void)
{
	u16 i = 0;
	for(i = 0; i < KEY_NUM_MAX; i++)
	{
		button_action_all_now[i] = BSP_BUTTON_ACTION_RELEASE;
		button_action_all_last[i] = BSP_BUTTON_ACTION_RELEASE;
	}
}

uint8_t get_button_action_now(KEY_NUM_ENUM pin_no, uint8_t *button_action)
{
	if((pin_no >= KEY_NUM_MAX)||(pin_no <= KEY_NUM_MIN))
	{
		return false;
	}
	*button_action = button_action_all_now[pin_no];
	return true;
}

void init_general_key_button(void)
{
    //配置6个普通功能按钮输入
    nrf_gpio_cfg_input(KEY_MOTION_1, NRF_GPIO_PIN_PULLUP);
    nrf_gpio_cfg_input(KEY_MOTION_2, NRF_GPIO_PIN_PULLUP);
    nrf_gpio_cfg_input(KEY_MOTION_3, NRF_GPIO_PIN_PULLUP);
    nrf_gpio_cfg_input(KEY_MOTION_4, NRF_GPIO_PIN_PULLUP);
    nrf_gpio_cfg_input(KEY_MOTION_5, NRF_GPIO_PIN_PULLUP);
    nrf_gpio_cfg_input(KEY_MOTION_6, NRF_GPIO_PIN_PULLUP);
}

void uninit_general_key_button(void)
{
    //配置6个普通功能按钮输出
    //nrf_gpio_cfg_output(KEY_MOTION_1);
    nrf_gpio_cfg_output(KEY_MOTION_2);
    nrf_gpio_cfg_output(KEY_MOTION_3);
    nrf_gpio_cfg_output(KEY_MOTION_4);
    nrf_gpio_cfg_output(KEY_MOTION_5);
    nrf_gpio_cfg_output(KEY_MOTION_6);
	
    //低电平
    //nrf_gpio_pin_clear(KEY_MOTION_1);
    nrf_gpio_pin_clear(KEY_MOTION_2);
    nrf_gpio_pin_clear(KEY_MOTION_3);
    nrf_gpio_pin_clear(KEY_MOTION_4);
    nrf_gpio_pin_clear(KEY_MOTION_5);
    nrf_gpio_pin_clear(KEY_MOTION_6);
	
}

/**@brief Function for general button configuration.
 *
 * @param[in] void.
 */
void init_general_button(void)
{	
	init_general_key_button();
	
	// Configure KEY_MOTION_1 with SENSE enabled 
    nrf_gpio_cfg_sense_input(KEY_MOTION_1, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
    nrf_gpio_cfg_sense_input(PWR_MOTION_CHRG, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
    nrf_gpio_cfg_sense_input(PWR_MOTION_STDBY, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
}



//检测开机按钮状态是否为按下状态，如果不是，则强制关机
void detect_bootup_key_status(void)
{
	if((0 != nrf_gpio_pin_read(KEY_MOTION_1)) && (0 != nrf_gpio_pin_read(PWR_MOTION_CHRG)))
	{
		//enterSystemOff();  //test
	}
}

//初始化按钮缓冲队列
void init_general_button_queue(void)
{
	//初始化按键缓冲队列
	InitRollDetQue(&btnDetQue);
	
	init_BTN_DET_TIMEOUT_STRUCT();
	
	clear_button_action_all();
	
}

uint8_t keyMotionToU8(uint8_t pin, uint8_t button_action)
{
	return ( ((pin & 0x0F) << 4) | (0x0F & button_action) );
}

uint8_t keyMotionFromU8(uint8_t key_str, uint8_t *pin, uint8_t *button_action)
{
	if((NULL == pin) || (NULL == button_action))
	{
		return false;
	}
	*pin = (key_str & 0xF0) >> 4;
	*button_action = key_str & 0x0F;
	return true;
}

void init_BTN_DET_TIMEOUT_STRUCT(void)
{
	uint16_t i = 0;
	
	for(i=0; i<KEY_NUM_MAX; i++)
	{
		btn_det_timeout.cnt_ctl[i].flag = false;
		btn_det_timeout.cnt_ctl[i].cnt = 0;
		btn_det_timeout.cnt_ctl[i].cntMax = BTN_DETECT_TIMEOUT;
		btn_det_timeout.finish_flag[i] = false;
		btn_det_timeout.timeout_flag[i] = false;
	}
}

/**@brief Function for handling events from the general button handler module.
 *
 * @param[in] void.
 */
void general_button_event_detect(void)
{
	uint8_t button_action = BSP_BUTTON_ACTION_RELEASE;
	uint8_t pin_no = 254;
	KEY_NUM_ENUM key_num = KEY_NUM_MIN;
	
	for(int i=0;i<KEY_NUM_MAX;i++)
	{
		//--------------------------------------------------------
		key_num = (KEY_NUM_ENUM)i;
		if(false == convertKeyNumToMotion(key_num, &pin_no)) //将枚举转换为实际IO管脚编号
		{
			continue;
		}
		button_action = BSP_BUTTON_ACTION_RELEASE;
		
		//--------------------------------------------------------
		//获取按键IO状态
		if(0 == GET_PIN_IN_STATUS(pin_no))
		{
			//nrf_delay_ms(10);
			//delay_ms_cle(1);
			if(0 == GET_PIN_IN_STATUS(pin_no))
			{
				button_action = BSP_BUTTON_ACTION_PUSH;
			}
			else
			{
				button_action = BSP_BUTTON_ACTION_RELEASE;
			}
		}
		else
		{
			button_action = BSP_BUTTON_ACTION_RELEASE;
		}
		
		//特殊需要，针对需一直检测的按钮，不论状态是否变化，例如充电中、充电满按钮
		if(BSP_BUTTON_ACTION_PUSH == button_action)
		{
			//充电中或充电满状态有效
			if((KEY_NUM_CHRG == key_num)||(KEY_NUM_STDBY == key_num))
			{
				disAllowSystemOff();				//充电中或充电满，不允许定时关机
			}
		}
		
		//状态未变化，跳过
		if(button_action == button_action_all_last[key_num])
		{
			continue;
		}
		
		button_action_all_last[key_num] = button_action;     	//更新上次按键状态
		
		//--------------------------------------------------------
		if(BSP_BUTTON_ACTION_PUSH == button_action)
		{
			//充电中允许充电闪烁提示灯
			if((KEY_NUM_CHRG == key_num))
			{
				allowChargingLedShining_EN_Flag = true;			//允许充电中闪烁led开始闪烁
			}
			
			//第一次按下，使能计数
			btn_det_timeout.cnt_ctl[key_num].flag = true;
			btn_det_timeout.cnt_ctl[key_num].cnt = 0;
			btn_det_timeout.finish_flag[key_num] = false;
			btn_det_timeout.timeout_flag[key_num] = false;
			disAllowSystemOff();					//有按键活动，不允许定时关机
			
		}
		else if(BSP_BUTTON_ACTION_RELEASE == button_action)
		{
			//充电完成禁止充电闪烁提示灯
			if((KEY_NUM_CHRG == key_num))
			{
				allowChargingLedShining_EN_Flag = false;		//禁止充电中闪烁led开始闪烁
			}
			
			btn_det_timeout.cnt_ctl[key_num].flag = false;  //超时松开、正常松开则停止计数
			//释放按钮，判断按钮类型
			if(btn_det_timeout.cnt_ctl[key_num].cnt >= btn_det_timeout.cnt_ctl[key_num].cntMax)
			{
				//超时松开，不处理
				btn_det_timeout.finish_flag[key_num] = false;
				btn_det_timeout.timeout_flag[key_num] = true;
			}
			else
			{
				btn_det_timeout.finish_flag[key_num] = true;
				btn_det_timeout.timeout_flag[key_num] = false;
				//正常松开按钮，根据按下时常判断按钮类型
				//btn_det_timeout.cnt_ctl[key_num].cnt = 0;
			}
		}
		
	}
}

void cycle_add_btn_det_timeout(void)
{
	uint16_t i = 0;
	uint8_t button_action = BSP_BUTTON_ACTION_RELEASE;
	KEY_NUM_ENUM key_num = KEY_NUM_MIN;
	
	for(i=0; i<KEY_NUM_MAX; i++)
	{
		button_action = BSP_BUTTON_ACTION_RELEASE;
		//--------------------------------------------------------
		key_num = (KEY_NUM_ENUM)i;
		
		//允许计数
		if(true == btn_det_timeout.cnt_ctl[key_num].flag)
		{
			btn_det_timeout.cnt_ctl[key_num].cnt++;
			if(btn_det_timeout.cnt_ctl[key_num].cnt > btn_det_timeout.cnt_ctl[key_num].cntMax)
			{
				btn_det_timeout.cnt_ctl[key_num].cnt = btn_det_timeout.cnt_ctl[key_num].cntMax;
			}
		}
		
		if((true == btn_det_timeout.finish_flag[key_num])||(true == btn_det_timeout.timeout_flag[key_num]))
		{
			//根据按下时间判断按钮动作类型
			if(false == judge_button_type_by_times(btn_det_timeout.cnt_ctl[key_num].cnt, &button_action))
			{
				continue;
			}
			
			//--------------------------------------------------------
			//按键有效动作处理（按钮正常松开、按钮长按超时）
			if((BSP_BUTTON_ACTION_LONG_PUSH == button_action)||(BSP_BUTTON_ACTION_PUSH == button_action))
			{
				//压入按键缓冲队列
				PutRollDetQue(&btnDetQue, 0, (u8 *)&i, (u16 *)&button_action, 1);
				btn_det_timeout.finish_flag[key_num] = false;
			}
		}
	}
}

//根据按钮计时判断按钮类型：短按、长按、其它
//button_action		:按钮动作输出
uint8_t judge_button_type_by_times(uint16_t times, uint8_t *button_action)
{
	uint8_t rtn_flag = true;
	if(times < BTN_PUSH_TIMEOUT)					//小于1s的属于短按
	{
		*button_action = BSP_BUTTON_ACTION_PUSH;  				//短按
	}
	else if(times <= BTN_LONG_PUSH_TIMEOUT)			//小于等于12s的属于长按
	{
		*button_action = BSP_BUTTON_ACTION_LONG_PUSH;  			//长按
	}
	else if(BTN_DETECT_TIMEOUT == times)			//持续长按
	{
		*button_action = BSP_BUTTON_ACTION_KEEP_LONG_PUSH;  	//持续长按
	}
	else
	{
		rtn_flag = false;
	}
	return rtn_flag;
}

uint8_t convertKeyNumToMotion(KEY_NUM_ENUM key_num, uint8_t *pin_no)
{
	uint8_t rtn_flag = true;
	switch(key_num)
	{
		case KEY_NUM_1    : *pin_no = KEY_MOTION_1     ; break;
		case KEY_NUM_2    : *pin_no = KEY_MOTION_2     ; break;
		case KEY_NUM_3    : *pin_no = KEY_MOTION_3     ; break;
		case KEY_NUM_4    : *pin_no = KEY_MOTION_4     ; break;
		case KEY_NUM_5    : *pin_no = KEY_MOTION_5     ; break;
		case KEY_NUM_6    : *pin_no = KEY_MOTION_6     ; break;
		case KEY_NUM_CHRG : *pin_no = PWR_MOTION_CHRG  ; break;
		case KEY_NUM_STDBY: *pin_no = PWR_MOTION_STDBY ; break;
		default:rtn_flag = false;break;
	}
	
	return rtn_flag;	
}


/**@brief Function for cycle process general button actions.
 *
 * @param[in] void.
 */
uint8_t cycleProcessKeyMotion(void)
{
	uint8_t button_action = BSP_BUTTON_ACTION_RELEASE;
	KEY_NUM_ENUM key_num = KEY_NUM_MIN;
	uint8_t rtn_flag = true;
	uint16_t i = 0, btnQueueLen = 0;
	u32 time = 0;
	
	btnQueueLen = GetRollDetQueLen(&btnDetQue);
	if(0 == btnQueueLen)
	{
		return false;
	}
		
	for(i = 0;i < btnQueueLen; i++)
	{
		if(false == GetRollDetQue(&btnDetQue, &time, (u8 *)&key_num, (u16 *)&button_action))
		{
			continue;
		}
		if(KEY_NUM_MIN == key_num)
		{
			continue;
		}
		button_action_all_now[key_num] = button_action;  //全局存储所有按键状态
		
		sprintf((char *)debug_str, "pin=%d action=%d \n",key_num, button_action);
		debug_print_wifi(debug_str);
		
		//process task of diff pin status
		if(BSP_BUTTON_ACTION_PUSH == button_action)				//处理按键短按
		{
			switch(key_num)
			{
			case KEY_NUM_1    :  //R
#if KEY_SWITCH_MODE == KEY_SWITCH_SEPERATE_MODE
				switch_game_specific(GAM_NUM_teach_led);
#endif
				break;
			case KEY_NUM_2    :  //F
				break;
			case KEY_NUM_3    :  //U
#if KEY_SWITCH_MODE == KEY_SWITCH_SERIAL_MODE || KEY_SWITCH_MODE == KEY_SWITCH_SEPERATE_MODE
//				init_game_first();		//切换游戏关
#endif
				break;
			case KEY_NUM_4    :  //L
#if KEY_SWITCH_MODE == KEY_SWITCH_SERIAL_MODE
//				switch_game();			//切换游戏
#elif KEY_SWITCH_MODE == KEY_SWITCH_SEPERATE_MODE
				switch_game_specific(GAM_NUM_eat_led);
#endif
				break;
			case KEY_NUM_5    :  //B
				//leave_standby_mode();
				break;
			case KEY_NUM_6    :  //D
				break;
			case KEY_NUM_CHRG :
				detectChargePinStatus();	//充电状态检测
				break;
			case KEY_NUM_STDBY:  
				detectChargePinStatus();	//充电状态检测
				break;
			default:
				rtn_flag = false;
				break;
			}
		}
		else if(BSP_BUTTON_ACTION_RELEASE == button_action)		//处理按键释放
		{
			switch(key_num)
			{
			case KEY_NUM_1    :  //R
				break;
			case KEY_NUM_2    :  //F
				break;
			case KEY_NUM_3    :  //U
				break;
			case KEY_NUM_4    :  //L
				break;
			case KEY_NUM_5    :  //B
				break;
			case KEY_NUM_6    :  //D
				break;
			case KEY_NUM_CHRG :  
				detectChargePinStatus();	//充电状态检测
				break;
			case KEY_NUM_STDBY:  
				detectChargePinStatus();	//充电状态检测
				break;
			default:
				rtn_flag = false;
				break;
			}
		}
		else if(BSP_BUTTON_ACTION_LONG_PUSH == button_action)	//处理按键长按
		{
			switch(key_num)
			{
			case KEY_NUM_1    :  //R
				do_power_key_press();			
				break;
			case KEY_NUM_2    :  //F
				break;
			case KEY_NUM_3    :  //U
				break;
			case KEY_NUM_4    :  //L
				break;
			case KEY_NUM_5    :  //B
//				updateAndCalibrateAllCubeCellColor("YYYYYYYYY|RRRRRRRRR|WWWWWWWWW|OOOOOOOOO|BBBBBBBBB|GGGGGGGGG", 59);
				break;
			case KEY_NUM_6    :  //D
#if KEY_SWITCH_MODE == KEY_SWITCH_SEPERATE_MODE
				switch_display_all_white_cell_leds();
#endif
				break;
			case KEY_NUM_CHRG :  
				break;
			case KEY_NUM_STDBY:  
				break;
			default:
				rtn_flag = false;
				break;
			}
		}
	}
	
	return rtn_flag;
}

volatile bool m_chrg_button_action_Flag = false;
volatile bool m_stdby_button_action_Flag = false;

/**@brief Function for cycle detect charging button actions.
 *
 * @param[in] void.
 */
void detectChargePinStatus(void)
{
	uint8_t chrg_button_action = BSP_BUTTON_ACTION_RELEASE;
	uint8_t stdby_button_action = BSP_BUTTON_ACTION_RELEASE;
	KEY_NUM_ENUM pin_no = KEY_NUM_MIN;
	PWR_CHARGE_MODE_ENUM chg_mod = PWR_CHARGE_MODE_MIN;
	
	//获取充电IO检测状态
	pin_no = KEY_NUM_CHRG;
	if(false == get_button_action_now(pin_no, &chrg_button_action))
	{
		return;
	}
	pin_no = KEY_NUM_STDBY;
	if(false == get_button_action_now(pin_no, &stdby_button_action))
	{
		return;
	}
	
	//充电状态判断及对应处理
	if((BSP_BUTTON_ACTION_PUSH == chrg_button_action)&(BSP_BUTTON_ACTION_RELEASE == stdby_button_action))
	{
		//充电中
		chg_mod = PWR_CHARGE_MODE_DOING;
	}
	else if((BSP_BUTTON_ACTION_PUSH == chrg_button_action)&(BSP_BUTTON_ACTION_PUSH == stdby_button_action))
	{
		//充电满
		chg_mod = PWR_CHARGE_MODE_FINISH;
	}
	else if((BSP_BUTTON_ACTION_RELEASE == chrg_button_action)&(BSP_BUTTON_ACTION_PUSH == stdby_button_action))
	{
		//充电满
		chg_mod = PWR_CHARGE_MODE_FINISH;
	}
	else if((BSP_BUTTON_ACTION_RELEASE == chrg_button_action)&(BSP_BUTTON_ACTION_RELEASE == stdby_button_action))
	{
		//充电器拔出
		chg_mod = PWR_CHARGE_MODE_CACEL;
	}
	//else if((BSP_BUTTON_ACTION_PUSH == chrg_button_action)&(BSP_BUTTON_ACTION_PUSH == stdby_button_action))
	//{
	//	//电池反接，报错
	//	chg_mod = PWR_CHARGE_MODE_BATERR;
	//}
	
	doChargeDoingKeyMotion(&chg_mod);
}


/*********************************************end of file*********************************************/
