/*-------------------------------------------------------------------------
   ADC key function copy right information

   Copyright (C) 2006-2008. Lin, Rongrong <woody@palmmicro.com>
                            Lin, Guofeng  <alanda@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 "version.h"
#include "type.h"
#include "core.h"
#include "apps.h"

#include "bank1.h"

UCHAR _iHandsetDownCounter;

void _HandleHandsetDown(UCHAR iCount)
{
	_iHandsetDownCounter ++;
	if (_iHandsetDownCounter >= iCount)
	{
		OnHandsetDown();
		_iHandsetDownCounter = 0;
	}
}

#ifdef KEY_ADC

volatile UCHAR _pADC_KeyVal[KEY_ADC_STAGE];
volatile UCHAR _pADC_KeyVal2[KEY_ADC_STAGE];
volatile UCHAR _iADC_KeyStage, _iADC_KeyStage2;

UCHAR _iADC_OldKey, _iADC_OldKey2;

void ADC_KeyStart()
{
	_iADC_KeyStage = 0;
	_iADC_KeyStage2 = 0;
	_iADC_OldKey = 0;
	_iADC_OldKey2 = 0;
	memset(_pADC_KeyVal, 0, KEY_ADC_STAGE);
	memset(_pADC_KeyVal2, 0, KEY_ADC_STAGE);

	_iHandsetDownCounter = 0;
}

#ifdef KEY_ADC_2X7	//	7x2 ADC keys
#define KEY_ADC_MAX		7
const UCHAR _cADC_KeyLimits[] = {0x00, 0x01, 0x34, 0x5c, 0x7f, 0xa2, 0xca, 0xff};
#else				//	11x2 ADC keys
#define KEY_ADC_MAX		11
const UCHAR _cADC_KeyLimits[] = {0x00, 0x01, 0x22, 0x41, 0x59, 0x6f, 0x81, 0x94, 0xa9, 0xc1, 0xdd, 0xff};
#endif

UCHAR _ADC_GetKey(UCHAR iVal)
{
	UCHAR i;

	iVal -= 0x7f;
	for (i = 0; i < KEY_ADC_MAX; i ++)
	{
		if (iVal > _cADC_KeyLimits[i] && iVal <= _cADC_KeyLimits[i+1])		break;
	}
	return i;
}

UCHAR _ADC_JudgeKey(PCHAR pVals)
{
	UCHAR i, iVal, iKey;
	UCHAR pArray[KEY_ADC_MAX+1];

	memset(pArray, 0, KEY_ADC_MAX+1);
	for (i = 0; i < KEY_ADC_STAGE; i ++)
	{
		iKey = _ADC_GetKey(pVals[i]);
		pArray[iKey] ++;
	}

	iKey = 0;
	iVal = 0;
	for (i = 0; i <= KEY_ADC_MAX; i ++)
	{
		if (pArray[i] > iVal)
		{
			iVal = pArray[i];
			iKey = i;
		}
	}
	return iKey;
}

BOOLEAN _bIsADC_HandsetKey(UCHAR iKey)
{
#ifdef KEY_ADC_2X7	//	7x2 ADC keys
	if (iKey == 'v')	return TRUE;
#else				//	7x11 ADC keys
	if (iKey == 'z')	return TRUE;
#endif
	return FALSE;
}

void ADC_KeyRun()
{
//	UCHAR i;
	UCHAR iKey;

	if (_iADC_KeyStage == KEY_ADC_STAGE)
	{
		_iADC_KeyStage = 0;
		iKey = _ADC_JudgeKey(_pADC_KeyVal);
/*		for (i = 0; i < KEY_ADC_STAGE; i ++)
		{
			UdpDebugVal((UCHAR)(_pADC_KeyVal[i]-0x7f), 16);
		}
*/
		if (iKey == KEY_ADC_MAX)
		{
			_iADC_OldKey = 0;
		}
		else
		{
			iKey += 'e';
			if (_iADC_OldKey != iKey)
			{
				_iADC_OldKey = iKey;
				UI_HandleKeys(iKey);
			}
		}
	}
	if (_iADC_KeyStage2 == KEY_ADC_STAGE)
	{
		_iADC_KeyStage2 = 0;
		iKey = _ADC_JudgeKey(_pADC_KeyVal2);

		if (iKey == KEY_ADC_MAX)
		{
			_HandleHandsetDown(2);
			_iADC_OldKey2 = 0;
		}
		else
		{
			_iHandsetDownCounter = 0;
			iKey += 'p';
			if (_bIsADC_HandsetKey(iKey))
			{
				OnHook();
				_iADC_OldKey2 = 0;
			}
			else
			{
				if (_iADC_OldKey2 != iKey)
				{
					_iADC_OldKey2 = iKey;
					UI_HandleKeys(iKey);
				}
			}
		}
	}
}

#endif	// ADC_KEY

#if defined HOOK_GPIO

extern volatile UCHAR _iGPIO_Hook;
extern volatile BOOLEAN _bHook;

void HookStart()
{
	_iHandsetDownCounter = 0;
	_iGPIO_Hook = 0x04;
	_bHook = FALSE;
}

void HookRun()
{
	if (!_bHook)	return;

	if (_iGPIO_Hook & 0x04)
	{
		_HandleHandsetDown(12);
	}
	else
	{
		_iHandsetDownCounter = 0;
		OnHook();
	}

	_bHook = FALSE;
}
	
#endif	// HOOK_GPIO

#ifdef SLIC_79R70

extern volatile UCHAR _iGPIO_Hook;
extern volatile BOOLEAN _bHook;
extern BOOLEAN SLIC_bFirstRing, SLIC_bTransCID;

void HookStart()
{
	_iHandsetDownCounter = 0;
	_iGPIO_Hook = 0x10;
	_bHook = FALSE;

	SLIC_bFirstRing = FALSE;
	SLIC_bTransCID = FALSE;
}

void Gateway_KeyRun()
{
	if (!_bHook)	return;

	// hook detection
	if (_iGPIO_Hook & 0x10)
	{
		_HandleHandsetDown(12);
	}
	else
	{
		_iHandsetDownCounter = 0;
		OnHook();
	}

	_bHook = FALSE;
	// safemode key detection
}

#endif	// SLIC_79R70
