/********************************************************************
 *                Copyright Simcom(shanghai)co. Ltd.                   *
 *---------------------------------------------------------------------
 * FileName      :   app_demo_inputmethod.c
 * version       :   0.10
 * Description   :   
 * Authors       :   maobin
 * Notes         :
 *---------------------------------------------------------------------
 *
 *    HISTORY OF CHANGES
 *---------------------------------------------------------------------
 *0.10  2012-09-24, maobin, create originally.
 *
 *--------------------------------------------------------------------
 * File Description
 * AT+CEAT=parma1,param2
 * param1 param2 
 *   1      1    Test millisecond level timer, Start timer1 timer2 timer3
 *   1      2    Stop timer1, timer2, timer3
 *
 *   2      1    Test microsecond level timer, Start gpt timer
 *   2      2    Stop gpt timer
 *   
 *   3      1    Get elapsed time from the boot to the present
 *   3      2    Get time interval with the last time
 *
 *   4      1    Test RTC, get current rtc value
 *   4      2    Set rtc value
 *
 *--------------------------------------------------------------------
 ********************************************************************/
/********************************************************************
 * Include Files
 ********************************************************************/
#include <string.h>
#include <stdio.h>
#include "eat_modem.h"
#include "eat_interface.h"
#include "eat_uart.h"
#include "eat_timer.h" 
#include "eat_inputmethod.h"

/********************************************************************
 * Macros
 ********************************************************************/
#define EAT_IME_CONVERT_ERROR 0xFF
#define INPUT_EXIT 13000
/********************************************************************
 * Types
 ********************************************************************/
typedef void (*app_user_func)(void*);
/********************************************************************
 * Extern Variables (Extern /Global)
 ********************************************************************/
 
/********************************************************************
 * Local Variables:  STATIC
 ********************************************************************/
static IME_KEY_MAP g_ime_customer_key_map_table[] = 
{
	{EAT_KEY_C2R4, WDK_NORMAL_0},
	{EAT_KEY_C3R1, WDK_NORMAL_1},
	{EAT_KEY_C2R1, WDK_NORMAL_2},
	{EAT_KEY_C1R1, WDK_NORMAL_3},
	{EAT_KEY_C3R2, WDK_NORMAL_4},
	{EAT_KEY_C2R2, WDK_NORMAL_5},
	{EAT_KEY_C1R2, WDK_NORMAL_6},
	{EAT_KEY_C3R3, WDK_NORMAL_7},
	{EAT_KEY_C2R3, WDK_NORMAL_8},
	{EAT_KEY_C1R3, WDK_NORMAL_9},
    
	//{EAT_KEY_C3R5, WDK_NORMAL_Q},
	//{EAT_KEY_C4R0, WDK_NORMAL_U},
	//{EAT_KEY_C4R1, WDK_NORMAL_A},
	//{EAT_KEY_C4R2, WDK_NORMAL_N},
	//{EAT_KEY_C4R3, WDK_NORMAL_P},
	//{EAT_KEY_C4R4, WDK_NORMAL_I},
	//{EAT_KEY_C4R5, WDK_NORMAL_N},
	
	//{DEVICE_KEY_C0R0, WDK_NORMAL_A},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_B},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_C},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_D},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_E},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_F},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_G},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_H},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_I},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_J},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_K},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_L},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_M},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_N},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_O},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_P},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_Q},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_R},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_S},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_T},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_U},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_V},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_W},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_X},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_Y},
	//{DEVICE_KEY_C0R0, WDK_NORMAL_Z},

	{EAT_KEY_C3R4, WDK_STAR},			/* "*" 键   */
	{EAT_KEY_C1R4, WDK_SHARP},			/* "#" 键   */
	{EAT_KEY_C0R0, WDK_UP},				/* 方向键   */
	{EAT_KEY_C0R4, WDK_DOWN},
	{EAT_KEY_C0R3, WDK_LEFT},
	{EAT_KEY_C0R1, WDK_RIGHT},
	{EAT_KEY_C2R5, WDK_C},				/* 删除键	*/
	{EAT_KEY_C0R2, WDK_OK},				/* 确认键：用于确认当前的选择项    */
	//{DEVICE_KEY_C0R0, WDK_MENU},			/* 全键盘时，执行FN键功能      */
	//{DEVICE_KEY_C0R0, WDK_SOFTLEFT},		/* 左软键：全键盘时，执行空格键功能  */
	//{DEVICE_KEY_C0R0, WDK_SOFTRIGHT},		/* 右软键： */
	//{DEVICE_KEY_C0R0, WDK_SHIFT},			/* Shift    */
	//{DEVICE_KEY_C0R0, WDK_CAPLOCK},   	/* 大小写切换： */
	//{DEVICE_KEY_C0R0, WDK_SEPERATER},		/* 分隔    */
	//{DEVICE_KEY_C0R0, WDK_FUNC},			/* FN：    */
	//{DEVICE_KEY_C0R0, WDK_ENTER},			/* 回车    */
	//{DEVICE_KEY_C0R0, WDK_ALT},		    /* Alt     */
	//{DEVICE_KEY_C0R0, WDK_SPACE},			/* 空格	   */
	//{DEVICE_KEY_C0R0, WDK_SYMBOL},		/* 符号	   */
	//{DEVICE_KEY_C0R0, WDK_SWITCHIME},		/* 切换输入法 */
};

static u8 ime_types[] = 
{
	EAT_IME_DIGIT, 
	EAT_IME_CN_CPINYIN, 
//	EAT_IME_CN_FULLPINYIN,
	EAT_IME_ENGLISH_ABC,
	EAT_IME_ENGLISH,
	EAT_IME_CN_BIHUA,
};

/********************************************************************
 * External Functions declaration
 ********************************************************************/
extern void APP_InitRegions(void);

/********************************************************************
 * Local Function declaration
 ********************************************************************/
void app_main(void *data);
void app_func_ext1(void *data);
/********************************************************************
 * Local Function
 ********************************************************************/
#pragma arm section rodata="APPENTRY"
	const EatEntry_st AppEntry = 
	{
		app_main,
		app_func_ext1,
		(app_user_func)EAT_NULL,//app_user1,
		(app_user_func)EAT_NULL,//app_user2,
		(app_user_func)EAT_NULL,//app_user3,
		(app_user_func)EAT_NULL,//app_user4,
		(app_user_func)EAT_NULL,//app_user5,
		(app_user_func)EAT_NULL,//app_user6,
		(app_user_func)EAT_NULL,//app_user7,
		(app_user_func)EAT_NULL,//app_user8,
		EAT_NULL,
		EAT_NULL,
		EAT_NULL,
		EAT_NULL,
		EAT_NULL,
		EAT_NULL
	};
#pragma arm section rodata

void app_func_ext1(void *data)
{
	/*This function can be called before Task running ,configure the GPIO,uart and etc.
	   Only these api can be used:
		 eat_uart_set_debug: set debug port
		 eat_pin_set_mode: set GPIO mode
		 eat_uart_set_at: set AT port
	*/
	eat_uart_set_debug(EAT_UART_2);
    eat_uart_set_at_port(EAT_UART_1);// UART1 is as AT PORT

	eat_pin_set_mode(EAT_PIN29_KBC5, EAT_PIN_MODE_GPIO);
	eat_pin_set_mode(EAT_PIN30_KBC4, EAT_PIN_MODE_KEY);
	eat_pin_set_mode(EAT_PIN31_KBC3, EAT_PIN_MODE_KEY);
	eat_pin_set_mode(EAT_PIN32_KBC2, EAT_PIN_MODE_KEY);
	eat_pin_set_mode(EAT_PIN33_KBC1, EAT_PIN_MODE_KEY);
	eat_pin_set_mode(EAT_PIN34_KBC0, EAT_PIN_MODE_KEY);
	eat_pin_set_mode(EAT_PIN35_KBR5, EAT_PIN_MODE_KEY);
	eat_pin_set_mode(EAT_PIN36_KBR4, EAT_PIN_MODE_KEY);
	eat_pin_set_mode(EAT_PIN37_KBR3, EAT_PIN_MODE_KEY);
	eat_pin_set_mode(EAT_PIN38_KBR2, EAT_PIN_MODE_KEY);
	eat_pin_set_mode(EAT_PIN39_KBR1, EAT_PIN_MODE_KEY);
	eat_pin_set_mode(EAT_PIN40_KBR0, EAT_PIN_MODE_KEY);

}
eat_bool eat_modem_data_parse(u8* buffer, u16 len, u8* param1, u8* param2)
{
    eat_bool ret_val = EAT_FALSE;
    /*param:%d,extern_param:%d*/
    if( strstr((const char *)buffer,"param"))
    {
        sscanf((const char *)buffer, "param:%d,extern_param:%d",(u32*)param1, (u32*)param2);
        eat_trace("data parse param1:%d param2:%d",*param1, *param2);
        ret_val = EAT_TRUE;
    }
    return ret_val;
}

u8 eat_customer_key_to_device_key(u8 customer_key)
{
	extern const EatKey_enum eat_device_key[EAT_KEY_NUM];
	u8 device_key_len = sizeof(eat_device_key)/sizeof(EatKey_enum);
	if(customer_key < device_key_len)
	{
		return eat_device_key[customer_key];
	}
	else
	{
		return EAT_IME_CONVERT_ERROR;
	}
}

u8 eat_ime_key_to_customer_key(u32 ime_key)
{
	u8 table_index = 0;
	int table_len = sizeof(g_ime_customer_key_map_table)/sizeof(IME_KEY_MAP);
	for(; table_index < table_len; table_index++)
	{
		if(ime_key == g_ime_customer_key_map_table[table_index].uIMEValue)
		{
			return g_ime_customer_key_map_table[table_index].uEatValue;
		}
	}
	
	return EAT_IME_CONVERT_ERROR;
}

void eat_entry_testing_loop()
{	
	if(EAT_TRUE == eat_timer_start(EAT_TIMER_6, 100))
	{
        eat_trace("IME Timer test, timer1 start successed!");
    }
	else
	{
        eat_trace("IME Timer test, timer1 start failed!");
    }
}

void eat_stop_ime_testing()
{
	eat_trace("IME test stop");
	eat_ime_exit();
}


void eat_send_system_key_to_ime(u32 sys_key, eat_bool long_press)
{
	s8 key_event = long_press ? 2 : 1;

	u8 customer_key = eat_ime_key_to_customer_key(sys_key);
	eat_trace("sys_key = %d,customer_key = %d",sys_key,customer_key);
	
	if(EAT_IME_CONVERT_ERROR != customer_key)
	{
		u8 deviceKey = eat_customer_key_to_device_key(customer_key);
		eat_trace("deviceKey = %d",deviceKey);
		if(EAT_IME_CONVERT_ERROR != deviceKey)
		{
			eat_send_key(deviceKey, key_event);
		}
	}
	else
	{
		eat_trace("eat_send_system_key_to_ime error!");
	}
}

void eat_start_ime_testing()
{
	u8 key_map_len = sizeof(g_ime_customer_key_map_table)/sizeof(IME_KEY_MAP);
	if(eat_ime_register_keymap(g_ime_customer_key_map_table, key_map_len))
	{
		if(0 ==eat_ime_entry(ime_types, sizeof(ime_types)/sizeof(u8), EAT_IME_CN_CPINYIN, 4))
		{
			eat_entry_testing_loop();
		}
	}
}



u32 eat_get_one_ime_key(eat_bool* long_press)
{
	static u32 table_index = 0;
	static u32 input_table[] = {
		WDK_NORMAL_2,/*纯拼*/
		WDK_NORMAL_4,
		WDK_NORMAL_8,
		WDK_NORMAL_6,
		WDK_RIGHT,
		WDK_OK,
		WDK_NORMAL_7,
		WDK_NORMAL_4,
		WDK_NORMAL_6,
		WDK_RIGHT,
		WDK_OK,//33
		WDK_C,//32
		WDK_SHARP,/*全拼*///27
		WDK_NORMAL_Q,//193
		WDK_NORMAL_U,//197
		WDK_NORMAL_A,//177
		WDK_NORMAL_N,
		WDK_OK,
		WDK_NORMAL_P,
		WDK_NORMAL_I,
		WDK_NORMAL_N,
		WDK_OK,
		WDK_C,
		WDK_SHARP,/*ab*/
		WDK_NORMAL_2,
		WDK_OK,
		WDK_NORMAL_2,
		WDK_NORMAL_2,
		WDK_OK,
		WDK_SHARP,/*english*/
		WDK_NORMAL_3,
		WDK_NORMAL_6,
		WDK_NORMAL_4,
		WDK_NORMAL_5,
		WDK_RIGHT,
		WDK_OK,
		WDK_SHARP,/*笔画*/
		WDK_NORMAL_3,
		WDK_NORMAL_1,
		WDK_NORMAL_4,
		WDK_NORMAL_3,
		WDK_NORMAL_1,
		WDK_NORMAL_4,
		WDK_NORMAL_3,
		WDK_NORMAL_1,
		WDK_NORMAL_1,
		WDK_OK,
		WDK_C,
		WDK_SHARP,/*数字*/
		WDK_NORMAL_1,
		WDK_NORMAL_2,
		WDK_NORMAL_3,
	};
	
	u32 ime_key = INPUT_EXIT;

	int table_len = sizeof(input_table) / sizeof(input_table[0]);
	if (table_index < table_len)
	{
		ime_key = input_table[table_index];
		table_index++;
	}
	else
	{
		table_index = 0;
	}

	return ime_key;
}

void eat_ime_on_timer()
{
	u32 input_key = 0;
	eat_bool long_press = EAT_FALSE;

	static u32 times = 0;
	times++;
	eat_trace("IME Timer test, timer1 called (%d)s!", times);
	
	input_key = eat_get_one_ime_key(&long_press);
	if (INPUT_EXIT == input_key)
	{
		eat_stop_ime_testing();
		times = 0;
	}
	else
	{
		u8 ret = 0;
		eat_send_system_key_to_ime(input_key, long_press);
               ret = eat_timer_start(EAT_TIMER_6, 100);
		eat_trace("eat_timer_start uRet = %d",ret);
	}
}

/****************************************************
 * Timer testing module
 *****************************************************/
eat_bool eat_module_test_inputmethod(u8 param1, u8 param2)
{
    eat_bool result = EAT_TRUE;
    /***************************************
     * example 1
     * Start and stop 3 timers
     ***************************************/
    if( 1 == param1 )
    {
    	eat_start_ime_testing();
    }
    return EAT_TRUE;
}


void app_main(void *data)
{
    EatEvent_st event;
    u8 buf[2048];
    u16 len = 0;
	s32 sRet = 0;
    APP_InitRegions();//Init app RAM
    
    eat_trace(" app_main ENTRY");
    while(EAT_TRUE)
    {
        eat_get_event(&event);
        eat_trace("MSG id = %x", event.event);
        switch(event.event)
        {
            case EAT_EVENT_TIMER :
                {
                    eat_ime_on_timer();
                }
                break;
            case EAT_EVENT_MDM_READY_RD:
                {
                    u8 param1,param2;
                    len = 0;
                    len = eat_modem_read(buf, 2048);
                    if(len > 0)
                    {
                        //Get the testing parameter
                        if(eat_modem_data_parse(buf,len,&param1,&param2))
                        {
                            //Entry timer test module
                            eat_module_test_inputmethod(param1, param2);
                        }
                        else
                        {
                            eat_trace("From Mdm:%s",buf);
                        }
                    }
                }
                break;
            case EAT_EVENT_IME_KEY:
                {
                    eat_trace("get message:EAT_EVENT_IME_KEY");
                    if(event.data.ime_result->output[0] != 0)
                    {
                        eat_trace("g_ime_result.output=%x",event.data.ime_result->output[0]);
                    }
                }
                break;
            case EAT_EVENT_MDM_READY_WR:
            case EAT_EVENT_UART_READY_RD:
                break;
            case EAT_EVENT_UART_SEND_COMPLETE :
                break;
            default:
                break;
        }

    }

}


