// reversion.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "reversion.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

void _RewriteVersion(CString strFileName, CString strVer, CString strCall, CString strRes, CString strOem);

void CommandLineDefault(int argc, TCHAR* argv[], CString & strFileName, CString & strVer, CString & strCall, CString & strRes, CString & strOem);

/////////////////////////////////////////////////////////////////////////////
// The one and only application object

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		cerr << _T("Fatal Error: MFC initialization failed") << endl;
		nRetCode = 1;
	}
	else
	{
		// TODO: code your application's behavior here.
//		CString strHello;
//		strHello.LoadString(IDS_HELLO);
//		cout << (LPCTSTR)strHello << endl;
		CString strFileName, strVer, strCall, strRes, strOem;
		
		CommandLineDefault(argc, argv, strFileName, strVer, strCall, strRes, strOem);
		_RewriteVersion(strFileName, strVer, strCall, strRes, strOem);
	}

	return nRetCode;
}

BOOL _MatchString(CString str, CString strCmp)
{
	int iLen, iVal;

	iLen = strCmp.GetLength();
	if (iLen < str.GetLength())
	{
		iVal = str.GetAt(iLen);
		if (iVal != ' ' && iVal != '\t')	return FALSE;
	}
	if (str.Left(iLen) == strCmp)	return TRUE;
	return FALSE;
}

//#define
BOOL _ProcessString(CString & str, CString strCmpVer, CString strCmpCall, CString strCmpRes, CString strCmpOem)
{
	CString str1;

	if (str.Left(9) == "//#define")
	{
		str1 = str.Right(str.GetLength() - 9);
		str1.TrimLeft();
		if (_MatchString(str1, strCmpVer) || _MatchString(str1, strCmpCall)
			|| _MatchString(str1, strCmpRes) || _MatchString(str1, strCmpOem))
		{
			str = str.Right(str.GetLength() - 2);
			return TRUE;
		}
	}
	else if (str.Left(7) == "#define")
	{
		str1 = str.Right(str.GetLength() - 7);
		str1.TrimLeft();
		if (_MatchString(str1, strCmpVer) || _MatchString(str1, strCmpCall)
			|| _MatchString(str1, strCmpRes) || _MatchString(str1, strCmpOem))
		{
			return FALSE;
		}
		str = "//" + str;
		return TRUE;
	}

	return FALSE;
}

void _RewriteVersion(CString strFileName, CString strVer, CString strCall, CString strRes, CString strOem)
{
	CStdioFile file;
	CString strName;
	CString str;
	CString strCmpVer;
	CString strCmpCall;
	CString strCmpRes;
	CString strCmpOem;
	char szCurDir[128];
	CStringList list;
	POSITION pos, old;
	BOOL bChanged;

	GetCurrentDirectory(128, szCurDir);
	strName.Format("%s\\%s", szCurDir, strFileName);

	strCmpVer = "VER_" + strVer;
	strCmpVer.MakeUpper();

	strCmpCall = "CALL_" + strCall;
	strCmpCall.MakeUpper();

	strCmpRes = "RES_" + strRes;
	strCmpRes.MakeUpper();

	strCmpOem = "OEM_" + strOem;
	strCmpOem.MakeUpper();

	// read first
	if (!file.Open(strName, CFile::modeRead|CFile::typeText))
	{
		return;
	}
	while (file.ReadString(str))
	{
		list.AddTail(str);
	}
	file.Close();

	// process
	bChanged = FALSE;
	for (pos = list.GetHeadPosition(); pos != NULL;)
	{
		old = pos;
		str = list.GetNext(pos);
		if (str.Left(10) == "/*********")
		{
			break;
		}
		if (_ProcessString(str, strCmpVer, strCmpCall, strCmpRes, strCmpOem))
		{
			list.SetAt(old, str);
			bChanged = TRUE;
		}
	}

	if (!bChanged)	return;		// no need to rewrite

	// write
	file.Open(strName, CFile::modeCreate|CFile::modeWrite|CFile::typeText);
//	file.WriteString("//my changed version.h\n");
	while (!list.IsEmpty())
	{
		str = list.RemoveHead();
		str += "\n";
		file.WriteString(str);
	}
	file.Close();
}
