#include "u_app_handler.h"
#include "u_main.h"
#include "u_time.h"
#include "u_ble.h"
#include "u_light_ctrl.h"
#include "u_effect_normal.h"
#include "u_effect_color.h"
#include "u_effect_rhythm.h"
#include "user_driver.h"
#include "LH_TaskManager.h"


uint32_t 	m_clr_play_buff[APP_MODE_CLR_MAX_NUM] 		= {0x00};

void light_state_upload(void)            //�ط��Ƶ�״̬��app
{
	uint8_t upload_buff[14] = {0};
	
	if(g_light_para.power_st == GLO_EN)		  //�Ƶ�ǰ�Ƿ񿪹�
	{
		upload_buff[0] = 1;
	}
	else
	{
		upload_buff[0] = 0;
	}
	
	if (g_light_para.app_mode[0] >= LIGHT_APP_MODE_RC_MIN)
	{
		upload_buff[1] = LIGHT_APP_MODE_COLORUR;
	}
	else
	{
		upload_buff[1] = g_light_para.app_mode[0]; //�Ƶ�ǰ��ģʽ
		upload_buff[2] = g_light_para.app_mode[1];
	}
	
	               
	upload_buff[3] = g_light_para.bright;       //�Ƶ�ǰ������
	upload_buff[4] = g_light_para.app_speed;//���ٶ�
	upload_buff[5] = 100 - g_light_para.rhythm_sensit * APP_SENSIT_K;           
	upload_buff[6] = g_light_para.clr_temp[0];
	upload_buff[7] = g_light_para.clr_temp[1];
	upload_buff[8] = g_light_para.clr_temp[2];
	upload_buff[9] = g_light_para.clr_temp[3];
	upload_buff[10] = g_light_para.rgb_order[0];
	upload_buff[11] = g_light_para.rgb_order[1];
	upload_buff[12] = g_light_para.rgb_order[2];
	upload_buff[13] = 0x00;
	//UART_PRINTF("user_send_light_state %d %d %d\r\n",Rgb_Para.color_arr[10],Rgb_Para.color_arr[11],Rgb_Para.color_arr[12]);
	reply_app_encode(0x10, upload_buff, 14);
}

static void app_light_colour_enter(const uint32_t *static_clr, uint8_t static_bright)
{
	u_rhythm_timer_ctrl(GLO_DIS);
	light_mode_static_cfg(&g_light_info, static_clr, static_bright);

}

static void app_rhythm_enter(uint8_t *app_mode)
{
	if (app_mode[0] == APP_RHYTHM_MODE_MUSIC)
	{
		light_rhythm_enter(RHYTHM_MODE_GRADUAL_7);
	}
	else
	{
		switch (app_mode[1])
		{
			case APP_RHYTHM_MODE_FADE3:
			{
				light_rhythm_enter(RHYTHM_MODE_FADE_3);
			}
				break;
			case APP_RHYTHM_MODE_FADE7:
			{
				light_rhythm_enter(RHYTHM_MODE_FADE_7);
			}
				break;		
			case APP_RHYTHM_MODE_JUMP3:
			{
				light_rhythm_enter(RHYTHM_MODE_JUMP_3);
			}
				break;
			case APP_RHYTHM_MODE_JUMP7:
			{
				light_rhythm_enter(RHYTHM_MODE_JUMP_7);
			}
				break;			
		}
	}
}

void light_mode_set(uint8_t *app_mode)
{
	
	memcpy(g_light_para.app_mode, app_mode, 2);
	switch (g_light_para.app_mode[0])
	{
		case LIGHT_APP_MODE_WHITE_LIGHT:
		case LIGHT_APP_MODE_COLORUR:
		{
			clr_format_transition(CLR_TS_TYPE_8_32, 1, g_light_para.clr_temp, m_clr_play_buff);
			app_light_colour_enter(m_clr_play_buff, g_light_para.bright);
		}
			break;
		case LIGHT_APP_MODE_S_RED:
		case LIGHT_APP_MODE_S_BLUE:
		case LIGHT_APP_MODE_S_GREEN:
		case LIGHT_APP_MODE_S_CYAN:
		case LIGHT_APP_MODE_S_YELLOW:
		case LIGHT_APP_MODE_S_PURPLE:
		case LIGHT_APP_MODE_S_WHITE:
		{
			uint8_t clr_ind = g_light_para.app_mode[0] - LIGHT_APP_MODE_S_RED;
			light_mode_static_cfg(&g_light_info, &app_static_clr[clr_ind], g_light_para.bright);
		}
			break;
		
		case LIGHT_APP_MODE_JUMP_3:
		{
			light_mode_jump_cfg(&g_light_info, base_clr, 3, g_light_para.speed, g_light_para.bright);
		}
			break;
		case LIGHT_APP_MODE_JUMP_7:
		{
			light_mode_jump_cfg(&g_light_info, base_clr, 7, g_light_para.speed, g_light_para.bright);
		}
			break;
		case LIGHT_APP_MODE_FADE_3:
		{
			light_mode_gradual_cfg(&g_light_info, base_clr, 3, g_light_para.speed, g_light_para.bright);
		}
			break;
		case LIGHT_APP_MODE_FADE_7:
		{
			light_mode_gradual_cfg(&g_light_info, base_clr, 7, g_light_para.speed, g_light_para.bright);
		}
			break;
		
		case LIGHT_APP_MODE_BREATH_RED:
		case LIGHT_APP_MODE_BREATH_BLUE:
		case LIGHT_APP_MODE_BREATH_GREEN:
		case LIGHT_APP_MODE_BREATH_YELLOW:
		case LIGHT_APP_MODE_BREATH_CYAN:
		case LIGHT_APP_MODE_BREATH_PURPLE:
		case LIGHT_APP_MODE_BREATH_WHITE:
		{
			uint8_t clr_ind = g_light_para.app_mode[0] - LIGHT_APP_MODE_BREATH_RED;
			light_mode_breath_cfg(&g_light_info, &base_clr[clr_ind], 1, g_light_para.speed, g_light_para.bright);

		}
			break;	

		case LIGHT_APP_MODE_FADE_RG:
		{
			light_mode_gradual_cfg(&g_light_info, base_clr, 2, g_light_para.speed, g_light_para.bright);
		}
			break;
		case LIGHT_APP_MODE_FADE_RB:
		{
			light_mode_gradual_cfg(&g_light_info, app_static_clr, 2, g_light_para.speed, g_light_para.bright);
		}
			break;
		case LIGHT_APP_MODE_FADE_GB:
		{
			light_mode_gradual_cfg(&g_light_info, &base_clr[1], 2, g_light_para.speed, g_light_para.bright);
		}
			break;			
	
		case LIGHT_APP_MODE_BLINK_7:
		{
			light_mode_blink_cfg(&g_light_info, base_clr, 7, 5, g_light_para.speed, g_light_para.bright);
		}
		break;
		case LIGHT_APP_MODE_BLINK_RED:
		case LIGHT_APP_MODE_BLINK_GREEN:
		case LIGHT_APP_MODE_BLINK_BLUE:
		case LIGHT_APP_MODE_BLINK_YELLOW:
		case LIGHT_APP_MODE_BLINK_CYAN:
		case LIGHT_APP_MODE_BLINK_PURPLE:
		case LIGHT_APP_MODE_BLINK_WHITE:
		{
			uint8_t clr_ind = g_light_para.app_mode[0] - LIGHT_APP_MODE_BLINK_RED;
			light_mode_blink_cfg(&g_light_info, &base_clr[clr_ind], 1, 5, g_light_para.speed, g_light_para.bright);

		}
		break;
		case LIGHT_APP_MODE_RHYTHM_APP:
		case LIGHT_APP_MODE_RHYTHM_MUSIC:
		{
			app_rhythm_enter(app_mode);
		}
		break;
		
	}
	
}

static void app_mode_enter(uint8_t *app_mode)
{
	light_mode_set(app_mode);
}

void reply_app_encode(uint8_t cmd, uint8_t *data, uint8_t len)  //�ط�app��������
{
	static uint8_t send[64]={0};
	uint8_t i;
	uint16_t crc;

	send[0] = 0xA1;
	send[1] = cmd;
	send[2] = len + 3;
	for(i = 0; i<len; i++)
	{
		send[3+i] = data[i];
	}
	
	crc = crc_16(send, len +3);
	send[3+len] = crc & 0xff;
	send[4+len] = crc >> 8;
	//UART_PRINTF("crc: %x\r\n", crc);
#if 1
	U_UART_PRINTF("\r\ntx:");
	for(i = 0; i < len + 5; i++)
	{
		U_UART_PRINTF("%02X ", send[i]);
	}
	U_UART_PRINTF("\r\n");
#endif
	u_ble_data_send(send, len + 5);
}
int PrintfOut(void)
{
  U_UART_PRINTF("\r\nTimer is:%d %d\r\n",sys_time_handle.get_run_ticks(),g_light_para.rebootCnt);
}
//app�·����ݵĴ������� 
void decode_app_cmd(uint8_t cmd, uint8_t *data, uint8_t len)
{
	static uint8_t xx = 0, yy = 0;
	uint8_t reply_state;
	#if 0
	//UART_PRINTF("app cmd: 0x%x, %d\r\n", cmd, len);
	UART_PRINTF("app cmd: %02x, %02x %02x\r\n",data[0],data[1],data[2]);
	#endif
	switch(cmd)
	{
		case 0x00:   //����ָ��
		{
			if(memcmp(&data[0], "CCHIP", 5) == 0)
			{
				uint8_t str[7] = "CCHIP";

				xx = HW_Get_Native_Clk_Avoid_Race() % 8;
				yy = HW_Get_Native_Clk_Avoid_Race() /100 % 8;
				str[5] = xx;
				str[6] = yy;
				reply_app_encode(0x00, str, 7);
				U_UART_PRINTF("check device1: %02x,%02x\r\n", xx, yy);
			}
		}
		break;
		case 0x01:  //����ָ��
		{
			if(memcmp(&data[0], "CCHIP", 5) == 0)
			{
				uint8_t send[6] = "CCHIP";
				U_UART_PRINTF("check device2: %02x,%02x, %02x,%02x\r\n", (xx^36),data[5],(yy^63+13)&0xff,data[6]);
				if((((xx^36) &0xff) == data[5]) && (((yy^63+13) &0xff) == data[6]))
				{
					send[5] = 0x00;
					reply_app_encode(0x01, send, 6);
					//user_connect();
					U_UART_PRINTF("check ok\r\n");
				}
				else
				{
					send[5] = 0x01;
					reply_app_encode(0x01, send, 6);
					U_UART_PRINTF("check error\r\n");
				}
			}
		}
		break;
		
	
		case 0x10:    //��ȡ�����Ե�ָ��
		{
			light_state_upload();
		}
		break;
		case 0x11:   //���õƿ��ص�ָ��
		{
			U_UART_PRINTF("light_power_st = %d\r\n", data[0]);
			light_power_set(data[0]);
			reply_state = 1;
			reply_app_encode(cmd, &reply_state, 1);
		}
		break;	

		case 0x12:   //���õ�ģʽ
		{
			reply_state = 1;
			reply_app_encode(cmd, &reply_state, 1);
			U_UART_PRINTF("\r\n app_mode = %X, app_effect = %X\r\n",data[0], data[1]);
			app_mode_enter(data);
			light_power_set(g_light_para.power_st);
		}
		break;
		case 0x13:   //���õ�����
		{
			//data[0] bright
			light_bright_ctrl(data[0]);
			reply_state = 1;
			reply_app_encode(cmd, &reply_state, 1);
			
		}
		break;
		case 0x15:	//���õ���ɫ
		{
			memcpy(g_light_para.clr_temp, &data[0], 4);
			reply_state = 0x01;
			reply_app_encode(cmd, &reply_state, 1);
			
			clr_format_transition(CLR_TS_TYPE_8_32, 1, g_light_para.clr_temp, m_clr_play_buff);
			app_light_colour_enter(m_clr_play_buff, g_light_para.bright);
			g_light_para.app_mode[0]  	= LIGHT_APP_MODE_COLORUR;
			light_power_set(g_light_para.power_st);
		}
		break;
		case 0x16:   //���õ��ٶ�
		{
			//data[0] speed
			light_speed_ctrl(data[0]);
			reply_state = 1;
			reply_app_encode(cmd, &reply_state, 1);
			
		}
		break;
		case 0x17:  //�����ɶ�������
		{
			rhythm_sensit_ctrl(NULL, data[0]);
			reply_state = 1;
			reply_app_encode(cmd, &reply_state, 1);
		}
		break;
		case 0x18:	//����RGB����
		{
			memcpy(g_light_para.rgb_order, data, 3);
			rgb_line_order_check();
			light_power_set(g_light_para.power_st);
			reply_state = 1;
			reply_app_encode(cmd, &reply_state, 1);
		}
		break;
		case 0x19:  //���ð׹�
		{
			reply_state = 1;
			reply_app_encode(cmd, &reply_state, 1);
		}
		break;
		case 0x1A:  //�����ɶ� ��ɫ&����
		{
			
		}
		break;
		case 0x20:  //�׹���ɫ&ɫ��
		{
			memcpy(g_light_para.clr_temp, data, 4);
			reply_state = 1;
			reply_app_encode(cmd, &reply_state, 1);
			
			clr_format_transition(CLR_TS_TYPE_8_32, 1, g_light_para.clr_temp, m_clr_play_buff);
			app_light_colour_enter(m_clr_play_buff, g_light_para.bright);
			g_light_para.app_mode[0]  	= LIGHT_APP_MODE_COLORUR;
		}
		break;
		case 0x21:  //�ɶ���ʼ&��ͣ
		{
			u_rhythm_timer_ctrl(data[0]);
			reply_state = 1;
			reply_app_encode(cmd, &reply_state, 1);
		}
		break;
		case 0x28:  //��ȡ����
		{
			uint8_t reply_buff[2] = {0x00};
			
			reply_buff[0] = g_light_para.app_seting >> 4;
			reply_buff[1] = g_light_para.app_seting & 0x0F;
			reply_app_encode(cmd, reply_buff, 2);
		}
		break;
		case 0x29:  //��������״̬
		{
			g_light_para.app_seting = (data[0] << 4) | (g_light_para.app_seting & 0x0F);
			
			reply_state = 0x01;
			reply_app_encode(cmd, &reply_state, 1);
		}
		break;
		case 0x2A:  //���öϿ�״̬
		{
			g_light_para.app_seting = (g_light_para.app_seting & 0xF0) | (data[0] & 0x0F);
			
			reply_state = 0x01;
			reply_app_encode(cmd, &reply_state, 1);
		}
		break;

		case 0x31:   //ͬ����ǰ��ʱ��
		{
			time_app_driver_sync(data);
			reply_state = 1;
			reply_app_encode(cmd, &reply_state, 1);
		}
		break;
		case 0x34:  //���ӵ�����
		{
			time_alarm_set(data);
			reply_state = 1;
			reply_app_encode(cmd, &reply_state, 1);
		}
		break;
		case 0x35:   //��ȡ���ӵ�״̬ 
		{
			uint8_t reply_len = 0, alarm_st[24] = {0x00};
			time_alarm_state_query(alarm_st, &reply_len);
			reply_app_encode(cmd, alarm_st, reply_len);
		}
		break;
		case 0x51:  //�ɶ�ֵ
		{ 
			app_rhythm_val_up(data[0]);
			reply_state = 1;
			reply_app_encode(cmd, &reply_state, 1);
		}
		break;
		case 0x41:  //��ȡ�汾��
		{ 
			uint8_t temp[] = "1.1.1";
			reply_app_encode(0x41, temp, sizeof(temp) - 1);
		}
		break;
		
		case 0xFD:
		{
			g_light_para.rebootCnt=0;
			U_UART_PRINTF("\r\nErase save Count \r\n");
			light_info_save();
		}
		break;
		
		case 0xFE:
		{
			U_UART_PRINTF("\r\nTimer_Start\r\n");
			UserTimerTask_Create(PrintfOut,2000);
		}
		break;
		
	}
	light_info_save_set();//���ñ����־λ
}