#include "p_apps.h"
#include "mediaring.h"

CCHAR g_cSoftwareVersion[5] = {SOFT_VER_HIGH + '0', '.', SOFT_VER_LOW + '0', SOFT_VER_BUILD + '0', 0};

void CopyFileToOption(UCHAR iNum, UCHAR iStart)
{
	DCHAR i, j;

	j = iStart;
	for (i = 0; i < iNum; i += 2)
	{
		SdramRead(FILE_IN_SDRAM_HI, i, SRAM_DMA_DWORD);
		SdramWrite(OPTIONS_SDRAM_HI, j, SRAM_DMA_DWORD);
		j += 2;
	}
}

BOOLEAN IsUpgradeFileOK(UCHAR iSdramHi)
{
#if defined OEM_MEDIARING || defined OEM_RINGCHAT
	MediaringEncrypt((PXCHAR)0);		// just call it to avoid data space overflow.
	return CheckMediaRingID(iSdramHi);
#else
	// don't check if debug level is high enough
	if (Udp_iOutputDebug == DEBUG_DISABLE_PRODUCTID)	return TRUE;

	// check product tag
	SdramReadData(OPTIONS_SDRAM_POS+DESIGN_NAME_SDRAM_LO);
	p_memcpy_x2x((PXCHAR)Sdram_pDataCache2, (PXCHAR)Sdram_pDataCache, MAX_TAG_LENGTH); 

	SdramRead(iSdramHi, FLAGS_CODE_POS_HIGH, MAX_TAG_LENGTH/4);
	if (p_memcmp_x2x((PXCHAR)Sdram_pDataCache, (PXCHAR)Sdram_pDataCache2, MAX_TAG_LENGTH))
	{	// different hardware version
		OutputString(IDS_UPGRADE_BINARY_MISMATCH);
		return FALSE;
	}
	return TRUE;
#endif
}

BOOLEAN IsFirmwareLenOK(ULONG iFileLen)
{
	// don't check if debug level is high enough
	if (Udp_iOutputDebug == DEBUG_DISABLE_PRODUCTID)	return TRUE;

#ifdef AM29LV002T
	if (iFileLen == FILE_FULL_PAGE_SIZE * 3)		return TRUE;
#elif defined AM29F040
	if (iFileLen == FILE_FULL_PAGE_SIZE * 6)		return TRUE;
#elif defined AM29LV004T || defined MX29LV004T || defined AM29LV008B
	if (iFileLen == FILE_FULL_PAGE_SIZE * 7)		return TRUE;
#elif defined AM29LV008T || defined MX29LV008B || defined MT28F016
	if (iFileLen == FILE_FULL_PAGE_SIZE * 15)		return TRUE;
#endif

	OutputString(IDS_UPGRADE_BINARY_LENERROR);
	return FALSE;
}

void CreateUpgradeFile()
{
	DCHAR i;

	SdramClearDataCache();
	for (i = 0; i < 8; i += 2)
	{
		SdramWrite(FILE_IN_SDRAM_HI, i, SRAM_DMA_DWORD);
//		SdramWrite(FILE_OUT_SDRAM_HI, i, SRAM_DMA_DWORD);
	}
	UdpDebugRemoteStop();
	SoloFileClose();
	SoloFileOpen(FILE_IN_SDRAM_HI, TRUE, FILE_WRITE_MAX_SIZE);
//	SoloFileOpen(FILE_OUT_SDRAM_HI, TRUE, FILE_WRITE_MAX_SIZE);
	DisplayString(g_cUpdating, 0);
	DisplayString(g_cPleaseWait, 1);
}

#ifdef VER_WG2000
CCHAR Sys_cVersion[] = "Version ";
#else
CCHAR Sys_cVersion[] = "V";
#endif

static CCHAR _cEngVersion[] = {'.', ENG_BUILD_HIGH+'0', ENG_BUILD_MID+'0', ENG_BUILD_LOW+'0', 0};

PXCHAR GetVersionTextEx(BOOLEAN bEng, BOOLEAN bCfg)
{
	PXCHAR_D pCur;
	DSHORT iCfgVersion;

	SdramReadOptions();
	iCfgVersion = PXCHAR2USHORT((PXCHAR)(Sdram_pDataCache + OPTIONS_SETTINGS_VER));

	SdramReadFlags();
	pCur = (PXCHAR)(Sdram_pDataCache+FLAGS_PRODUCT_TAG);

	p_strcat_char2x(pCur, ' ');
	p_strcat_c2x(pCur, Sys_cVersion);
	p_strcat_c2x(pCur, g_cSoftwareVersion);

	if (bEng)
	{
		p_strcat_c2x(pCur, _cEngVersion);
	}
	p_strcat_char2x(pCur, ' ');

	if (bCfg)
	{
		p_strcat_c2x(pCur, (PCCHAR)"CFG");
		p_itoa(iCfgVersion, (PXCHAR)(pCur + p_strlen_x(pCur)), 10);
		p_strcat_char2x(pCur, ' ');
	}
	return pCur;
}

PXCHAR GetVersionText()
{
	BOOLEAN bOutput;

	bOutput = Udp_iOutputDebug ? TRUE : FALSE;
	return GetVersionTextEx(bOutput, bOutput);
}

PXCHAR GetSoftwareVersion()
{
	PXCHAR_D pCur;

	pCur = (PXCHAR)Sdram_pDataCache;
	p_strcpy_c2x(pCur, Sys_cVersion);
	p_strcat_c2x(pCur, g_cSoftwareVersion);
	p_strcat_c2x(pCur, _cEngVersion);
	return pCur;
}

PXCHAR GetHardwareVersion()
{
	SdramReadFlags();
	return (PXCHAR)(Sdram_pDataCache+FLAGS_PRODUCT_TAG);
}

BOOLEAN IsUpgrading()
{
	if (Udp_iOutputDebug == DEBUG_LEVEL_FILE)	return FALSE;
	return SoloFileIsWriting();
}

BOOLEAN CheckFileVersion(UCHAR iUpgradePage)
{
	DCHAR iPage;

	iPage = iUpgradePage;
	if (iPage == PROGRAM_UPGRADE_PAGE)
	{
		if (!IsUpgradeFileOK(FILE_IN_SDRAM_HI)) return FALSE;				// Check page1 product tag
		if (!IsUpgradeFileOK((UCHAR)(FILE_IN_SDRAM_HI+2))) return FALSE;	// Check page3 product tag
	}
	else if (!iPage || iPage == 1 || iPage == 3)
	{
		if (!IsUpgradeFileOK(FILE_IN_SDRAM_HI)) return FALSE;	// Check page0, 1, 3 product tag
	}
	return TRUE;
}
