

#include <vector>
#include <string>
#include <Windows.h>
#include <shlwapi.h>

#include "ErrorSearch.h"

using namespace std;

#pragma warning(disable : 4996)




unsigned int						g_EnumId;
static std::vector<ERR_DATA_UNIT>	g_ErrDataList_API;
static std::vector<ERR_DATA_UNIT>	g_ErrDataList_MSG;
static std::vector<ERR_DATA_UNIT>	g_ErrDataList_SRC;

//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/09/04
//******************************************************************************************************
void StringReplace(wstring &_wstr, wstring _original,wstring _result,bool _replaceall)
{
	size_t				m_Pos1 ;
	wstring::iterator	m_It1;
	wstring::iterator	m_It2;


	while(true)
	{
		
		m_Pos1 = _wstr.find(_original); 
		
		if(m_Pos1==wstring::npos){break;}

		m_It1	= _wstr.begin()+m_Pos1;
		m_It2	= _wstr.begin()+m_Pos1+_original.length();

		_wstr.replace(m_It1,m_It2,_result.begin(),_result.end());
	}
}


//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/09/04
//******************************************************************************************************
void StringRemoveToEnd(wstring &_wstr, wstring _original)
{
	size_t				m_Pos1 ;
	wstring::iterator	m_It1;



		
		m_Pos1 = _wstr.find(_original);

		if(m_Pos1==wstring::npos){return;}


		m_It1	= _wstr.begin()+m_Pos1;

		_wstr.erase(m_It1,_wstr.end());
	
}





//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/09/04
//******************************************************************************************************
void ControlCharReplace(unsigned char	*_input)
{

		if((*_input==0x9||(*_input==0xD)))
		{
			*_input=0X20;

		}
	
}





//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/09/04
//******************************************************************************************************
void EreaseEmptyLine(vector<wstring> &_vect_wstr)
{
	for(int i=0;i<(int)_vect_wstr.size();i++)
	{
			if(_vect_wstr[i].empty())
			{
				_vect_wstr.erase(_vect_wstr.begin()+i);
				i--;
			}
	}
	
}



//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/09/04
//******************************************************************************************************
void MatchEnumAndId(wstring _wstr,ERR_DATA_UNIT &_err_data_unit,unsigned int &_enum_numb)
{
	size_t				m_Pos1  = _wstr.find(L"=");
	size_t				m_Pos2  = _wstr.find(L",");
	wstring				m_Buff;


	int					m_StrToExtA_Value = 0;


	if(	m_Pos2!=wstring::npos )
	{
		if(m_Pos1!=wstring::npos)
		{
			m_Buff = _wstr.substr(m_Pos1+1,(m_Pos2-m_Pos1-1));
			StrToIntEx(m_Buff.c_str(),STIF_DEFAULT,&m_StrToExtA_Value);	
			_enum_numb = m_StrToExtA_Value;
			m_Buff = _wstr.substr(0,m_Pos1);
		}	
		else
		{
			
			m_Buff = _wstr.substr(0,m_Pos2);
			_enum_numb++;
		}

		_err_data_unit.EnumId = _enum_numb;
		wcscpy(_err_data_unit.Text,m_Buff.c_str());
	}	
}



//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/09/04
//******************************************************************************************************
bool IsInited()
{
	if(g_ErrDataList_API.size()==0)	{return false;}
	if(g_ErrDataList_SRC.size()==0)	{return false;}
	if(g_ErrDataList_MSG.size()==0)	{return false;}
	return true;
}




//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/09/04
//******************************************************************************************************
void SearchErrorCode(unsigned long _err_code,ERR_DATA_GROUP &_err_data_group)
{

	static unsigned long	m_API = (_err_code >> 11) & 0x3FF;
	static unsigned long	m_MSG = (_err_code >> 0 ) & 0x3FF;
	static unsigned long	m_SRC = (_err_code >> 26) & 0x3F;;

	if(g_ErrDataList_API.size()==0)	{return;}
	if(g_ErrDataList_SRC.size()==0)	{return;}
	if(g_ErrDataList_MSG.size()==0)	{return;}

	for(int i=0;i<(int)g_ErrDataList_API.size();i++)
	{
		if(		g_ErrDataList_API[i].EnumId==m_API)
		{
			_err_data_group.API.EnumId = m_API;
			wcscpy(_err_data_group.API.Text,g_ErrDataList_API[i].Text);
			break;
		}
	}

	for(int i=0;i<(int)g_ErrDataList_SRC.size();i++)
	{
		if(		g_ErrDataList_SRC[i].EnumId==m_SRC)
		{
			_err_data_group.SRC.EnumId = m_API;
			wcscpy(_err_data_group.SRC.Text,g_ErrDataList_SRC[i].Text);
			break;
		}
	}


	for(int i=0;i<(int)g_ErrDataList_MSG.size();i++)
	{
		if(		g_ErrDataList_MSG[i].EnumId==m_MSG)
		{
			_err_data_group.MSG.EnumId = m_MSG;
			wcscpy(_err_data_group.MSG.Text,g_ErrDataList_MSG[i].Text);
			break;
		}
	}



	

}


//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/09/04
//******************************************************************************************************
bool HeaderFileImport()
{
	wchar_t			m_ErrorHeaderPath[512]	= {0};
	wchar_t			m_StringBuffer[65536]	= {0};	

	unsigned char	m_FileDataBuff[65536]	= {0};
	unsigned char	m_FileBuffTmp1[65536]	= {0};
	unsigned char	m_FileBuffTmp2[65536]	= {0};


	ERR_DATA_UNIT	m_ErrDataUnit;
	unsigned long	m_ReadSize				=  0;
	unsigned long	m_LastErrCode			=  0;
	HANDLE			m_ErrFileHandle;

	int				m_StrLen				= 0;
	int				m_ReadingIndex			= 0;

	WIN32_FIND_DATA	m_Win32FindData;
	wstring			m_WStringBuff;
	wstring			m_WStr_Original;
	wstring			m_WStr_NewStr;


	std::vector<std::wstring>		m_TextLines;

	g_ErrDataList_API.clear();
	g_ErrDataList_SRC.clear();
	g_ErrDataList_MSG.clear();

	//g_ErrDataList.push_back(m_ErrDataUnit);
	m_TextLines.clear();
	GetCurrentDirectory(512,m_ErrorHeaderPath);
	wcscat(m_ErrorHeaderPath,L"\\ErrorCode.h");

	FindFirstFile(m_ErrorHeaderPath,&m_Win32FindData);
	if(GetLastError()!=0)
	{
		MessageBox(NULL,L"ErrorCode.h file loss",L"Error",MB_OK);
		return false;
	}

		//wcscat(m_ErrorHeaderPath,L"C:\\ErrorCode.h");
		
		m_ErrFileHandle = CreateFile(	m_ErrorHeaderPath,
										GENERIC_READ,
										FILE_SHARE_READ,
										NULL,
										OPEN_EXISTING,
										FILE_ATTRIBUTE_NORMAL,
										NULL);

		if(m_ErrFileHandle==NULL)
		{			
			MessageBox(NULL,L"HANDLE NULL",L"BB",MB_OK);
			return false;
		}


			//Clear queue buffer.
			m_WStringBuff.clear();


			if(ReadFile(	m_ErrFileHandle,
							m_FileDataBuff,
							65536,
							&m_ReadSize,
							NULL))
			{
				for(int i=0;i<(int)m_ReadSize;i++)
				{
					ControlCharReplace(&m_FileDataBuff[i]);
					if(m_FileDataBuff[i]=='\n')
					{
							//Clear temperatory buffers.
							memset(m_FileBuffTmp1,0,65536);
							memset(m_FileBuffTmp2,0,65536);


							if((m_FileDataBuff[i]!=0x0A)||(m_FileDataBuff[i+1]!=0x0D))							
							{

								if(!((m_FileDataBuff[i]==0x0A)&&(m_FileDataBuff[i+1]==0x2F)&&(m_FileDataBuff[i+2]==0x2F)))
								{
									//Split original string as two substrings.
									memcpy(m_FileBuffTmp1,m_FileDataBuff+m_ReadingIndex+1,i-m_ReadingIndex-1);
									m_ReadingIndex = i;

									//Convert from bytes to string format, and queue the string.			
									swprintf(m_StringBuffer,L"%S",m_FileBuffTmp1);												

									m_TextLines.push_back(m_StringBuffer);
								}
							}
					
					}
					
				}				
				
			
			//m_LastErrCode = GetLastError();
			//swprintf(m_ErrorHeaderPath,L"ReadFile ErrorCode = %d",m_LastErrCode);			
			//MessageBox(NULL,m_ErrorHeaderPath,L"BB",MB_OK);
		
		
		



		for(int i=0;i<(int)m_TextLines.size();i++)
		{

			StringReplace(m_TextLines[i],L";",L"",true);
			StringReplace(m_TextLines[i],L"-",L"",true);	
			//StringReplace(m_TextLines[i],L",",L"",true);
			StringReplace(m_TextLines[i],L"{",L"",true);
			StringReplace(m_TextLines[i],L"}",L"",true);
			StringRemoveToEnd(m_TextLines[i],L"//");
			StringReplace(m_TextLines[i],L"/",L"",true);
			StringReplace(m_TextLines[i],L"\n",L"",true);
			StringReplace(m_TextLines[i],L" ",L"",true);
		}

		EreaseEmptyLine(m_TextLines);

		

		//ERR_SRC
		for(int i=0;i<(int)m_TextLines.size();i++)
		{
			if(m_TextLines[i].find(L"ERR_SRC")!=wstring::npos)
			{
				i++;
				g_EnumId= 0;
				while(i<(int)m_TextLines.size())
				{
					if(m_TextLines[i].find(L"ERR_API")!=wstring::npos){break;}
					if(m_TextLines[i].find(L"ERR_MSG")!=wstring::npos){break;}

					MatchEnumAndId(m_TextLines[i++],m_ErrDataUnit,g_EnumId);
					g_ErrDataList_SRC.push_back(m_ErrDataUnit);
				}
			}
		}


		//ERR_API
		for(int i=0;i<(int)m_TextLines.size();i++)
		{
			if(m_TextLines[i].find(L"ERR_API")!=wstring::npos)
			{
				i++;
				g_EnumId= 0;
				while(i<(int)m_TextLines.size())
				{
					if(m_TextLines[i].find(L"ERR_SRC")!=wstring::npos){break;}
					if(m_TextLines[i].find(L"ERR_MSG")!=wstring::npos){break;}

					MatchEnumAndId(m_TextLines[i++],m_ErrDataUnit,g_EnumId);
					g_ErrDataList_API.push_back(m_ErrDataUnit);
				}
			}
		}

		//ERR_MSG
		for(int i=0;i<(int)m_TextLines.size();i++)
		{
			if(m_TextLines[i].find(L"ERR_MSG")!=wstring::npos)
			{
				i++;
				g_EnumId= 0;
				while(i<(int)m_TextLines.size())
				{
					if(m_TextLines[i].find(L"ERR_API")!=wstring::npos){break;}
					if(m_TextLines[i].find(L"ERR_SRC")!=wstring::npos){break;}

					MatchEnumAndId(m_TextLines[i++],m_ErrDataUnit,g_EnumId);
					g_ErrDataList_MSG.push_back(m_ErrDataUnit);
				}
			}
		}




		if(m_ErrFileHandle!=NULL)
		{
			CloseHandle(m_ErrFileHandle);
		}

		
	}


	return true;

}
