/*-------------------------------------------------------------------------
   AR168M demo external controller MCS51
   UI function copy right information

   Copyright (C) 2008. Lin, Rongrong <woody@palmmicro.com>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This software is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-------------------------------------------------------------------------*/

#include "type.h"
#include "8051.h"
#include "sys.h"

#define MODE_ZERO		0
#define MODE_COMMAND	1
#define MODE_DATA		2

#define COMMAND_LEN		4
#define MAX_DATA_LEN	24

DCHAR _iMode, _iCommandPos, _iDataPos;
DCHAR _pCommand[COMMAND_LEN];
DCHAR _pData[MAX_DATA_LEN + 1];

void UI_Init()
{
	_iMode = MODE_ZERO;
	_iCommandPos = _iDataPos = 0;
}

BOOLEAN _isprint(UCHAR iVal) 
{
	return (iVal >= 0x20 && iVal < 0x7f) ? TRUE : FALSE;
}

const CCHAR _pKey[] = "KEY ";
const CCHAR _pLcd[] = "LCD ";
const CCHAR _pLcdCursor[] = "LCDC";
const CCHAR _pLed[] = "LED ";
const CCHAR _pLoop[] = "LOOP";

void _Padding()
{
	DCHAR i;

	for (i = 0; i < 4; i ++)
	{
		UART_SendChar(0);
	}
}

void _SendCommand(PCCHAR pCommand)
{
	DCHAR i;

	for (i = 0; i < COMMAND_LEN; i ++)
	{
		UART_SendChar(pCommand[i]);
	}
}

void _SendData(PDCHAR pData)
{
	DCHAR i;

	for (i = 0; i < MAX_DATA_LEN; i ++)
	{
		UART_SendChar(pData[i]);
		if (!pData[i])
		{
			break;
		}
	}
}

BOOLEAN _CompareCommand(PCCHAR p)
{
	return memcmp_c2d(_pCommand, p, COMMAND_LEN) ? FALSE : TRUE;
}

void _HandleData()
{
	DCHAR iVal;

	if (_CompareCommand(_pLcd))
	{
		LcdDisplay((PDCHAR)(_pData + 1), _pData[0] - '0');
	}
	else if (_CompareCommand(_pLcdCursor))
	{
		LcdCursor(_pData[0] - '0', _pData[1] - '0', (BOOLEAN)(_pData[2] - '0'));
	}
	else if (_CompareCommand(_pLed))
	{
		iVal = _pData[0] - '0';
		switch (_pData[1])
		{
		case '0':
			LED_On(iVal);
			break;

		case '1':
			LED_Off(iVal);
			break;

		case '2':
			LED_Blink(iVal);
			break;
		}
	}
	else if (_CompareCommand(_pLoop))
	{
		_SendCommand(_pLoop);
		_SendData(_pData);
		_Padding();
	}
}

void UI_HandleSerialChar(UCHAR iVal)
{
//	UART_SendChar(iVal);	// Simple loop back
	
	// Analyze it!
	if (_iMode == MODE_COMMAND)
	{
		if (_iCommandPos < COMMAND_LEN)
		{
			if (_isprint(iVal))
			{
				_pCommand[_iCommandPos] = iVal;
				_iCommandPos ++;
			}
			else
			{
				_iMode = MODE_ZERO;
			}
		}
		else
		{
			if (iVal)
			{
				_iMode = MODE_DATA;
				_pData[0] = iVal;
				_iDataPos = 1;
			}
			else
			{
				_iMode = MODE_ZERO;
			}
		}
	}
	else if (_iMode == MODE_DATA)
	{
		if (iVal)
		{
			if (_iDataPos < MAX_DATA_LEN)
			{
				_pData[_iDataPos] = iVal;
				_iDataPos ++;
			}
		}
		else
		{
			_pData[_iDataPos] = 0;
			_HandleData();
			_iMode = MODE_ZERO;
		}
	}
	else	// MODE_ZERO
	{
		if (_isprint(iVal))
		{
			_iMode = MODE_COMMAND;
			_pCommand[0] = iVal;
			_iCommandPos = 1;
		}
	}
}

void UI_HandleKey(UCHAR iKey)
{
	DCHAR pBuf[2];

	if (!iKey)	return;

	pBuf[0] = iKey;
	pBuf[1] = 0;
#ifdef SYS_DEBUG
	LcdDisplay(pBuf, 0);
#endif

	_SendCommand(_pKey);
	_SendData(pBuf);
	_Padding();
}
