#include "Page1.h"
#include "PalmChip.h"
#include "p_dsp.h"
#include "p_rtp.h"

#include "v_task.h"

#define SDRAM_PLAY_NUMBER_MAX	999
#define SDRAM_PLAY_NUMBER_NONE	1000

void SdramStartup()
{
	// read flags first
	SdramReadFlags();

// load voice message length
#ifdef CALL_MGCP
	Sys_iDigitMapNum = 0;
#else
	Sys_iDigitMapNum = X_VAL(Sdram_pDataCache, FLAGS_MAP_NUMBER);
#endif

#ifdef _USE_FXS
	Sys_iDeviceAttr = DEVICE_ATTR_NONE;
#else
	Sys_iDeviceAttr = DEVICE_ATTR_SPEAKER;
#endif
#ifdef _USE_FAKE_FXO
	Sys_iDeviceAttr |= DEVICE_ATTR_DUALMODE;
#endif
	SdramUpdateFlagByte(FLAGS_DEVICE_ATTR, Sys_iDeviceAttr);

	// read options in the second step, because it will use flags to adjust options
	SysReadOptions();

	// clear necessary sdram buffers
	SdramClearDataCache();
	SdramWriteData(OPTIONS_SDRAM_POS+KEY_PREVBUF_SDRAM_LO, MAX_KEYBUF_LEN*2);
}

void SdramWriteFile(UCHAR iIndexHigh, UCHAR iIndexLow, USHORT iLength)
{
	DCHAR iTmp;

	while (iLength >= 256)
	{
		SdramRead(iIndexHigh, iIndexLow, SRAM_DMA_HALF_DWORD);
		SoloFileWriteSdramCache((UCHAR)256);
		iLength -= 256;
		iIndexLow ++;
	}

	iTmp = (UCHAR)iLength;
	if (iTmp)
	{
		SdramRead(iIndexHigh, iIndexLow, (UCHAR)(iTmp>>2));
		SoloFileWriteSdramCache(iTmp);
	}
}

BOOLEAN SdramFileCreate()
{
	SoloFileCloseRead();
	return SoloFileOpen(PLAY_SDRAM_HI, TRUE, FILE_ONE_PAGE_SIZE);
}


void SdramWriteMsg(UCHAR iMsgIndex)
{
	SdramRead(OPTIONS_SDRAM_HI, IVR3_SDRAM_LO, SRAM_DMA_HALF_DWORD);
	SdramWriteFile(IVR_SDRAM_HI, (UCHAR)(iMsgIndex*IVR_UNIT_SDRAM_NUM), PXCHAR2USHORT((PXCHAR)(Sdram_pDataCache+(UCHAR)(iMsgIndex<<1))));
}

#ifdef RES_CN
void SdramWriteDigit(UCHAR iDigit)
{
	if (iDigit == 1)
	{
		SdramWriteMsg(IVR_MSG_ONE);
	}
	else
	{
		SdramWriteMsg(iDigit);
	}
}
#else
#define SdramWriteDigit	SdramWriteMsg
#endif

void SdramWriteStrings(PXCHAR pString)
{
	DCHAR i, iTmp;

	i = 0;
	while (1)
	{
		iTmp = pString[i];
		if (iTmp)
		{
			if (iTmp >= '0' && iTmp <= '9')
			{
				SdramWriteDigit((UCHAR)(iTmp-'0'));
			}
			else if (iTmp == '*' || iTmp == '.')
			{
				SdramWriteMsg(IVR_MSG_DOT);
			}
		}
		else
		{
			return;
		}
		i ++;
	}
}

#ifdef RES_CN
void SdramWriteIndex(USHORT iIndex)
{
	DCHAR iCur;

	iCur = (UCHAR)iIndex;
	if (iIndex >= 100)
	{
		if (iIndex >= 200 && iIndex < 300)
		{
			iCur = iIndex - 200;
			SdramWriteMsg(IVR_MSG_TWO);
			SdramWriteMsg(IVR_MSG_HUNDRED);
			if (!iCur)	return;
		}
		else
		{
			SdramWriteMsg((UCHAR)(iIndex/100));
			iCur = iIndex%100;
			SdramWriteMsg(IVR_MSG_HUNDRED);
			if (!iCur)	return;
		}
		if (iCur < 20)
		{
			if (iCur >= 10)
			{
				SdramWriteMsg(IVR_MSG_1);
			}
			else
			{
				SdramWriteMsg(IVR_MSG_0);
			}
		}
	}

	if (iCur >= 20)
	{
		SdramWriteMsg((UCHAR)(iCur/10));
		iCur = iCur%10;
		SdramWriteMsg(IVR_MSG_10);
		if (!iCur)	return;
	}
	else if (iCur >= 10)
	{
		SdramWriteMsg(IVR_MSG_10);
		iCur -= 10;
		if (!iCur)	return;
	}

	SdramWriteMsg(iCur);
}
#else
void SdramWriteIndex(USHORT iIndex)
{
	DCHAR iCur;

	iCur = (UCHAR)iIndex;
	if (iIndex >= 100)
	{
		SdramWriteMsg((UCHAR)(iIndex/100));
		iCur = iIndex%100;
		if (!iCur)
		{
			SdramWriteMsg(IVR_MSG_0);
			SdramWriteMsg(IVR_MSG_0);
			return;
		}
		if (iCur < 10)
		{
			SdramWriteMsg(IVR_MSG_0);
		}
	}

	if (iCur >= 10)
	{
		SdramWriteMsg((UCHAR)(iCur/10));
		iCur = iCur%10;
	}

	SdramWriteMsg(iCur);
}
#endif

void SdramPlay(PXCHAR pString, UCHAR iIVR1, USHORT iIndex, UCHAR iIVR2)
{
	DCHAR i;

	if (!SdramFileCreate())		return;

	SdramWriteMsg(iIVR1);
	if (iIndex <= SDRAM_PLAY_NUMBER_MAX)
	{
		SdramWriteIndex(iIndex);
	}
	SdramWriteMsg(iIVR2);
	if (pString)
	{
		SdramWriteStrings(pString);
	}
	for (i = 0; i < Sys_iJitterSize; i ++)
	{
		SdramWriteMsg(IVR_MSG_BLANK);
	}
#if defined OEM_NONE_IVR || defined OEM_JR168
	SoloFileClose();
#else
	SoloFileOpen(PLAY_SDRAM_HI, FALSE, SoloFileClose());
	Ac97StartIVR();
#endif
}

void SdramPlayIP(UCHAR iIVR1, UCHAR iIVR2, PXCHAR pIP)
{
	XCHAR pString[16];

	p_IP2String(pIP, pString);
	DisplayLine(pString, 1);
#ifdef IVR_REVERSED
	SdramPlay(pString, iIVR2, SDRAM_PLAY_NUMBER_NONE, iIVR1);
#else
	SdramPlay(pString, iIVR1, SDRAM_PLAY_NUMBER_NONE, iIVR2);
#endif
}

#ifndef CALL_MGCP
void SdramPlayString(PXCHAR pString)
{
	SdramPlay(pString, IVR_MSG_SIGNAL, SDRAM_PLAY_NUMBER_NONE, IVR_MSG_BLANK);
}
#endif

/*
void SdramPlayNumber(USHORT iNumber)
{
	SdramPlay((PXCHAR)0, IVR_MSG_BLANK, (USHORT)((iNumber > SDRAM_PLAY_NUMBER_MAX) ? SDRAM_PLAY_NUMBER_MAX : iNumber), IVR_MSG_BLANK);
}
*/

void SdramPhoneNumber()
{
#ifdef IVR_REVERSED
	SdramPlay(Sys_pLocalNumber, IVR_MSG_NUMBER, SDRAM_PLAY_NUMBER_NONE, IVR_MSG_LOCAL);
#else
	SdramPlay(Sys_pLocalNumber, IVR_MSG_LOCAL, SDRAM_PLAY_NUMBER_NONE, IVR_MSG_NUMBER);
#endif
}

void SdramSpeedDial(UCHAR iIndex)
{
#ifndef VER_IPH_E00
	DisplayLine(Key_pBuf, 0);
#endif
	SdramPlay(Key_pBuf, IVR_MSG_NUMBER, iIndex, IVR_MSG_SIGNAL);
}

USHORT _GetRingLength()
{
	DSHORT iLen;
	SdramReadFlags();

	iLen = PXCHAR2USHORT((PXCHAR)(Sdram_pDataCache + FLAGS_RING_SIZE));
	switch (Dsp_iType)
	{
	case CODEC_G729:	// 10ms 12 bytes
		break;

	case CODEC_G7231:	// 30ms 24 bytes
		// 36/24=3/2
		iLen /= 3;	
		iLen *= 2;
		break;

	case CODEC_G711U:	// 10ms 80 bytes
	case CODEC_G711A:
		// 12/80=3/20
		iLen /= 3;
		iLen *= 20;
		break;

	case CODEC_GSM610:	// 20ms 33 bytes
		// 24/33=8/11
		iLen /= 8;
		iLen *= 11;
		break;

	case CODEC_ILBC:
		break;
	}

	return iLen;
}

void SdramRingFile()
{
	SoloFileCloseRead();

	SoloFileOpen((UCHAR)(RING_G729_SDRAM_HI + Dsp_iType), FALSE, _GetRingLength());
}

