

/*
#include <stdio.h>
#include <Arduino.h>
#include <EEPROM.h>
#include <SPI.h>
#include <avr/pgmspace.h>
*/

/*#include "FT_Hal_SPI.cpp"
#include "FT_CoPro_Cmds.cpp"
#include "Player.cpp"*/


#include "FT_Platform.h"
#include "Ft_App_Font.h"
#include "sdcard.h"




#define SAMAPP_DELAY_BTW_APIS (1000)
#define SAMAPP_ENABLE_DELAY() Ft_Gpu_Hal_Sleep(SAMAPP_DELAY_BTW_APIS)
#define SAMAPP_ENABLE_DELAY_VALUE(x) Ft_Gpu_Hal_Sleep(x)

/* Global variables for display resolution to support various display panels */
/* Default is WQVGA - 480x272 */
ft_int16_t FT_DispWidth = 480;
ft_int16_t FT_DispHeight = 272;
ft_int16_t FT_DispHCycle =  548;
ft_int16_t FT_DispHOffset = 43;
ft_int16_t FT_DispHSync0 = 0;
ft_int16_t FT_DispHSync1 = 41;
ft_int16_t FT_DispVCycle = 292;
ft_int16_t FT_DispVOffset = 12;
ft_int16_t FT_DispVSync0 = 0;
ft_int16_t FT_DispVSync1 = 10;
ft_uint8_t FT_DispPCLK = 5;
ft_char8_t FT_DispSwizzle = 0;
ft_char8_t FT_DispPCLKPol = 1;

/* Global used for buffer optimization */
Ft_Gpu_Hal_Context_t host,*phost;


ft_uint32_t Ft_CmdBuffer_Index;
ft_uint32_t Ft_DlBuffer_Index;


static ft_bool_t showCursor = TRUE;
static ft_uint16_t   sc_flag = 65535;//flag for toggling simplified chinease and traditional chinese

static ft_uint16_t currentLine = 0,currentCol =0;

#ifdef BUFFER_OPTIMIZATION
ft_uint8_t  Ft_DlBuffer[FT_DL_SIZE];
ft_uint8_t  Ft_CmdBuffer[FT_CMD_FIFO_SIZE];
#endif

ft_void_t Ft_App_WrCoCmd_Buffer(Ft_Gpu_Hal_Context_t *phost,ft_uint32_t cmd)
{
#ifdef  BUFFER_OPTIMIZATION
   /* Copy the command instruction into buffer */
   ft_uint32_t *pBuffcmd;
   pBuffcmd =(ft_uint32_t*)&Ft_CmdBuffer[Ft_CmdBuffer_Index];
   *pBuffcmd = cmd;
#endif
#ifdef ARDUINO_PLATFORM
   Ft_Gpu_Hal_WrCmd32(phost,cmd);
#endif

   /* Increment the command index */
   Ft_CmdBuffer_Index += FT_CMD_SIZE;  
}

ft_void_t Ft_App_WrDlCmd_Buffer(Ft_Gpu_Hal_Context_t *phost,ft_uint32_t cmd)
{
#ifdef BUFFER_OPTIMIZATION  
   /* Copy the command instruction into buffer */
   ft_uint32_t *pBuffcmd;
   pBuffcmd =(ft_uint32_t*)&Ft_DlBuffer[Ft_DlBuffer_Index];
   *pBuffcmd = cmd;
#endif

#ifdef ARDUINO_PLATFORM
   Ft_Gpu_Hal_Wr32(phost,(RAM_DL+Ft_DlBuffer_Index),cmd);
#endif
   /* Increment the command index */
   Ft_DlBuffer_Index += FT_CMD_SIZE;  
}

ft_void_t Ft_App_WrCoStr_Buffer(Ft_Gpu_Hal_Context_t *phost,const ft_char8_t *s)
{
#ifdef  BUFFER_OPTIMIZATION  
  ft_uint16_t length = 0;
  length = strlen(s) + 1;//last for the null termination
  
  strcpy(&Ft_CmdBuffer[Ft_CmdBuffer_Index],s);  

  /* increment the length and align it by 4 bytes */
  Ft_CmdBuffer_Index += ((length + 3) & ~3);  
#endif  
}

ft_void_t Ft_App_Flush_DL_Buffer(Ft_Gpu_Hal_Context_t *phost)
{
#ifdef  BUFFER_OPTIMIZATION    
   if (Ft_DlBuffer_Index> 0)
     Ft_Gpu_Hal_WrMem(phost,RAM_DL,Ft_DlBuffer,Ft_DlBuffer_Index);
#endif     
   Ft_DlBuffer_Index = 0;
   
}

ft_void_t Ft_App_Flush_Co_Buffer(Ft_Gpu_Hal_Context_t *phost)
{
#ifdef  BUFFER_OPTIMIZATION    
   if (Ft_CmdBuffer_Index > 0)
     Ft_Gpu_Hal_WrCmdBuf(phost,Ft_CmdBuffer,Ft_CmdBuffer_Index);
#endif     
   Ft_CmdBuffer_Index = 0;
}


/* API to give fadeout effect by changing the display PWM from 100 till 0 */
ft_void_t SAMAPP_fadeout()
{
   ft_int32_t i;
	
	for (i = 100; i >= 0; i -= 3) 
	{
		Ft_Gpu_Hal_Wr8(phost,REG_PWM_DUTY,i);

		Ft_Gpu_Hal_Sleep(2);//sleep for 2 ms
	}
}

/* API to perform display fadein effect by changing the display PWM from 0 till 100 and finally 128 */
ft_void_t SAMAPP_fadein()
{
	ft_int32_t i;
	
	for (i = 0; i <=100 ; i += 3) 
	{
		Ft_Gpu_Hal_Wr8(phost,REG_PWM_DUTY,i);
		Ft_Gpu_Hal_Sleep(2);//sleep for 2 ms
	}
	/* Finally make the PWM 100% */
	i = 128;
	Ft_Gpu_Hal_Wr8(phost,REG_PWM_DUTY,i);
}


/* API to check the status of previous DLSWAP and perform DLSWAP of new DL */
/* Check for the status of previous DLSWAP and if still not done wait for few ms and check again */
ft_void_t SAMAPP_GPU_DLSwap(ft_uint8_t DL_Swap_Type)
{
	ft_uint8_t Swap_Type = DLSWAP_FRAME,Swap_Done = DLSWAP_FRAME;

	if(DL_Swap_Type == DLSWAP_LINE)
	{
		Swap_Type = DLSWAP_LINE;
	}

	/* Perform a new DL swap */
	Ft_Gpu_Hal_Wr8(phost,REG_DLSWAP,Swap_Type);

	/* Wait till the swap is done */
	while(Swap_Done)
	{
		Swap_Done = Ft_Gpu_Hal_Rd8(phost,REG_DLSWAP);

		if(DLSWAP_DONE != Swap_Done)
		{
			Ft_Gpu_Hal_Sleep(10);//wait for 10ms
		}
	}	
}


ft_void_t Ft_BootupConfig()
{

	/* Do a power cycle for safer side */
	Ft_Gpu_Hal_Powercycle(phost,FT_TRUE);
	Ft_Gpu_Hal_Rd16(phost,RAM_G);
	/* Set the clk to external clock */
	Ft_Gpu_HostCommand(phost,FT_GPU_EXTERNAL_OSC);  
	Ft_Gpu_Hal_Sleep(10);
	  

	/* Switch PLL output to 48MHz */
	Ft_Gpu_HostCommand(phost,FT_GPU_PLL_48M);  
	Ft_Gpu_Hal_Sleep(10);

	/* Do a core reset for safer side */
	Ft_Gpu_HostCommand(phost,FT_GPU_CORE_RESET);     

	/* Access address 0 to wake up the FT800 */
	Ft_Gpu_HostCommand(phost,FT_GPU_ACTIVE_M);  

    Ft_Gpu_Hal_Wr8(phost, REG_GPIO_DIR,0x80 | Ft_Gpu_Hal_Rd8(phost,REG_GPIO_DIR));
    Ft_Gpu_Hal_Wr8(phost, REG_GPIO,0x080 | Ft_Gpu_Hal_Rd8(phost,REG_GPIO));
	
	{
		ft_uint8_t chipid;
		//Read Register ID to check if FT800 is ready. 
		chipid = Ft_Gpu_Hal_Rd8(phost, REG_ID);
		while(chipid != 0x7C)
			chipid = Ft_Gpu_Hal_Rd8(phost, REG_ID);
#ifdef MSVC_PLATFORM
		printf("VC1 register ID after wake up %x\n",chipid);
#endif
	}
	/* Configuration of LCD display */
#ifdef SAMAPP_DISPLAY_QVGA	
	/* Values specific to QVGA LCD display */
	FT_DispWidth = 320;
	FT_DispHeight = 240;
	FT_DispHCycle =  408;
	FT_DispHOffset = 70;
	FT_DispHSync0 = 0;
	FT_DispHSync1 = 10;
	FT_DispVCycle = 263;
	FT_DispVOffset = 13;
	FT_DispVSync0 = 0;
	FT_DispVSync1 = 2;
	FT_DispPCLK = 8;
	FT_DispSwizzle = 2;
	FT_DispPCLKPol = 0;
#endif

    Ft_Gpu_Hal_Wr16(phost, REG_HCYCLE, FT_DispHCycle);
    Ft_Gpu_Hal_Wr16(phost, REG_HOFFSET, FT_DispHOffset);
    Ft_Gpu_Hal_Wr16(phost, REG_HSYNC0, FT_DispHSync0);
    Ft_Gpu_Hal_Wr16(phost, REG_HSYNC1, FT_DispHSync1);
    Ft_Gpu_Hal_Wr16(phost, REG_VCYCLE, FT_DispVCycle);
    Ft_Gpu_Hal_Wr16(phost, REG_VOFFSET, FT_DispVOffset);
    Ft_Gpu_Hal_Wr16(phost, REG_VSYNC0, FT_DispVSync0);
    Ft_Gpu_Hal_Wr16(phost, REG_VSYNC1, FT_DispVSync1);
    Ft_Gpu_Hal_Wr8(phost, REG_SWIZZLE, FT_DispSwizzle);
    Ft_Gpu_Hal_Wr8(phost, REG_PCLK_POL, FT_DispPCLKPol);
    Ft_Gpu_Hal_Wr8(phost, REG_PCLK,FT_DispPCLK);//after this display is visible on the LCD
    Ft_Gpu_Hal_Wr16(phost, REG_HSIZE, FT_DispWidth);
    Ft_Gpu_Hal_Wr16(phost, REG_VSIZE, FT_DispHeight);


    /* Touch configuration - configure the resistance value to 1200 - this value is specific to customer requirement and derived by experiment */
    Ft_Gpu_Hal_Wr16(phost, REG_TOUCH_RZTHRESH,1200);
    Ft_Gpu_Hal_Wr8(phost, REG_GPIO_DIR,0xff);
    Ft_Gpu_Hal_Wr8(phost, REG_GPIO,0x0ff);

}



/* Boot up for FT800 followed by graphics primitive sample cases */
/* Initial boot up DL - make the back ground green color */
const ft_uint8_t FT_DLCODE_BOOTUP[12] = 
{
    255,255,255,2,//GPU instruction CLEAR_COLOR_RGB
    7,0,0,38, //GPU instruction CLEAR
    0,0,0,0,  //GPU instruction DISPLAY
};



char *info[] = {  "FT800 Font Application",
				   "APP to demo simplified and traditional chinese font", 
				   "using Button",
				   "& other primitives."
                }; 

static ft_uint8_t home_star_icon[] = {0x78,0x9C,0xE5,0x94,0xBF,0x4E,0xC2,0x40,0x1C,0xC7,0x7F,0x2D,0x04,0x8B,0x20,0x45,0x76,0x14,0x67,0xA3,0xF1,0x0D,0x64,0x75,0xD2,0xD5,0x09,0x27,0x17,0x13,0xE1,0x0D,0xE4,0x0D,0x78,0x04,0x98,0x5D,0x30,0x26,0x0E,0x4A,0xA2,0x3E,0x82,0x0E,0x8E,0x82,0xC1,0x38,0x62,0x51,0x0C,0x0A,0x42,0x7F,0xDE,0xB5,0x77,0xB4,0x77,0x17,0x28,0x21,0x26,0x46,0xFD,0x26,0xCD,0xE5,0xD3,0x7C,0xFB,0xBB,0xFB,0xFD,0xB9,0x02,0xCC,0xA4,0xE8,0x99,0x80,0x61,0xC4,0x8A,0x9F,0xCB,0x6F,0x31,0x3B,0xE3,0x61,0x7A,0x98,0x84,0x7C,0x37,0xF6,0xFC,0xC8,0xDD,0x45,0x00,0xDD,0xBA,0xC4,0x77,0xE6,0xEE,0x40,0xEC,0x0E,0xE6,0x91,0xF1,0xD2,0x00,0x42,0x34,0x5E,0xCE,0xE5,0x08,0x16,0xA0,0x84,0x68,0x67,0xB4,0x86,0xC3,0xD5,0x26,0x2C,0x20,0x51,0x17,0xA2,0xB8,0x03,0xB0,0xFE,0x49,0xDD,0x54,0x15,0xD8,0xEE,0x73,0x37,0x95,0x9D,0xD4,0x1A,0xB7,0xA5,0x26,0xC4,0x91,0xA9,0x0B,0x06,0xEE,0x72,0xB7,0xFB,0xC5,0x16,0x80,0xE9,0xF1,0x07,0x8D,0x3F,0x15,0x5F,0x1C,0x0B,0xFC,0x0A,0x90,0xF0,0xF3,0x09,0xA9,0x90,0xC4,0xC6,0x37,0xB0,0x93,0xBF,0xE1,0x71,0xDB,0xA9,0xD7,0x41,0xAD,0x46,0xEA,0x19,0xA9,0xD5,0xCE,0x93,0xB3,0x35,0x73,0x0A,0x69,0x59,0x91,0xC3,0x0F,0x22,0x1B,0x1D,0x91,0x13,0x3D,0x91,0x73,0x43,0xF1,0x6C,0x55,0xDA,0x3A,0x4F,0xBA,0x25,0xCE,0x4F,0x04,0xF1,0xC5,0xCF,0x71,0xDA,0x3C,0xD7,0xB9,0xB2,0x48,0xB4,0x89,0x38,0x20,0x4B,0x2A,0x95,0x0C,0xD5,0xEF,0x5B,0xAD,0x96,0x45,0x8A,0x41,0x96,0x7A,0x1F,0x60,0x0D,0x7D,0x22,0x75,0x82,0x2B,0x0F,0xFB,0xCE,0x51,0x3D,0x2E,0x3A,0x21,0xF3,0x1C,0xD9,0x38,0x86,0x2C,0xC6,0x05,0xB6,0x7B,0x9A,0x8F,0x0F,0x97,0x1B,0x72,0x6F,0x1C,0xEB,0xAE,0xFF,0xDA,0x97,0x0D,0xBA,0x43,0x32,0xCA,0x66,0x34,0x3D,0x54,0xCB,0x24,0x9B,0x43,0xF2,0x70,0x3E,0x42,0xBB,0xA0,0x95,0x11,0x37,0x46,0xE1,0x4F,0x49,0xC5,0x1B,0xFC,0x3C,0x3A,0x3E,0xD1,0x65,0x0E,0x6F,0x58,0xF8,0x9E,0x5B,0xDB,0x55,0xB6,0x41,0x34,0xCB,0xBE,0xDB,0x87,0x5F,0xA9,0xD1,0x85,0x6B,0xB3,0x17,0x9C,0x61,0x0C,0x9B,0xA2,0x5D,0x61,0x10,0xED,0x2A,0x9B,0xA2,0x5D,0x61,0x10,0xED,0x2A,0x9B,0xA2,0x5D,0x61,0x10,0xED,0x2A,0x9B,0xED,0xC9,0xFC,0xDF,0x14,0x54,0x8F,0x80,0x7A,0x06,0xF5,0x23,0xA0,0x9F,0x41,0xF3,0x10,0x30,0x4F,0x41,0xF3,0x18,0x30,0xCF,0xCA,0xFC,0xFF,0x35,0xC9,0x79,0xC9,0x89,0xFA,0x33,0xD7,0x1D,0xF6,0x5E,0x84,0x5C,0x56,0x6E,0xA7,0xDA,0x1E,0xF9,0xFA,0xAB,0xF5,0x97,0xFF,0x2F,0xED,0x89,0x7E,0x29,0x9E,0xB4,0x9F,0x74,0x1E,0x69,0xDA,0xA4,0x9F,0x81,0x94,0xEF,0x4F,0xF6,0xF9,0x0B,0xF4,0x65,0x51,0x08};


static ft_uint8_t sk=0;
ft_uint8_t Read_Keys()
{
  static ft_uint8_t Read_tag=0,temp_tag=0,ret_tag=0;	
  Read_tag = Ft_Gpu_Hal_Rd8(phost,REG_TOUCH_TAG);
  ret_tag = NULL;
  if(Read_tag!=NULL)								// Allow if the Key is released
  {
    if(temp_tag!=Read_tag)
    {
      temp_tag = Read_tag;	
      sk = Read_tag;										// Load the Read tag to temp variable	
    }  
  }
  else
  {
    if(temp_tag!=0)
    {
      ret_tag = temp_tag;
    }  
    sk = 0;
  }
  return ret_tag;
}

ft_void_t home_setup()
{
  Ft_Gpu_Hal_WrCmd32(phost,CMD_INFLATE);
  Ft_Gpu_Hal_WrCmd32(phost,250*1024L);
  Ft_Gpu_Hal_WrCmdBuf(phost,home_star_icon,sizeof(home_star_icon));
  
  Ft_Gpu_CoCmd_Dlstart(phost);        // start
  Ft_App_WrCoCmd_Buffer(phost,CLEAR(1,1,1));
  Ft_App_WrCoCmd_Buffer(phost,COLOR_RGB(255, 255, 255));
  Ft_App_WrCoCmd_Buffer(phost,BITMAP_HANDLE(13));    // handle for background stars
  Ft_App_WrCoCmd_Buffer(phost,BITMAP_SOURCE(250*1024L));      // Starting address in gram
  Ft_App_WrCoCmd_Buffer(phost,BITMAP_LAYOUT(L4, 16, 32));  // format 
  Ft_App_WrCoCmd_Buffer(phost,BITMAP_SIZE(NEAREST, REPEAT, REPEAT, 512, 512  ));
  Ft_App_WrCoCmd_Buffer(phost,BITMAP_HANDLE(14));    // handle for background stars
  Ft_App_WrCoCmd_Buffer(phost,BITMAP_SOURCE(250*1024L));      // Starting address in gram
  Ft_App_WrCoCmd_Buffer(phost,BITMAP_LAYOUT(L4, 16, 32));  // format 
  Ft_App_WrCoCmd_Buffer(phost,BITMAP_SIZE(NEAREST, BORDER, BORDER, 32, 32  ));
  Ft_App_WrCoCmd_Buffer(phost,DISPLAY());
  Ft_Gpu_CoCmd_Swap(phost);
  Ft_App_Flush_Co_Buffer(phost);
  Ft_Gpu_Hal_WaitCmdfifo_empty(phost);
}

ft_void_t Info()
{
  ft_uint16_t dloffset = 0,z;
  Ft_CmdBuffer_Index = 0;  
 
  Ft_Gpu_CoCmd_Dlstart(phost); 
  Ft_App_WrCoCmd_Buffer(phost,CLEAR(1,1,1));
  Ft_App_WrCoCmd_Buffer(phost,COLOR_RGB(255,255,255));
  Ft_Gpu_CoCmd_Text(phost,FT_DispWidth/2,FT_DispHeight/2,26,OPT_CENTERX|OPT_CENTERY,"Please tap on a dot");
  Ft_Gpu_CoCmd_Calibrate(phost,0);
  Ft_App_WrCoCmd_Buffer(phost,DISPLAY());
  Ft_Gpu_CoCmd_Swap(phost);
  Ft_App_Flush_Co_Buffer(phost);
  Ft_Gpu_Hal_WaitCmdfifo_empty(phost);
  
  Ft_Gpu_CoCmd_Logo(phost);
  Ft_App_Flush_Co_Buffer(phost);
  Ft_Gpu_Hal_WaitCmdfifo_empty(phost);
  while(0!=Ft_Gpu_Hal_Rd16(phost,REG_CMD_READ)); 
  dloffset = Ft_Gpu_Hal_Rd16(phost,REG_CMD_DL);
  dloffset -=4;
  Ft_Gpu_Hal_WrCmd32(phost,CMD_MEMCPY);
  Ft_Gpu_Hal_WrCmd32(phost,100000L);
  Ft_Gpu_Hal_WrCmd32(phost,RAM_DL);
  Ft_Gpu_Hal_WrCmd32(phost,dloffset);
  do
  {
    Ft_Gpu_CoCmd_Dlstart(phost);   
    Ft_Gpu_CoCmd_Append(phost,100000L,dloffset);
    Ft_App_WrCoCmd_Buffer(phost,BITMAP_TRANSFORM_A(256));
    Ft_App_WrCoCmd_Buffer(phost,BITMAP_TRANSFORM_A(256));
    Ft_App_WrCoCmd_Buffer(phost,BITMAP_TRANSFORM_B(0));
    Ft_App_WrCoCmd_Buffer(phost,BITMAP_TRANSFORM_C(0));
    Ft_App_WrCoCmd_Buffer(phost,BITMAP_TRANSFORM_D(0));
    Ft_App_WrCoCmd_Buffer(phost,BITMAP_TRANSFORM_E(256));
    Ft_App_WrCoCmd_Buffer(phost,BITMAP_TRANSFORM_F(0));  
    Ft_App_WrCoCmd_Buffer(phost,SAVE_CONTEXT());	
    Ft_App_WrCoCmd_Buffer(phost,COLOR_RGB(219,180,150));
    Ft_App_WrCoCmd_Buffer(phost,COLOR_A(220));
    Ft_App_WrCoCmd_Buffer(phost,BEGIN(EDGE_STRIP_A));
    Ft_App_WrCoCmd_Buffer(phost,VERTEX2F(0,FT_DispHeight*16));
    Ft_App_WrCoCmd_Buffer(phost,VERTEX2F(FT_DispWidth*16,FT_DispHeight*16));
    Ft_App_WrCoCmd_Buffer(phost,COLOR_A(255));
    Ft_App_WrCoCmd_Buffer(phost,RESTORE_CONTEXT());	
    Ft_App_WrCoCmd_Buffer(phost,COLOR_RGB(0,0,0));
   // INFORMATION 
    Ft_Gpu_CoCmd_Text(phost,FT_DispWidth/2,20,28,OPT_CENTERX|OPT_CENTERY,info[0]);
    Ft_Gpu_CoCmd_Text(phost,FT_DispWidth/2,60,26,OPT_CENTERX|OPT_CENTERY,info[1]);
    Ft_Gpu_CoCmd_Text(phost,FT_DispWidth/2,90,26,OPT_CENTERX|OPT_CENTERY,info[2]);  
    Ft_Gpu_CoCmd_Text(phost,FT_DispWidth/2,120,26,OPT_CENTERX|OPT_CENTERY,info[3]);  
    Ft_Gpu_CoCmd_Text(phost,FT_DispWidth/2,FT_DispHeight-30,26,OPT_CENTERX|OPT_CENTERY,"Click to play");
    if(sk!='P')
    Ft_App_WrCoCmd_Buffer(phost,COLOR_RGB(255,255,255));
    else
    Ft_App_WrCoCmd_Buffer(phost,COLOR_RGB(100,100,100));
    Ft_App_WrCoCmd_Buffer(phost,BEGIN(FTPOINTS));   
    Ft_App_WrCoCmd_Buffer(phost,POINT_SIZE(20*16));
    Ft_App_WrCoCmd_Buffer(phost,TAG('P'));
    Ft_App_WrCoCmd_Buffer(phost,VERTEX2F((FT_DispWidth/2)*16,(FT_DispHeight-60)*16));
    Ft_App_WrCoCmd_Buffer(phost,COLOR_RGB(180,35,35));
    Ft_App_WrCoCmd_Buffer(phost,BEGIN(BITMAPS));
    Ft_App_WrCoCmd_Buffer(phost,VERTEX2II((FT_DispWidth/2)-14,(FT_DispHeight-75),14,4));
    Ft_App_WrCoCmd_Buffer(phost,DISPLAY());
    Ft_Gpu_CoCmd_Swap(phost);
    Ft_App_Flush_Co_Buffer(phost);
    Ft_Gpu_Hal_WaitCmdfifo_empty(phost);
  }while(Read_Keys()!='P');
}

#ifdef ARDUINO_PLATFORM
void Load_afile(ft_uint32_t add, Reader &r)
{
  ft_uint8_t imbuff[512];  
  ft_uint16_t blocklen;
  while (r.offset < r.size)
  {
    uint16_t n = min(512, r.size - r.offset);
    n = (n + 3) & ~3;   // force 32-bit alignment
    r.readsector(imbuff);
//    Ft_Gpu_Hal_WrCmdBuf(phost,imbuff,n);				/* copy data continuously into command memory */
    Ft_Gpu_Hal_WrMem(phost,add,imbuff,n);
    add += n;
  }
}
#endif

ft_void_t readfile2flash(const char *filename, ft_uint32_t ft800_addr)
{
#ifdef   MSVC_PLATFORM
	ft_uint32_t FileLen =0, ft800_memaddr= 0;

	FILE *pFile = fopen(filename,"rb");
	ft_uint8_t *pbuff = NULL;

	ft800_memaddr = ft800_addr;

	fseek(pFile,0,SEEK_END);
	FileLen = ftell(pFile);
	fseek(pFile,0,SEEK_SET);

	pbuff = malloc(FileLen);

	fread(pbuff,1,FileLen,pFile);

	while (FileLen > 64*1024)
	{
	   Ft_Gpu_Hal_WrMemFromFlash(phost, ft800_memaddr,(ft_uchar8_t *)pbuff,  64*1024);
	   FileLen -= 64*1024;
	   ft800_memaddr += 64*1024;
	   pbuff += 64*1024;
	}
	Ft_Gpu_Hal_WrMemFromFlash(phost, ft800_memaddr,(ft_uchar8_t *)pbuff,  FileLen);
	free(pbuff);
#endif

#ifdef ARDUINO_PLATFORM
  Reader fontfile;
  byte file = 0; 
  file = fontfile.openfile(filename);
  Load_afile(ft800_addr,fontfile);
#endif  
}


ft_void_t download_bmpfile(ft_uint16_t sc_flag)
{

#define INDEX_BASE      1

#define A_F_FILE_ADDR   RAM_G
#define A_F_HANDLE      1
#define A_F_SOURCE     (A_F_FILE_ADDR+148-34*14*INDEX_BASE)

#define G_L_FILE_ADDR   (A_F_FILE_ADDR + 28708)
#define G_L_HANDLE      2
#define G_L_SOURCE     (G_L_FILE_ADDR+148-34*14*INDEX_BASE)


#define M_R_FILE_ADDR   (G_L_FILE_ADDR + 28708)
#define M_R_HANDLE      3
#define M_R_SOURCE     (M_R_FILE_ADDR+148-34*14*INDEX_BASE)

#define S_X_FILE_ADDR   (M_R_FILE_ADDR + 28708)
#define S_X_HANDLE      4
#define S_X_SOURCE     (S_X_FILE_ADDR+148-34*14*INDEX_BASE)

#define Y_Z_FILE_ADDR   (S_X_FILE_ADDR + 28708)
#define Y_Z_HANDLE      5
#define Y_Z_SOURCE     (Y_Z_FILE_ADDR+148-34*14*INDEX_BASE)

#define SC_NOTE_FILE_ADDR   (Y_Z_FILE_ADDR + 13476)
#define SC_NOTE_HANDLE      6
#define SC_NOTE_SOURCE     (SC_NOTE_FILE_ADDR+148-34*15*INDEX_BASE)

#ifdef MSVC_PLATFORM
	if (sc_flag)
	{
		readfile2flash("..\\..\\..\\Test\\A-F_SC.raw", A_F_FILE_ADDR);
		readfile2flash("..\\..\\..\\Test\\G-L_SC.raw", G_L_FILE_ADDR);
		readfile2flash("..\\..\\..\\Test\\M-R_SC.raw", M_R_FILE_ADDR);
		readfile2flash("..\\..\\..\\Test\\S-X_SC.raw", S_X_FILE_ADDR);
		readfile2flash("..\\..\\..\\Test\\Y-Z_SC.raw", Y_Z_FILE_ADDR);
	}else
	{
		readfile2flash("..\\..\\..\\Test\\A-F_TC.raw", A_F_FILE_ADDR);
		readfile2flash("..\\..\\..\\Test\\G-L_TC.raw", G_L_FILE_ADDR);
		readfile2flash("..\\..\\..\\Test\\M-R_TC.raw", M_R_FILE_ADDR);
		readfile2flash("..\\..\\..\\Test\\S-X_TC.raw", S_X_FILE_ADDR);
		readfile2flash("..\\..\\..\\Test\\Y-Z_TC.raw", Y_Z_FILE_ADDR);
	}

	readfile2flash("..\\..\\..\\Test\\SC_Note.raw", SC_NOTE_FILE_ADDR);
#endif
#ifdef ARDUINO_PLATFORM
	if (sc_flag)
	{
		readfile2flash("A-F_SC.raw", A_F_FILE_ADDR);
		readfile2flash("G-L_SC.raw", G_L_FILE_ADDR);
		readfile2flash("M-R_SC.raw", M_R_FILE_ADDR);
		readfile2flash("S-X_SC.raw", S_X_FILE_ADDR);
		readfile2flash("Y-Z_SC.raw", Y_Z_FILE_ADDR);
	}else
	{
		readfile2flash("A-F_TC.raw", A_F_FILE_ADDR);
		readfile2flash("G-L_TC.raw", G_L_FILE_ADDR);
		readfile2flash("M-R_TC.raw", M_R_FILE_ADDR);
		readfile2flash("S-X_TC.raw", S_X_FILE_ADDR);
		readfile2flash("Y-Z_TC.raw", Y_Z_FILE_ADDR);
	}

	readfile2flash("SC_Note.raw", SC_NOTE_FILE_ADDR);
#endif
}

ft_void_t setup_bmp()
{
	Ft_App_WrCoCmd_Buffer(phost,TAG_MASK(0));

	//A_F bitmap configuration
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_HANDLE(A_F_HANDLE));
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_SOURCE(A_F_SOURCE));	
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_LAYOUT(L4,14,34));
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_SIZE(NEAREST,BORDER,BORDER,28,34));		
	Ft_Gpu_CoCmd_SetFont(phost, A_F_HANDLE, A_F_FILE_ADDR);	

	//G_L bitmap configuration
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_HANDLE(G_L_HANDLE));
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_SOURCE(G_L_SOURCE));
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_LAYOUT(L4,14,34));
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_SIZE(NEAREST,BORDER,BORDER,28,34));		
	Ft_Gpu_CoCmd_SetFont(phost, G_L_HANDLE, G_L_FILE_ADDR);	

	//M_R bitmap configuration
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_HANDLE(M_R_HANDLE));
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_SOURCE(M_R_SOURCE));
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_LAYOUT(L4,14,34));
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_SIZE(NEAREST,BORDER,BORDER,28,34));		
	Ft_Gpu_CoCmd_SetFont(phost, M_R_HANDLE, M_R_FILE_ADDR);	


	//S_X bitmap configuration
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_HANDLE(S_X_HANDLE));
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_SOURCE(S_X_SOURCE));
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_LAYOUT(L4,14,34));
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_SIZE(NEAREST,BORDER,BORDER,28,34));		
	Ft_Gpu_CoCmd_SetFont(phost, S_X_HANDLE, S_X_FILE_ADDR);	

	//Y_Z bitmap configuration
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_HANDLE(Y_Z_HANDLE));
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_SOURCE(Y_Z_SOURCE));
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_LAYOUT(L4,14,34));
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_SIZE(NEAREST,BORDER,BORDER,28,34));		
	Ft_Gpu_CoCmd_SetFont(phost, Y_Z_HANDLE, Y_Z_FILE_ADDR);	


	//SC Note bitmap configuration
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_HANDLE(SC_NOTE_HANDLE));
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_SOURCE(SC_NOTE_SOURCE));
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_LAYOUT(L4,15,34));
	Ft_App_WrCoCmd_Buffer(phost,BITMAP_SIZE(NEAREST,BORDER,BORDER,30,34));		
	Ft_Gpu_CoCmd_SetFont(phost, SC_NOTE_HANDLE, SC_NOTE_FILE_ADDR);	
}




ft_void_t Play_Sound(ft_uint8_t sound,ft_uint8_t volume)
{
  Ft_Gpu_Hal_Wr8(phost,REG_VOL_SOUND,volume);
  Ft_Gpu_Hal_Wr8(phost,REG_SOUND,sound);
  Ft_Gpu_Hal_Wr8(phost,REG_PLAY,1);
}	

static ft_bool_t istouch()
{
	ft_int16_t x,y;
	x = (Ft_Gpu_Hal_Rd32(phost,REG_TOUCH_SCREEN_XY) >> 16) & 0xffff;
	y = Ft_Gpu_Hal_Rd32(phost,REG_TOUCH_SCREEN_XY) & 0xffff;

	if (x>=0 && x<=FT_DispWidth-1)
		if (y>=0 && y<=FT_DispHeight-1)
			return TRUE;
	return false;
}



static ft_uint8_t Read_Keypad()
{
  static ft_uint8_t temp_tag=0;	
  ft_uint8_t Read_tag = 0;

  Read_tag = Ft_Gpu_Hal_Rd8(phost,REG_TOUCH_TAG);
  Flag.Key_Detect = 0;

  if(Read_tag)								// Allow if the Key is released
  {
	Flag.Key_Detect = 1; 

    if(temp_tag != Read_tag)
    {
	  //First touch
      temp_tag = Read_tag;		
      Play_Sound(0x51,100);      	  
    }
  }
  else
  {
	//Key is released
    if((temp_tag != 0) && !istouch())
    {	
      Read_tag = temp_tag;
	  Flag.Key_Detect = 2; 
    }
	temp_tag = 0;
  }

  return Read_tag;
}


static ft_void_t Display_Candidates(ft_uint8_t handle, ft_uint8_t index,ft_uint8_t index_pressed)
{
#define MAX_CHARS_PERLINE   10
	ft_char8_t str2disp[MAX_CHARS_PERLINE+1];
	ft_int32_t i;
	str2disp[MAX_CHARS_PERLINE] = '\x00';
	for (i=0;i<MAX_CHARS_PERLINE;i++)
		str2disp[i] = index + i + 1;
	
	Ft_Gpu_CoCmd_Keys(phost,0,(FT_DispHeight*0.30),FT_DispWidth,(FT_DispHeight*0.15),handle,0 | index_pressed,(const ft_char8_t*)str2disp);
}

ft_void_t display_notepad(ft_uint16_t startLine)
{
	ft_uint16_t i,j;
	ft_int16_t baseX=0,baseY=0;
	ft_uint16_t currentCode;

	Ft_App_WrCoCmd_Buffer(phost,TAG_MASK(0));
	Ft_App_WrCoCmd_Buffer(phost,BEGIN(BITMAPS));

	for (i=startLine;i<MAX_LINES;i++)
	{		
		baseX = 0;
		for (j=0;j<MAX_COLS;j++)
		{													
			currentCode = Buffer.notepad[i][j];
			if (currentCode ==0)
			{
				break;
			}					

			if (currentCode >= 269)
			{
				
				if ((!showCursor && currentCode == CURSOR_CELL_CODE))
				{
				}else
				{
					Ft_App_WrCoCmd_Buffer(phost,VERTEX2II(baseX,baseY,6,currentCode - 268));
				}

			    if (currentCode == CURSOR_CELL_CODE)
				{
					return;
				}

			}
			else
			{
				if (currentCode%60)
					Ft_App_WrCoCmd_Buffer(phost,VERTEX2II(baseX,baseY,currentCode/60+1,currentCode%60));
				else
					Ft_App_WrCoCmd_Buffer(phost,VERTEX2II(baseX,baseY,currentCode/60,60));
			}
			baseX += 30;//30 pixel is the width of character
		}
		baseY += 34; //34 pixel is the height of character
	}
}


ft_uint8_t find_lastChar(ft_uint8_t line)
{
	int i=0;
	for (i=0;i<MAX_COLS;i++)
		if (((Buffer.notepad[line][i] == 0)) || (Buffer.notepad[line][i] == CURSOR_CELL_CODE))
			return i;
}


ft_void_t update_notepad_buff(ft_uint8_t Read_sfk,ft_uint8_t   Candidate_Handle)
{

	switch (Read_sfk){
		case TOGGLE_BUTTON:
			//Toggle key for simplified Chinese and Traditional chinese
			break;
		case ENTER_BUTTON:
			//Enter Key
			Buffer.notepad[currentLine][currentCol] = 0;
			
			currentLine ++;
			currentCol = 0;

			if (currentLine == MAX_LINES)
			{
				currentLine = MAX_LINES - 1;
				currentCol = find_lastChar(currentLine);
			}
			Buffer.notepad[currentLine][currentCol] = CURSOR_CELL_CODE;
			break;
		case SPACE_BUTTON:
			//Space Key
			Buffer.notepad[currentLine][currentCol] = 269;
			currentCol ++;
			if (currentCol > 14)
			{
				currentLine ++;
				currentCol = 0;
			}
			if (currentLine == MAX_LINES)
			{
				currentLine = MAX_LINES - 1;
				currentCol = find_lastChar(currentLine);
			}
			
			Buffer.notepad[currentLine][currentCol] = CURSOR_CELL_CODE;
		    break;
		case BACK_SPACE:
			//Backspace(delete) key
			Buffer.notepad[currentLine][currentCol] = 0;

			if (currentCol>0)
				currentCol --;
			else
			{
				if (currentLine>0)
				{
					currentLine --;
					currentCol = find_lastChar(currentLine);
					
				}
			}
			Buffer.notepad[currentLine][currentCol] = CURSOR_CELL_CODE;

			break;
		case INPUT_DONE:
			//Done button
			break;
		default:
			//Other key
			Buffer.notepad[currentLine][currentCol] = (Candidate_Handle -1) * 60 + Read_sfk;
			currentCol ++;
			if (currentCol >= MAX_COLS)
			{
				currentLine ++;
				currentCol = 0;
			}

			if (currentLine == MAX_LINES)
			{
				currentLine = MAX_LINES - 1;
				currentCol = find_lastChar(currentLine);
			}
			Buffer.notepad[currentLine][currentCol] = CURSOR_CELL_CODE;
			break;
	}
}

//display all the characters in a new frame with scrolling way
ft_void_t display_note()
{
	ft_int16_t i,j;
	ft_int16_t baseX=0,baseY=0;

	ft_int16_t startY=0;
	ft_uint16_t currentCode;
    
	for (;;)
	{
		Ft_Gpu_CoCmd_Dlstart(phost); 
		Ft_App_WrCoCmd_Buffer(phost,CLEAR_COLOR_RGB(100,100,100));        
		Ft_App_WrCoCmd_Buffer(phost,CLEAR(1,1,1));	
		Ft_App_WrCoCmd_Buffer(phost,COLOR_RGB(255,255,255));

		baseY = startY;
		{
			Ft_App_WrCoCmd_Buffer(phost,TAG_MASK(0));
			Ft_App_WrCoCmd_Buffer(phost,BEGIN(BITMAPS));

			for (i=0;i<MAX_LINES;i++)
			{		
				baseX = 0;
				for (j=0;j<MAX_COLS;j++)
				{													
					currentCode = Buffer.notepad[i][j];
					if (currentCode ==0)
					{
						break;
					}					

					if (currentCode >= 269)
					{
				
						if ((!showCursor && currentCode == CURSOR_CELL_CODE))
						{
						}else
						{
							Ft_App_WrCoCmd_Buffer(phost,BITMAP_HANDLE(6));
							Ft_App_WrCoCmd_Buffer(phost,CELL(currentCode - 268));
							Ft_App_WrCoCmd_Buffer(phost,VERTEX2F(baseX*16,baseY*16));
						}

						if (currentCode == CURSOR_CELL_CODE)
						{
							//return;
							goto ___exit;
						}

					}
					else
					{
						if (currentCode%60)
						{
							Ft_App_WrCoCmd_Buffer(phost,BITMAP_HANDLE(currentCode/60+1));
							Ft_App_WrCoCmd_Buffer(phost,CELL(currentCode%60));
							Ft_App_WrCoCmd_Buffer(phost,VERTEX2F(baseX*16,baseY*16));
						}
						else
						{
							Ft_App_WrCoCmd_Buffer(phost,BITMAP_HANDLE(currentCode/60));
							Ft_App_WrCoCmd_Buffer(phost,CELL(60));
							Ft_App_WrCoCmd_Buffer(phost,VERTEX2F(baseX*16,baseY*16));
						}
					}
					baseX += 30;
				}
				baseY += 34;
			}
		}

___exit:
		Ft_App_WrCoCmd_Buffer(phost,DISPLAY());
		Ft_Gpu_CoCmd_Swap(phost);
		Ft_App_Flush_Co_Buffer(phost);
		Ft_Gpu_Hal_WaitCmdfifo_empty(phost);
		
		if (istouch())
			break;


		if (startY-- < (-34L*(i+1)))
			startY = FT_DispHeight;	
	}
}

ft_void_t clear_notepad_buff()
{
  ft_uint16_t tval;
  for(tval=0;tval<MAX_LINES;tval++)
	memset(&Buffer.notepad[tval],'\0',sizeof(Buffer.notepad[tval]));

  Buffer.notepad[0][0] = CURSOR_CELL_CODE;
}

void Notepad(void)
{

  /*local variables*/
  const ft_uint8_t   keypad_font = 27;

  ft_uint16_t Disp_pos = 0,But_opt =0;
  ft_uint8_t Read_sfk=0;	
  ft_uint8_t   Candidate_Handle = 0;
  ft_uint8_t   Candidate_Index = 0;
  
  clear_notepad_buff();
 
  {
        download_bmpfile(sc_flag);
	Ft_Gpu_CoCmd_Dlstart(phost); 
	Ft_App_WrCoCmd_Buffer(phost,CLEAR_COLOR_RGB(100,100,100));        
	Ft_App_WrCoCmd_Buffer(phost,CLEAR(1,1,1));	
	Ft_App_WrCoCmd_Buffer(phost,COLOR_RGB(255,255,255));

	setup_bmp();

	Ft_App_WrCoCmd_Buffer(phost,DISPLAY());
	Ft_Gpu_CoCmd_Swap(phost);
	Ft_App_Flush_Co_Buffer(phost);
	Ft_Gpu_Hal_WaitCmdfifo_empty(phost);
  }

  Flag.Display_candiate = 0;
  Read_sfk = 0;
  do
  {	
        showCursor = TRUE;
	// Display List start 
	Ft_Gpu_CoCmd_Dlstart(phost); 
	Ft_App_WrCoCmd_Buffer(phost,CLEAR_COLOR_RGB(100,100,100));        
	Ft_App_WrCoCmd_Buffer(phost,CLEAR(1,1,1));	
	Ft_App_WrCoCmd_Buffer(phost,COLOR_RGB(255,255,255));

	Ft_App_WrCoCmd_Buffer(phost,TAG_MASK(1));            // enable tagbuffer updation
	Ft_Gpu_CoCmd_FgColor(phost,0x101010);

	if (((Read_sfk>='A') && (Read_sfk<='Z') && (1==Flag.Key_Detect)))
	{
		if ((Read_sfk>='A') && (Read_sfk<='F'))
		{
			//Handle_A_F
			Candidate_Handle = A_F_HANDLE;Candidate_Index = (Read_sfk - 'A') * 10;
		}
		if ((Read_sfk>='G') && (Read_sfk<='L'))
		{
			//Handle_G_L
			Candidate_Handle = G_L_HANDLE;Candidate_Index = (Read_sfk - 'G') * 10;
		}
		if ((Read_sfk>='M') && (Read_sfk<='R'))
		{
			//Handle_M_R
			Candidate_Handle = M_R_HANDLE;Candidate_Index = (Read_sfk - 'M') * 10;
		}
		if ((Read_sfk>='S') && (Read_sfk<='X'))
		{
			//Handle_S_X
			Candidate_Handle = S_X_HANDLE;Candidate_Index = (Read_sfk - 'S') * 10;
		}
		if ((Read_sfk>='Y') && (Read_sfk<='Z'))
		{
			//Handle_Y_Z
			Candidate_Handle = Y_Z_HANDLE;Candidate_Index = (Read_sfk - 'Y') * 10;
		}
		Flag.Display_candiate = 1;
	}

	if (1==Flag.Display_candiate)
	{
		
		if (((Read_sfk >=1) && (Read_sfk <=60))  || 
			(Read_sfk>=TOGGLE_BUTTON))
		{
			if (1==Flag.Key_Detect)
				Display_Candidates(Candidate_Handle,Candidate_Index,Read_sfk);

			if (2==Flag.Key_Detect)
			{
				//Key is released and now update the notepad buffer
				update_notepad_buff(Read_sfk,Candidate_Handle);
				Display_Candidates(Candidate_Handle,Candidate_Index,0);
			}
		}else
		{
			Display_Candidates(Candidate_Handle,Candidate_Index,0);
		}
	}

	display_notepad(currentLine>1 ? currentLine - 1:0);

	Ft_App_WrCoCmd_Buffer(phost,TAG_MASK(1));            // enable tagbuffer updation

	//Toggle for traditional Chinese and simplified chinese
	Ft_App_WrCoCmd_Buffer(phost,TAG(TOGGLE_BUTTON));	
	But_opt = (Read_sfk== TOGGLE_BUTTON)? OPT_FLAT:0;
	if (TOGGLE_BUTTON == Read_sfk  && 2==Flag.Key_Detect)
	{
		if (sc_flag == 0)
		{
			sc_flag = 65535;	
		}
		else
		{
			sc_flag = 0;		
		}
		download_bmpfile(sc_flag);
	}
	Ft_Gpu_CoCmd_Toggle(phost,FT_DispWidth*0.040,(FT_DispHeight*0.89),(FT_DispWidth*0.07),Y_Z_HANDLE,But_opt,sc_flag,"\x19\xff\x1A");

	// BackSpace
	Ft_App_WrCoCmd_Buffer(phost,TAG(BACK_SPACE));												
	But_opt = (Read_sfk== BACK_SPACE)? OPT_FLAT:0;
	Ft_Gpu_CoCmd_Button(phost,FT_DispWidth*0.875,(FT_DispHeight*0.70),(FT_DispWidth*0.125),(FT_DispHeight*0.112),29,But_opt,"<--");	
	
	
	// Space Button
	Ft_App_WrCoCmd_Buffer(phost,TAG(SPACE_BUTTON));											
	But_opt = (Read_sfk== SPACE_BUTTON)? OPT_FLAT:0;
	Ft_Gpu_CoCmd_Button(phost,(FT_DispWidth*0.170),(FT_DispHeight*0.83),(FT_DispWidth*0.65),(FT_DispHeight*0.12),Y_Z_HANDLE,But_opt,"\x15\x16");


	//construct the keypad
	Ft_Gpu_CoCmd_Keys(phost,0,(FT_DispHeight*0.442),FT_DispWidth,(FT_DispHeight*0.112),keypad_font,Read_sfk,"QWERTYUIOP");
	Ft_Gpu_CoCmd_Keys(phost,(FT_DispWidth*0.042),(FT_DispHeight*0.57),(FT_DispWidth*0.96),(FT_DispHeight*0.112),keypad_font,Read_sfk,"ASDFGHJKL");
	Ft_Gpu_CoCmd_Keys(phost,(FT_DispWidth*0.132),(FT_DispHeight*0.70),(FT_DispWidth*0.73),(FT_DispHeight*0.112),keypad_font,Read_sfk,"ZXCVBNM");	

	//Enter Button
	Ft_App_WrCoCmd_Buffer(phost,TAG(ENTER_BUTTON));	
	But_opt = (Read_sfk== ENTER_BUTTON)? OPT_FLAT:0;
	Ft_Gpu_CoCmd_Button(phost,FT_DispWidth*0.001,(FT_DispHeight*0.70),(FT_DispWidth*0.124),(FT_DispHeight*0.112),Y_Z_HANDLE,But_opt,"\x1B\x1C");

	//Done Button
	Ft_App_WrCoCmd_Buffer(phost,TAG(INPUT_DONE));														
	But_opt = (Read_sfk== INPUT_DONE)?  OPT_FLAT:0;          
	Ft_Gpu_CoCmd_Button(phost,(FT_DispWidth*0.855),(FT_DispHeight*0.83),(FT_DispWidth*0.146),(FT_DispHeight*0.12),Y_Z_HANDLE,But_opt,"\x17\x18");	

	Ft_App_WrCoCmd_Buffer(phost,DISPLAY());
	Ft_Gpu_CoCmd_Swap(phost);

	
	Ft_App_Flush_Co_Buffer(phost);
	Ft_Gpu_Hal_WaitCmdfifo_empty(phost);

	//Input is done , now display all the input characters
	if (INPUT_DONE == Read_sfk && 2==Flag.Key_Detect)
	{
		showCursor = false;
		display_note();

		currentLine = currentCol = 0;
		Flag.Display_candiate = 0;
		clear_notepad_buff();
	}

	Read_sfk = Read_Keypad();                // read the keys   
 }while(1);		

}




#ifdef MSVC_PLATFORM
/* Main entry point */
ft_int32_t main(ft_int32_t argc,ft_char8_t *argv[])
#endif
#ifdef ARDUINO_PLATFORM
ft_void_t setup()
#endif
{
	Ft_Gpu_HalInit_t halinit;
	
	halinit.TotalChannelNum = 1;

              
	Ft_Gpu_Hal_Init(&halinit);
	host.hal_config.channel_no = 0;
#ifdef MSVC_PLATFORM_SPI
	host.hal_config.spi_clockrate_khz = 12000; //in KHz
#endif
#ifdef ARDUINO_PLATFORM_SPI
	host.hal_config.spi_clockrate_khz = 4000; //in KHz
#endif
        Ft_Gpu_Hal_Open(&host);
        
              
	phost = &host;

    Ft_BootupConfig();
    
    Serial.begin(9600);

	/*
	printf("reg_touch_rz =0x%x ", Ft_Gpu_Hal_Rd16(phost, REG_TOUCH_RZ));
	printf("reg_touch_rzthresh =0x%x ", Ft_Gpu_Hal_Rd32(phost, REG_TOUCH_RZTHRESH));
	printf("reg_touch_tag_xy=0x%x",Ft_Gpu_Hal_Rd32(phost, REG_TOUCH_TAG_XY));
	printf("reg_touch_tag=0x%x",Ft_Gpu_Hal_Rd32(phost, REG_TOUCH_TAG));
	*/


    /*It is optional to clear the screen here*/	
    Ft_Gpu_Hal_WrMem(phost, RAM_DL,(ft_uint8_t *)FT_DLCODE_BOOTUP,sizeof(FT_DLCODE_BOOTUP));
    Ft_Gpu_Hal_Wr8(phost, REG_DLSWAP,DLSWAP_FRAME);
    
    Ft_Gpu_Hal_Sleep(1000);//Show the booting up screen. 
    
  SD.begin(FT_SDCARD_CS); 
  SPI.setClockDivider(SPI_CLOCK_DIV2);
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0); 
      

	home_setup();
	Info();
	Notepad();

	/* Close all the opened handles */
    Ft_Gpu_Hal_Close(phost);
    Ft_Gpu_Hal_DeInit();
#ifdef MSVC_PLATFORM
	return 0;
#endif
}

void loop()
{
}



/* Nothing beyond this */













