#include "p_apps.h"
#include "PalmChip.h"

#if defined RES_BR
#include "lcd_br.c"
#elif defined RES_CZ
#include "lcd_cz.c"
#elif defined RES_DE
#include "lcd_de.c"
#elif defined RES_ES || defined RES_AR || defined RES_CL
#include "lcd_es.c"
#elif defined RES_ES_C
#include "lcd_es_c.c"
#elif defined RES_FR || defined RES_BE_F || defined RES_CA_F
#include "lcd_fr.c"
//#elif defined RES_HU
//#include "lcd_hu.c"
#elif defined RES_IT
#include "lcd_it.c"
#elif defined RES_NL || defined RES_BE_N || defined RES_ZA_N
#include "lcd_nl.c"
#elif defined RES_PL
#include "lcd_pl.c"
#elif defined RES_PT
#include "lcd_pt.c"
#else
#include "lcd_us.c"
#endif

#if defined LCD_HY1602 || defined LCD_HY1604 || defined LCD_GPM227A0
#define KS0066
#endif

#ifdef KS0066
void lcd_init()
{
	DCHAR i;

	for (i = 0; i < 3; i ++)
	{	// Set function mode
		write_control_byte(0x30);
	}
	
#ifdef LCD_GPM227A0	
	write_control_byte(0x20);       // set to 4-bit operation
	write_control_byte(0x28);	// set to 4-bit and select 2-line display line and character font
#else
	write_control_byte(0x38);	// set work mode, 8-bit 2-line 5*7
#endif
	write_control_byte(0x01);	// clear screen
	write_control_byte(0x06);	// set input method
	write_control_byte(0x0f);	// set display method, show cursor
	write_control_byte(0x14);	// set display method
	write_control_byte(0x80);
}
#endif

void DisplayInitialize()
{
//	XBYTE[CLK_ENAB2] |=	0x80;		// Enable LCD clock
//	XBYTE[DF_HS_LCD_MUX] &= 0x02;	// LCD data bus mux

	XBYTE[LCD_MODE] = 0x01;			// Reset the FSM
	XBYTE[LCD_MODE] = 0x00;
	XBYTE[LCD_READ_WAIT] = 0x7f;	// Setup the waiting cycle for reading
	XBYTE[LCD_WRITE_WAIT] = 0x7f;	// Setup the waiting cycle for writing

#ifdef KS0066
	lcd_init();
#endif
}

void DisplayCursor(BOOLEAN bShow)
{
#ifdef KS0066
	write_control_byte(bShow ? 0x0f : 0x0c);
#endif
}

void Display(PXCHAR pBuf, UCHAR iLine, UCHAR iPos, BOOLEAN bPadding)
{
	DCHAR i, iLen;
	XCHAR pDisplay[DISPLAY_MAX_CHAR];

#ifdef KS0066
#ifdef LCD_HY1604
	static CCHAR _cWriteControl[4] = {0x80, 0xc0, 0x90, 0xd0};		// line DDRAM address
#else
	static CCHAR _cWriteControl[2] = {0x80, 0xc0};		// line DDRAM address
#endif
	DCHAR iCtrl;
	iCtrl = _cWriteControl[iLine] + iPos;
#endif

//	DebugString(pBuf);

	iLen = p_strlen_x(pBuf);
	i = iLen + iPos;
	if (i < DISPLAY_MAX_CHAR)
	{
		if (iLen)
		{
			p_memcpy_x2x((PXCHAR)(pDisplay+iPos), pBuf, iLen);
		}
		p_memset_x((PXCHAR)(pDisplay+i), ' ', (UCHAR)(DISPLAY_MAX_CHAR-i));
	}
	else if (i == DISPLAY_MAX_CHAR)
	{
		if (iLen)
		{
			p_memcpy_x2x((PXCHAR)(pDisplay+iPos), pBuf, iLen);
		}
	}
	else
	{
		p_memcpy_x2x(pDisplay, pBuf, DISPLAY_MAX_CHAR);
	}

#ifdef KS0066
	write_control_byte(iCtrl);
	for (i = iPos; i < DISPLAY_MAX_CHAR; i ++)
	{
		write_data_byte(pDisplay[i]);
	}

	if (!bPadding)
	{
		write_control_byte(iCtrl+iLen);
	}
#else
	SimDisplay(pDisplay, iLine);
#endif
}

void DisplayLine(PXCHAR pBuf, UCHAR iLine)
{
	Display(pBuf, iLine, 0, TRUE);
}

void DisplayString(PCCHAR pDisplay, UCHAR iLine)
{
	XCHAR pBuf[DISPLAY_MAX_CHAR+1];

	p_memcpy_c2x_0(pBuf, pDisplay, DISPLAY_MAX_CHAR);
	DisplayLine(pBuf, iLine);
}

void DisplayVal(USHORT iVal, PCCHAR pPrefix, UCHAR iLine)
{
	XCHAR pBuf[DISPLAY_MAX_CHAR+1];

	p_itoa(iVal, pBuf, 10);
	if (p_strlen_c(pPrefix) + p_strlen_x(pBuf) < DISPLAY_MAX_CHAR)
	{	// only display pPrefix when display length is enough
		p_strcpy_c2x(pBuf, pPrefix);
		p_strcat_char2x(pBuf, ':');
		p_itoa(iVal, (PXCHAR)(pBuf+p_strlen_x(pBuf)), 10);
	}
	DisplayLine(pBuf, iLine);
}

void DisplayStatus(PCCHAR pStatus, UCHAR iStatus, UCHAR iNum)
{
	DCHAR iVal, iStatusVal;
	XCHAR pBuf[DISPLAY_MAX_CHAR+1];

	iStatusVal = iStatus;
	iVal = iNum;

	if (iStatusVal != 255)
	{
		DisplayVal(iStatus, pStatus, 0);
	}
	else
	{
		DisplayString(pStatus, 0);
	}

	if (iVal > DISPLAY_MAX_CHAR)	iVal = DISPLAY_MAX_CHAR;
	if (iVal)
	{
		p_memset_x(pBuf, 0xff, iVal);
	}
	pBuf[iVal] = 0;
	DisplayLine(pBuf, 1);
}


