#include "RoleData/RoleDataEx.h"
#include "ObjectDataFile/ObjectDataBaseFile.h"
#include <fstream>
#include <Windows.h>
#include < vcclr.h >
#include "BaseForm.h"

#include "StringForm.h"
#include "MessageDialog.h"

#include "zip/zip.h"

extern "C"{
#include "lua/lua.h"
#include "lua/lauxlib.h"
#include "lua/lualib.h"
#include "lua/llex.h"
#include "lua/lfunc.h"
#include "lua/ldo.h"
#include "lua/lmem.h"
#include "lua/lobject.h"
#include "lua/lopcodes.h"
#include "lua/lstring.h"
#include "lua/lundump.h"
};

using namespace ObjDataEdit;

#pragma managed(push, off)
map<string, string> g_mapSysString;
map<string, string> g_mapCliString;
map<string, string> g_mapLoginString;

void func_GetStringFormat( const char* str , std::vector<string>& keylist );
bool func_CheckStringFormat( const char* str1, const char* str2 );

void func_GetStringFormat( const char* str , std::vector<string>& keylist )
{
	char* temp = new char [ strlen(str) + 1 ];
	char* pos;
	char* end;

	bool bfinded;

	//	keylist.clear();

	strcpy( temp , str );

	pos = temp;

	int i,count;

	while( 1 )
	{
		pos = strchr( pos , '%' );
		if( !pos )
		{
			break;
		}

		pos = pos + 1;

		end = pos + strlen(pos);

		bfinded = false;

		count = strlen(pos);
		for( i = 0 ; i < count ; ++i )
		{
			if( pos[i] == '0' ||
				pos[i] == '1' ||
				pos[i] == '2' ||
				pos[i] == '3' ||
				pos[i] == '4' ||
				pos[i] == '5' ||
				pos[i] == '6' ||
				pos[i] == '7' ||
				pos[i] == '8' ||
				pos[i] == '9' ||
				pos[i] == '.' )
			{
				continue;
			}

			if( pos[i] == 'd' ||
				pos[i] == 'f' ||
				pos[i] == 'x' ||
				pos[i] == 'X' ||
				pos[i] == 'u' ||
				pos[i] == 's' )
			{
				bfinded = true;
				end = pos + i;
				break;
			}

			//if( pos[i] > 128 )
			//{
			//pos = pos + i;
			break;
			//}
		}

		if( bfinded == false )
		{
			continue;
		}

		string strkey = pos;
		strkey.resize( end - pos + 1 );
		keylist.push_back( strkey );

		pos = end;
	}

	delete [] temp;
}




bool func_CheckStringFormat( const char* str1, const char* str2 )
{
	std::vector<string> keylist1;
	std::vector<string> keylist2;

	func_GetStringFormat( str1 , keylist1 );
	func_GetStringFormat( str2 , keylist2 );

	int k1sz = keylist1.size();
	int k2sz = keylist2.size();

	if( k1sz == 0 )
	{
		return true;
	}

	if( k1sz != k2sz )
	{
		return false;
	}

	for( int i = 0 ; i < k1sz ; ++i )
	{
		if( keylist1[i] != keylist2[i] )
		{
			return false;
		}
	}

	return true;
}

#pragma managed(pop)

void	StringForm::DataFill( )
{
	sqlDataAdapter1->UpdateCommand->CommandText = String::Format( "UPDATE StringDB SET KeyStr = @KeyStr, Type = @Type, SubType = @SubType, [Content] = @Content, Note = @Note, IsConfirmed1 = 0 , IsConfirmed2 = 0 , IsConfirmed3 = 0 ,IsConfirmed4 = 0 , IsConfirmed5 = 0 , IsConfirmed6 = 0 , IsConfirmed7 = 0 ,IsConfirmed8 = 0 , IsConfirmed9 = 0 , IsConfirmed10 = 0 , IsConfirmed11 = 0 ,IsConfirmed12 = 0 , IsConfirmed13 = 0 , IsConfirmed14 = 0 , IsConfirmed15 = 0 , IsUpdate =1 , IsTranslated1 = 0 , IsTranslated2 = 0 , IsTranslated3 = 0 ,IsTranslated4 = 0 , IsTranslated5 = 0 , IsTranslated6 = 0 , IsTranslated7 = 0 ,IsTranslated8 = 0 , IsTranslated9 = 0 , IsTranslated10 = 0 , IsTranslated11 = 0 ,IsTranslated12 = 0 , IsTranslated13 = 0 , IsTranslated14 = 0 , IsTranslated15 = 0 , UpdateTime = GETDATE() , Content_Editor='{0}' , DirZoneID=@DirZoneID , DirTagID=@DirTagID,DirVersionID=@DirVersionID,Translate=@Translate WHERE (KeyStr = @Original_KeyStr) AND (Type = @Original_Type) AND (SubType = @Original_SubType) AND ([Content] = @Original_Content) AND (Note = @Original_Note)" , _Account );
	sqlDataAdapter1->InsertCommand->CommandText = String::Format( "INSERT INTO StringDB	(KeyStr, Type, [Content], Note, SubType, Content_Editor,DirZoneID,DirTagID,DirVersionID,Translate) VALUES (@KeyStr,@Type,@Content,@Note,@SubType,'{0}',@DirZoneID,@DirTagID,@DirVersionID,@Translate)" , _Account );

	String* Str = "SELECT KeyStr, Type , SubType , Content, Note ,DirZoneID,DirTagID,DirVersionID,Translate FROM StringDB WHERE Type <> 1";
	if( CKB_SelectKeyChecked->Checked == true && TB_SelectKey->Text->Length != 0  )
	{
		switch( CB_SelectType->SelectedIndex )
		{
		case 0:	//key
			Str = String::Format( "{0} AND ( KeyStr LIKE '%{1}%' ) " , Str , TB_SelectKey->Text );
			break;
		case 1: //內容
			Str = String::Format( "{0} AND ( Content LIKE '%{1}%' ) " , Str , TB_SelectKey->Text );
			break;

		case 2: //說明
			Str = String::Format( "{0} AND ( Note LIKE '%{1}%' ) " , Str , TB_SelectKey->Text );
			break;
		}
		
	}

	sqlSelectCommand1->CommandText = Str;

	dataSet31->Clear();
	sqlDataAdapter1->Fill( dataSet31 );

}
//------------------------------------------------------------------------------------------------------
void	StringForm::UpDateData( )
{
	
	sqlDataAdapter1->Update( dataSet31 );
}

//------------------------------------------------------------------------------------------------------
//儲存字串結構
struct	StringFileHeadStruct
{
	char				KeyStr[64];

	int					ContentSize;
	char				Content[8192];	
};

int	StringForm::GetTotalLanguage()
{
	return EM_LanguageType_Count;
}

string StringForm::GetLanguageString( int iLanguageID )
{
	switch( iLanguageID )
	{
	case EM_LanguageType_TW:
		return	"TW";
	case EM_LanguageType_CN:
		return	"CN";
	case EM_LanguageType_ENUS:
		return	"ENUS";
	case EM_LanguageType_DE: 
		return	"DE";
	case EM_LanguageType_ENEU:
		return	"ENEU";
	case EM_LanguageType_JP:
		return	"JP";
	case EM_LanguageType_KR:
		return	"KR";
	case EM_LanguageType_BR:
		return	"BR";
	case EM_LanguageType_TR:
		return	"TR";
	case EM_LanguageType_VN:
		return	"VN";
	case EM_LanguageType_RU:
		return	"RU";
//	case EM_LanguageType_SG:
//		break;
	case EM_LanguageType_FR:
		return	"FR";
	case EM_LanguageType_ID:
		return	"ID";
	case EM_LanguageType_ES:
		return	"ES";
	case EM_LanguageType_PT:
		return "PT";
	case EM_LanguageType_PL:
		return "PL";
	case EM_LanguageType_PH:
		return "PH";
	case EM_LanguageType_AE:
		return "AE";
	case EM_LanguageType_TH:
		return "TH";
	case EM_LanguageType_SAES: //中南美洲(西班牙)
		return "SAES";
	case EM_LanguageType_ENAR: //中東英文
		return "ENAR";
	case EM_LanguageType_SAPT: //中南美洲(葡萄牙)
		return "SAPT";
	case EM_LanguageType_IT: //中南美洲(葡萄牙)
		return "IT";
	}
	return "";
}

void StringForm::_OutputFileLanguage()
{
	char Buf[ 512 ];
	SqlDataReader* myReader;

	int iLanguageID = -1;	
	string strOutDir = "";
	_OutputFileNameList = new ArrayList();
	_GUID				= -1;
	_OutputStatus		= EM_STROUT_STATUS_NORMAL;
	_OutputStep			= EM_STROUT_STEP_NONE;
	_CurrentRecordNum	= 0;
	_TotalRecordNum		= 0;
	_ErrorString		= "";

	//--------------------------------------------------
	//create SQL Command

	_UpdateConnection = (new System::Data::SqlClient::SqlConnection());
	_UpdateConnection->ConnectionString = Global::GetDBSource();
	_UpdateConnection->Open();

	_UpdateCommand = (new System::Data::SqlClient::SqlCommand());
	_UpdateCommand->Connection = _UpdateConnection;

	//------------------------------------------------
	//try to get an unprocessed task
	sqlCommand1->CommandText = "SELECT GUID, LanguageID, FilePath FROM StringOutputProgress WHERE IsProcessed = 0";
	myReader = sqlCommand1->ExecuteReader();

	iLanguageID = -1;	
	strOutDir	= "";

	//read only one record
	if (myReader->Read())
	{
		_GUID		= myReader->GetInt32( 0 );
		iLanguageID = myReader->GetInt32( 1 );
		strOutDir	= DotNetStr::StringToChar(myReader->GetString( 2 ));
	}

	myReader->Close();
	//------------------------------------------------

	//------------------------------------------------
	//mark as processed
	sprintf( Buf , "UPDATE StringOutputProgress SET IsProcessed = 1, StartTime = getdate() Where GUID = %d" , _GUID );	
	sqlCommand1->CommandText = Buf;
	myReader = sqlCommand1->ExecuteReader();
	myReader->Close();
	//------------------------------------------------


	//--------------------------------------------------
	string LanStr = GetLanguageString( iLanguageID );

	if (LanStr.empty())
	{
		_UpdateOutputStatus(EM_STROUT_STATUS_NO_SUCH_LANGUAGE);
	}
	else
	{
		_UpdateOutputStep(EM_STROUT_STEP_BEGIN);

		//------------------------------------------------------------------
		PrepareCheckStringFormat();

		//------------------------------------------------------------------
		_UpdateOutputStep(EM_STROUT_STEP_SYS_STRING);

		//-------------------------------------------------------
		//get total record number	
		sqlCommand1->CommandText = "SELECT count(*) FROM StringDB Where Type <> 0";
		myReader = sqlCommand1->ExecuteReader();

		_TotalRecordNum = 0;

		if (myReader->Read())
		{
			_TotalRecordNum = myReader->GetInt32( 0 );
		}

		myReader->Close();
		//-------------------------------------------------------

		sprintf( Buf , "SELECT KeyStr,Content_Language%d,Content FROM StringDB Where Type <> 0" , iLanguageID );	
		_OutputFile_SysString( iLanguageID, Buf );
		//------------------------------------------------------------------


		//------------------------------------------------------------------
		_UpdateOutputStep(EM_STROUT_STEP_CLI_STRING_TYPE_0);

		//-------------------------------------------------------
		//get total record number	
		sqlCommand1->CommandText = "SELECT count(*) FROM StringDB Where Type = 0";
		myReader = sqlCommand1->ExecuteReader();

		_TotalRecordNum = 0;

		if (myReader->Read())
		{
			_TotalRecordNum = myReader->GetInt32( 0 );
		}

		myReader->Close();
		//-------------------------------------------------------

		sprintf( Buf , "SELECT KeyStr,Content_Language%d,Content,Note FROM StringDB Where Type = 0" , iLanguageID );	
		_OutputFile_ClientString( iLanguageID, "String", Buf );
		//------------------------------------------------------------------


		//------------------------------------------------------------------
		_UpdateOutputStep(EM_STROUT_STEP_CLI_STRING_TYPE_3);

		//-------------------------------------------------------
		//get total record number	
		sqlCommand1->CommandText = "SELECT count(*) FROM StringDB Where Type = 3";
		myReader = sqlCommand1->ExecuteReader();

		_TotalRecordNum = 0;

		if (myReader->Read())
		{
			_TotalRecordNum = myReader->GetInt32( 0 );
		}

		myReader->Close();
		//-------------------------------------------------------

		sprintf( Buf , "SELECT KeyStr,Content_Language%d,Content,Note FROM StringDB Where Type = 3" , iLanguageID );	
		_OutputFile_ClientString( iLanguageID, "LoginString", Buf );
		//------------------------------------------------------------------

		EndCheckStringFormat();		

		//---------------------------------------
		//prepare zip file name
		//time string
		time_t Now;
		time( &Now );
		struct tm *gmt;
		gmt = localtime( &Now );

		//output directory
		if (strOutDir.empty())
		{
			strOutDir = Global::GetIniString( "DataPath" );
		}

		//combine all string as full file name
		sprintf(Buf, "%s\\String%s_%d%d%d%d%d.zip", strOutDir.c_str(), LanStr.c_str(), gmt->tm_year+1900, gmt->tm_mon+1, gmt->tm_mday, gmt->tm_hour , gmt->tm_min);
		string strFullZipFilePath = Buf;
		//---------------------------------------

		_UpdateOutputStep(EM_STROUT_STEP_ZIPPING);
		//---------------------------------------
		//zip all output files to a single zip file
		HZIP hZ = CreateZip(strFullZipFilePath.c_str() , 0);

		if (hZ)
		{
			for (int i = 0; i < _OutputFileNameList->Count; i++)
			{
				String* strFullPath = (String*)(_OutputFileNameList->get_Item(i));
				String* strFileName = "";
				string  pszFullPath = "";
				string  pszFileName = "";

				int iIndex = strFullPath->LastIndexOf('\\');

				if ((iIndex >= 0) && (iIndex != (strFullPath->Length - 1)))
				{
					strFileName = strFullPath->Substring(iIndex + 1);
					pszFullPath = DotNetStr::StringToChar(strFullPath);
					pszFileName = DotNetStr::StringToChar(strFileName);
					ZipAdd(hZ, pszFileName.c_str(), pszFullPath.c_str());
				}	
			}

			CloseZip(hZ);
		}
		//---------------------------------------

		//delete output files
		System::IO::Directory::Delete(Global::GetDataPath().c_str(), true);	

		//------------------------------------------------
		//final step
		_TotalRecordNum = 0;
		_CurrentRecordNum = 0;
		_UpdateProgress();
		_UpdateOutputStep(EM_STROUT_STEP_END);
		//------------------------------------------------

		//------------------------------------------------
		//update endtime
		sprintf( Buf , "UPDATE StringOutputProgress SET EndTime = getdate() Where GUID = %d" , _GUID );	
		sqlCommand1->CommandText = Buf;
		myReader = sqlCommand1->ExecuteReader();
		myReader->Close();
		//------------------------------------------------
	}
}

void StringForm::_OutputFile_SysString( int iLanguageID, String* SQLCmd )
{
	char szFullFileName[256];

	string LanStr = GetLanguageString( iLanguageID );

	//-------------------------------------------------------
	//try to open file for writing
	fstream file;
	sprintf( szFullFileName, "%s_%s", _OutputFileName, LanStr.c_str() );

	if(!_OutputFile_SimplifyProcess( file , szFullFileName , "DB"  ))
	{		
		return;
	}
	//-------------------------------------------------------

	//-------------------------------------------------------
	//read data from data base
	SqlDataReader* myReader;
	sqlCommand1->CommandText = SQLCmd;
	myReader = sqlCommand1->ExecuteReader();

	_CurrentRecordNum = 0;

	while( myReader->Read() )
	{
		_CurrentRecordNum++;

		_UpdateProgress();

		String* KeyStr			= myReader->GetString( 0 );
		String* ContentStr		= myReader->GetString( 1 );
		String* TwContentStr	= myReader->GetString( 2 );

		if(String::IsNullOrEmpty(TwContentStr))
			ContentStr = "";

		string _KeyStr		= DotNetStr::StringToChar( KeyStr );
		string _ContentStr	= DotNetStr::StringToChar( ContentStr );

		//-------------------------------------------------
		//String check TW不用比較
		if (iLanguageID != EM_LanguageType_TW)
		{
			map<string, string>::iterator iter = g_mapSysString.find(_KeyStr.c_str());

			if (iter != g_mapSysString.end())
			{
				//目標語言內容跟 StrKey一致, 不檢查
				if (_stricmp(_KeyStr.c_str(), (iter->second).c_str()) == 0)
				{
					//檢查字串format
					if (!func_CheckStringFormat((iter->second).c_str(), _ContentStr.c_str()))
					{
						String* _tmpString = "";
						_tmpString = String::Format("String format error : KEY = {0}\r\n", KeyStr);
						_ErrorString = String::Concat(_ErrorString, _tmpString);
						_tmpString = String::Format("Source(TW) CONTENT = {0}\r\n", TwContentStr);
						_ErrorString = String::Concat(_ErrorString, _tmpString);
						_tmpString = String::Format("Target({0}) CONTENT = {1}\r\n", new String(LanStr.c_str()) ,ContentStr);
						_ErrorString = String::Concat(_ErrorString, _tmpString);

						_UpdateErrorString();
						_UpdateOutputStatus(EM_STROUT_STATUS_STRING_FROMAT_CHECK_FAILED);
					}
				}
			}
		}
		//-------------------------------------------------

		//-------------------------------------------------
		//write data to file stream
		StringFileHeadStruct OutPutData;
		strncpy_s( OutPutData.KeyStr , sizeof(OutPutData.KeyStr) , _KeyStr.c_str() , sizeof(OutPutData.KeyStr) );

		if( ContentStr->Length != 0 )
		{
			char utf8 __gc[] = Encoding::UTF8->GetBytes( ContentStr );
			char __pin *charUtf8Str = &utf8[0];  
			OutPutData.ContentSize = strlen( charUtf8Str ) + 1;

			if( OutPutData.ContentSize > 8000 )
			{
				int a = 3;
				//MessageBox::Show( "TableString 輸出完成" , "訊息" );
			}

			strcpy( OutPutData.Content , charUtf8Str );
		}
		else
		{
			OutPutData.Content[0] = 0;
			OutPutData.ContentSize = 1;
		}

		file.write( (char*)&OutPutData.KeyStr		, sizeof(OutPutData.KeyStr) );
		file.write( (char*)&OutPutData.ContentSize	, sizeof(int) );
		file.write( (char*)&OutPutData.Content		, OutPutData.ContentSize );
		//------------------------------------------------------------------
	}
	myReader->Close();	
	file.close();
	//-------------------------------------------------------
}

void StringForm::_OutputFile_ClientString( int iLanguageID, String* FileName , String * SQLCmd )
{
	char szFullFileName[256];

	string LanStr = GetLanguageString( iLanguageID );

	//-------------------------------------------------------
	//try to open file for writing
	fstream file;
	sprintf( szFullFileName, "%s_%s", DotNetStr::StringToChar( FileName ).c_str() , LanStr.c_str() );

	if(!_OutputFile_SimplifyProcess( file , szFullFileName , "lua"  ))
	{		
		return;
	}
	//-------------------------------------------------------

	//-------------------------------------------------------
	//read data from data base
	SqlDataReader* myReader;
	sqlCommand1->CommandText = SQLCmd;
	myReader = sqlCommand1->ExecuteReader();

	_CurrentRecordNum = 0;

	while( myReader->Read() )
	{
		_CurrentRecordNum++;

		_UpdateProgress();

		String* KeyStr			= myReader->GetString( 0 );
		String* ContentStr		= myReader->GetString( 1 );
		String* TwContentStr	= myReader->GetString( 2 );
		String* Note			= myReader->GetString( 3 );

		if( String::IsNullOrEmpty(TwContentStr))
			ContentStr = "";

		string _KeyStr = DotNetStr::StringToChar( KeyStr );
		string _ContentStr = DotNetStr::StringToChar( ContentStr );

		//------------------------------------------------------------------
		//String check TW不用比較
		if (iLanguageID != EM_LanguageType_TW)
		{
			map<string, string>& mapStr = g_mapCliString;

			if (String::Equals(FileName, "String"))
			{
				mapStr = g_mapCliString;
			}
			else if (String::Equals(FileName, "LoginString"))
			{
				mapStr = g_mapLoginString;
			}

			map<string, string>::iterator iter = mapStr.find(_KeyStr.c_str());

			if (iter != mapStr.end())
			{
				//目標語言內容跟 StrKey一致, 不檢查
				if (_stricmp(_KeyStr.c_str(), (iter->second).c_str()) == 0)
				{
					//檢查字串format
					if (!func_CheckStringFormat((iter->second).c_str(), _ContentStr.c_str()))
					{
						String* _tmpString = "";
						_tmpString = String::Format("String format error : KEY = {0}\r\n", KeyStr);
						_ErrorString = String::Concat(_ErrorString, _tmpString);
						_tmpString = String::Format("Source(TW) CONTENT = {0}\r\n", TwContentStr);
						_ErrorString = String::Concat(_ErrorString, _tmpString);
						_tmpString = String::Format("Target({0}) CONTENT = {1}\r\n", new String(LanStr.c_str()) ,ContentStr);
						_ErrorString = String::Concat(_ErrorString, _tmpString);

						_UpdateErrorString();
						_UpdateOutputStatus(EM_STROUT_STATUS_STRING_FROMAT_CHECK_FAILED);
					}
				}
			}
		}

		//------------------------------------------------------------------

		char*	Str ;
		int		Strlen;
		int		TotalStrlen;

		//註解
		//		Str = "--";
		//		file.write( Str		, strlen( Str ) );
		//		Str = DotNetStr::StringToChar( Note );
		//		file.write( Str		, strlen( Str ) );
		//Str = "\r\n"
		//file.write( Str		, strlen( Str ) );
		//		file.put( '\r' );file.put( '\n' );


		char Buf[0x10000];

		//Key 與 內容
		const wchar_t __pin* wstr = PtrToStringChars(KeyStr);
		TotalStrlen = WCharToUTF8( wstr , Buf , sizeof(Buf) ) -1;
		file.write( Buf	,  TotalStrlen );
		Str = " = \"";
		file.write( Str , strlen( Str ) );

		wstr = PtrToStringChars(ContentStr);
		Strlen = WCharToUTF8( wstr , Buf , sizeof(Buf) ) -1;
		//file.write( Buf	,  Strlen );
		TotalStrlen = TotalStrlen + Strlen + 5;

		for( int i = 0 ; i < Strlen ; i++ )
		{
			if( Buf[i] == '\r' )
				continue;
			if( Buf[i] == '\n' )
			{
				file.put( '\\' );file.put( 'n' );

			}
			else if( Buf[i] == '\"' )
			{
				file.put( '\\' );
				file.put( '\"' );
			}
			else
			{
				file.put( Buf[i] );
			}
		}

		file.put( '\"' );

		for( int i = TotalStrlen/4 ; i < 16 ; i++ )
		{
			file.put( '\t' );
		}

		Str = "\t--";
		file.write( Str		, strlen( Str ) );

		wstr = PtrToStringChars(Note);
		Strlen = WCharToUTF8( wstr , Buf , sizeof(Buf) ) -1;

		//Str = DotNetStr::StringToChar( Note );
		file.write( Buf		, Strlen );

		file.put( '\r' );file.put( '\n' );
	}
	myReader->Close();
	file.close();

	//////////////////////////////////////////////////////////////////////////
	{
		//char	FileName[512];
		//sprintf( FileName , "%s.lua" , szFullFileName ) ;
		string  FileName = string(szFullFileName) + ".lua";
		char* FullPathFileName = CombineFilePath( Global::GetDataPath().c_str() , FileName.c_str() );

		lua_State* L_State;
		L_State  = lua_open();
		int Error= luaL_dofile(L_State, FullPathFileName);
		if( Error )
		{
			MessageBox::Show( lua_tostring( L_State , -1 ) , "警告" );

			lua_pop( L_State , 1 );
		}

		lua_close( L_State );
	}
	//////////////////////////////////////////////////////////////////////////

}

bool StringForm::_OutputFile_SimplifyProcess( fstream& file , const char* OpenFileName , const char* SubFile )
{
	char	Buf[256];
	char*	FileName;
	char    OutputFileName[256];
	//	char*	Path = (char*)Global::IniRootPath.c_str(); 

	sprintf( OutputFileName , "%s.%s" , OpenFileName , SubFile );
	Com_CreatePath( Global::GetDataPath().c_str() );

	FileName = CombineFilePath( Global::GetDataPath().c_str() , OutputFileName );
	String* strFileName = new String(FileName);

	file.open( FileName , ios::out | ios::binary );
	if( file.is_open() == false )
	{
		String* _tmpString = String::Format("Open file error : {0}\r\n", strFileName);
		_ErrorString = String::Concat(_ErrorString, _tmpString);

		_UpdateErrorString();
		_UpdateOutputStatus(EM_STROUT_STATUS_OPEN_DB_FILE_FAILED);
		//開檔失敗
		//sprintf( Buf , "%s 開檔失敗" ,  OutputFileName );
		//int Result = MessageBox::Show( Buf , "警告" );
		return false;
	}

	
	_OutputFileNameList->Add(strFileName);
	return true;
}

void StringForm::_UpdateOutputStep(int iStep)
{
	char Buf[256];

	_OutputStep = iStep;

	SqlDataReader* myReader;
	sprintf( Buf , "UPDATE StringOutputProgress SET OutputStep = %d  WHERE GUID = %d" , _OutputStep, _GUID);
	_UpdateCommand->CommandText = Buf;
	myReader = _UpdateCommand->ExecuteReader();
	myReader->Close();
}

void StringForm::_UpdateOutputStatus(int iStatus)
{
	char Buf[256];

	_OutputStatus = iStatus;

	SqlDataReader* myReader;
	sprintf( Buf , "UPDATE StringOutputProgress SET OutputStatus = %d  WHERE GUID = %d" , _OutputStatus, _GUID);
	_UpdateCommand->CommandText = Buf;
	myReader = _UpdateCommand->ExecuteReader();
	myReader->Close();
}

void StringForm::_UpdateProgress()
{
	char Buf[256];

	SqlDataReader* myReader;
	sprintf( Buf , "UPDATE StringOutputProgress SET Progress = %d, TotalRecord = %d  WHERE GUID = %d" , _CurrentRecordNum, _TotalRecordNum, _GUID);
	_UpdateCommand->CommandText = Buf;
	myReader = _UpdateCommand->ExecuteReader();
	myReader->Close();
}

void StringForm::_UpdateErrorString()
{
	SqlDataReader* myReader;
	String* SQLCommand = String::Format("UPDATE StringOutputProgress SET ErrorString = '{0}' WHERE GUID = {1}", _ErrorString, Convert::ToString(_GUID));
	_UpdateCommand->CommandText = SQLCommand;
	myReader = _UpdateCommand->ExecuteReader();
	myReader->Close();
}

void StringForm::OutputFile_SysString( int iLanguage, String * SQLCmd , bool OutputAll )
{
	if( OutputAll == false )
	{
		SQLCmd = String::Format( "{0} AND Translate = 1" , SQLCmd );
	}
	
	String* LanStr = GetLanguageString( iLanguage ).c_str();

	if( LanStr->Length == 0 )
		return;

	fstream file;
	char szFullFileName[256];
	
	sprintf( szFullFileName, "%s_%s", _OutputFileName, GetLanguageString( iLanguage ).c_str() );

	if( BaseForm::OutputFile_SimplifyProcess( file , szFullFileName , "DB"  ) == false )
		return;

	StringFileHeadStruct	OutPutData;
	SqlDataReader* myReader;

	bool bCheckOK = true;
	StringBuilder* sb = new StringBuilder(2048);

	//-----------------------------------------------------------------------------------------------------
	//TW不用比較
	if (iLanguage != EM_LanguageType_TW)
	{
		sb->Append(String::Format("OutputFile_SysString, Language = {0}\r\n", LanStr));
		sb->Append("*********************************************************************************************");
		sb->Append("\r\n");
	}
	//-----------------------------------------------------------------------------------------------------
	sqlCommand1->CommandText = SQLCmd;

	myReader = sqlCommand1->ExecuteReader();        
	while( myReader->Read() )
	{
		String* KeyStr			= myReader->GetString( 0 );
		String* ContentStr		= myReader->GetString( 1 );
		String* TwContentStr;
		if (myReader->FieldCount == 2)
		{
			TwContentStr	= myReader->GetString( 1 );
		}
		else
		{
			TwContentStr	= myReader->GetString( 2 );
		}

		if( TwContentStr->Length == 0 )
			ContentStr = "";

		string tempKeyStr = DotNetStr::StringToChar( KeyStr );
		const char *pszKey     = tempKeyStr.c_str();
		string tempContentStr = DotNetStr::StringToChar( ContentStr );
		const char *pszContent = tempContentStr.c_str();

		//------------------------------------------------------------------
		//String check TW不用比較
		if (iLanguage != EM_LanguageType_TW)
		{
			map<string, string>::iterator iter = g_mapSysString.find(pszKey);

			if (iter != g_mapSysString.end())
			{
				String* twContent = new String((iter->second).c_str());

				//目標語言內容跟 StrKey一致, 不檢查
				if (!String::Equals(KeyStr->ToLower()->Trim(), ContentStr->ToLower()->Trim()))
				{
					//檢查字串format
					if (!func_CheckStringFormat((iter->second).c_str(), pszContent))
					{								
						sb->Append(String::Format("字串內容格式錯誤, KEY = {0}\r\n", KeyStr));
						sb->Append(String::Format("Source(TW) CONTENT = {0}\r\n", twContent));
						sb->Append(String::Format("Target({0}) CONTENT = {1}\r\n", LanStr, ContentStr));
						sb->Append("\r\n");
						sb->Append("*********************************************************************************************");
						sb->Append("\r\n");

						bCheckOK = false;
					}
				}
				else
				{
					Sleep(0);
				}
			}
		}

		//------------------------------------------------------------------
		strncpy_s( OutPutData.KeyStr , sizeof(OutPutData.KeyStr) , pszKey , sizeof(OutPutData.KeyStr) );

		if( ContentStr->Length != 0 )
		{
			char utf8 __gc[] = Encoding::UTF8->GetBytes( ContentStr );
			char __pin *charUtf8Str = &utf8[0];  
			OutPutData.ContentSize = strlen( charUtf8Str ) + 1;
	
			if( OutPutData.ContentSize > 8000 )
			{
				int a = 3;
				MessageBox::Show( "OutPutData.ContentSize > 8000" , "訊息" );
			}
			
			strcpy( OutPutData.Content , charUtf8Str );



		}
		else
		{
			OutPutData.Content[0] = 0;
			OutPutData.ContentSize = 1;
		}

		file.write( (char*)&OutPutData.KeyStr		, sizeof(OutPutData.KeyStr) );
		file.write( (char*)&OutPutData.ContentSize	, sizeof(int) );
		file.write( (char*)&OutPutData.Content		, OutPutData.ContentSize );
	}
	myReader->Close();
	//-----------------------------------------------------------------------------------------------------
	file.close();

	//-----------------------------------------------------------------------------------------------------
	if (!bCheckOK)
	{
		_sbList->Add(sb);
	}
	//-----------------------------------------------------------------------------------------------------

	//////////////////////////////////////////////////////////////////////////
	//完成後上傳
	//////////////////////////////////////////////////////////////////////////

// 	String* tempPath = String::Format("C:\\RuneTempData\\{0}.db", new String(szFullFileName));
// 	String* RealPath = String::Format("{0}\\{1}.db", new String(Global::GetDataPath().c_str()), new String(szFullFileName));
// 	if (!System::IO::Directory::Exists(new String(Global::GetDataPath().c_str())))
// 	{
// 		System::IO::Directory::CreateDirectory(new String(Global::GetDataPath().c_str()));
// 	}
// 	System::IO::File::Copy(tempPath, RealPath, true);
}
//------------------------------------------------------------------------------------------------------

void StringForm::OutputFile_ClientString( int iLanguage, String* FileName , String * SQLCmd )
{

	char szFullFileName[256];

	if( strlen( GetLanguageString( iLanguage ).c_str() ) == 0 )
		return;

	sprintf( szFullFileName, "%s_%s", DotNetStr::StringToChar( FileName ).c_str() , GetLanguageString( iLanguage ).c_str() );


	fstream file;
	if( BaseForm::OutputFile_SimplifyProcess( file , DotNetStr::StringToChar( szFullFileName ).c_str() , "lua"  ) == false )
		return;

	SqlDataReader* myReader;

	bool bCheckOK = true;
	StringBuilder* sb = new StringBuilder();
	String* LanStr = GetLanguageString( iLanguage ).c_str();

	//ArrayList* updateCmds = new ArrayList();

	//TW不用比較
	if (iLanguage != EM_LanguageType_TW)
	{
		sb->Append(String::Format("OutputFile_ClientString, FileName = {1}, Language = {0}\r\n", FileName, LanStr));
		sb->Append("*********************************************************************************************");
		sb->Append("\r\n");
	}
	//------------------------------------------------------------------
	sqlCommand1->CommandText = SQLCmd;

	myReader = sqlCommand1->ExecuteReader();        
	while( myReader->Read() )
	{
		String* KeyStr			= myReader->GetString( 0 );
		String* ContentStr		= myReader->GetString( 1 );
		String* TwContentStr;
		String* Note;
		if (myReader->FieldCount == 3)		 //column數量不同做取值
		{
			TwContentStr	= myReader->GetString( 1 );
			Note = myReader->GetString( 2 );
		}
		else
		{
			TwContentStr	= myReader->GetString( 2 );
			Note = myReader->GetString( 3 );
		}

		if( TwContentStr->Length == 0 )
			ContentStr = "";

		string tempKeyStr = DotNetStr::StringToChar( KeyStr );
		const char *pszKey     = tempKeyStr.c_str();
		string tempContentStr = DotNetStr::StringToChar( ContentStr );
		const char *pszContent = tempContentStr.c_str();

		//------------------------------------------------------------------
		//String check TW不用比較
		if (iLanguage != EM_LanguageType_TW)
		{
			map<string, string>* pmapStr = NULL;

			if (String::Equals(FileName, "String"))
			{
				pmapStr = &g_mapCliString;
			}
			else if (String::Equals(FileName, "LoginString"))
			{
				pmapStr = &g_mapLoginString;
			}

			map<string, string>::iterator iter = pmapStr->find(pszKey);

			if (iter != pmapStr->end())
			{
				String* twContent = new String((iter->second).c_str());

				//目標語言內容跟StrKey一致, 不檢查
				if (!String::Equals(KeyStr->ToLower()->Trim(), ContentStr->ToLower()->Trim()))
				{
					//檢查字串format
					if (!func_CheckStringFormat((iter->second).c_str(), pszContent))
					{
						sb->Append(String::Format("字串內容格式錯誤, KEY = {0}\r\n", KeyStr));
						sb->Append(String::Format("Source(TW) CONTENT = {0}\r\n", twContent));
						sb->Append(String::Format("Target({0}) CONTENT = {1}\r\n", LanStr, ContentStr));
						sb->Append("\r\n");
						sb->Append("*********************************************************************************************");
						sb->Append("\r\n");
						bCheckOK = false;
					}
				}
				else
				{
					Sleep(0);
				}
			}
		}
		//------------------------------------------------------------------
		
		char*	Str ;
		int		Strlen;
		int		TotalStrlen;

		//註解
//		Str = "--";
//		file.write( Str		, strlen( Str ) );
//		Str = DotNetStr::StringToChar( Note );
//		file.write( Str		, strlen( Str ) );
		//Str = "\r\n"
		//file.write( Str		, strlen( Str ) );
//		file.put( '\r' );file.put( '\n' );


		char Buf[0x10000];

		//Key 與 內容
		const wchar_t __pin* wstr = PtrToStringChars(KeyStr);
		TotalStrlen = WCharToUTF8( wstr , Buf , sizeof(Buf) ) -1;
		file.write( Buf	,  TotalStrlen );
		Str = " = \"";
		file.write( Str , strlen( Str ) );

		wstr = PtrToStringChars(ContentStr);
		Strlen = WCharToUTF8( wstr , Buf , sizeof(Buf) ) -1;
		//file.write( Buf	,  Strlen );
		TotalStrlen = TotalStrlen + Strlen + 5;

		for( int i = 0 ; i < Strlen ; i++ )
		{
			if( Buf[i] == '\r' )
				continue;
			if( Buf[i] == '\n' )
			{
				file.put( '\\' );file.put( 'n' );

			}
			else if( Buf[i] == '\"' )
			{
				file.put( '\\' );
				file.put( '\"' );
			}
			else
			{
				file.put( Buf[i] );
			}
		}

		file.put( '\"' );

		for( int i = TotalStrlen/4 ; i < 16 ; i++ )
		{
			file.put( '\t' );
		}

		Str = "\t--";
		file.write( Str		, strlen( Str ) );

		wstr = PtrToStringChars(Note);
		Strlen = WCharToUTF8( wstr , Buf , sizeof(Buf) ) -1;

		//Str = DotNetStr::StringToChar( Note );
		file.write( Buf		, Strlen );

		file.put( '\r' );file.put( '\n' );
	}
	myReader->Close();
	file.close();

	//////////////////////////////////////////////////////////////////////////
	{
		//char	FileName[512];
		//sprintf( FileName , "%s.lua" , szFullFileName ) ;
		string  FileName = string(szFullFileName) + ".lua";
		char* FullPathFileName = CombineFilePath( Global::GetDataPath().c_str() , FileName.c_str() );
		//std::string TempDir = "C:\\RuneTempData\\";
		//char* FullPathFileName = CombineFilePath(TempDir.c_str() , FileName.c_str() );

		lua_State* L_State;
		L_State  = lua_open();
		int Error= luaL_dofile(L_State, FullPathFileName);
		if( Error )
		{
			MessageBox::Show( lua_tostring( L_State , -1 ) , "警告" );

			lua_pop( L_State , 1 );
		}

		lua_close( L_State );
	}
	//////////////////////////////////////////////////////////////////////////

	//-----------------------------------------------------------------------------------------------------
	if (!bCheckOK)
	{
		_sbList->Add(sb);
	}
	//-----------------------------------------------------------------------------------------------------

	//////////////////////////////////////////////////////////////////////////
	//完成後上傳
	//////////////////////////////////////////////////////////////////////////

// 	String* tempPath = String::Format("C:\\RuneTempData\\{0}.lua", new String(szFullFileName));
// 	String* RealPath = String::Format("{0}\\{1}.lua", new String(Global::GetDataPath().c_str()), new String(szFullFileName));
// 	if (!System::IO::Directory::Exists(new String(Global::GetDataPath().c_str())))
// 	{
// 		System::IO::Directory::CreateDirectory(new String(Global::GetDataPath().c_str()));
// 	}
// 	System::IO::File::Copy(tempPath, RealPath, true);
}
//------------------------------------------------------------------------------------------------------
void    StringForm::OutputFile( bool OutputAll )
{
	OutputFile_SysString	( 0, "SELECT KeyStr,Content FROM StringDB Where Type <> 0" , OutputAll );
	OutputFile_ClientString	( 0, "String" , "SELECT KeyStr,Content,Note FROM StringDB Where Type = 0" );
	OutputFile_ClientString	( 0, "LoginString" , "SELECT KeyStr,Content,Note FROM StringDB Where Type = 3" );
}

void    StringForm::OutputFileLanguage( int LanguageID )
{
	if( LanguageID == 0 )
	{
		OutputFile( false );
		return;
	}
	else if( LanguageID == -2 )
	{
		OutputFile( true );
		return;
	}
	else if( LanguageID == -1 )
	{
		//輸出繁體
		OutputFile( false );

		//準備字串格式檢查
		PrepareCheckStringFormat();

		for(  int i = 1 ; i < GetTotalLanguage() ; i++ )
		{
			char Buf[ 512 ];
			sprintf( Buf , "SELECT KeyStr,Content_Language%d ,Content FROM StringDB Where Type <> 0" , i );

			OutputFile_SysString	( i, Buf , false );

			sprintf( Buf , "SELECT KeyStr,Content_Language%d ,Content,Note FROM StringDB Where Type = 0" , i );
			OutputFile_ClientString( i,"String", Buf );

			sprintf( Buf , "SELECT KeyStr,Content_Language%d , Content,Note FROM StringDB Where Type = 3" , i );
			OutputFile_ClientString( i,"LoginString", Buf );
		}

		EndCheckStringFormat();
	}
	else
	{
		PrepareCheckStringFormat();

		char Buf[ 512 ];
		sprintf( Buf , "SELECT KeyStr,Content_Language%d,Content FROM StringDB Where Type <> 0" , LanguageID );

		OutputFile_SysString	( LanguageID, Buf , false );

		sprintf( Buf , "SELECT KeyStr,Content_Language%d,Content,Note FROM StringDB Where Type = 0" , LanguageID );
		OutputFile_ClientString( LanguageID, "String", Buf );

		sprintf( Buf , "SELECT KeyStr,Content_Language%d,Content,Note FROM StringDB Where Type = 3" , LanguageID );
		OutputFile_ClientString( LanguageID, "LoginString", Buf );

		EndCheckStringFormat();
	}

}

//------------------------------------------------------------------------------------------------------
/*
void    StringForm::OutputFileByStringTable( )
{
	OutputFile_SysString	( "SELECT KeyStr,Content_Language2 FROM StringDB Where Type <> 0" );
	OutputFile_ClientString	( "SELECT KeyStr,Content_Language2 ,Note FROM StringDB Where Type = 0" );
}
*/
//------------------------------------------------------------------------------------------------------

System::Void StringForm::OnTimeProc(System::Object*  sender, System::EventArgs*  e)
{
	if( _IsNeedUpdate  == true || _IsNeedFill  == true ) 
	{
		_IsNeedUpdate = false;
		UpDateData( );
	}

	if( _IsNeedFill  == true )
	{
		_IsNeedFill = false;
		DataFill( );
	}
}
System::Void StringForm::StringForm_Load(System::Object*  sender, System::EventArgs*  e)
{
	//開啟預設不讀取String
	_IsNeedFill	 = false;

	_IsNeedUpdate = false;
	timer1->Enabled = true;

	static bool bLoadDataFromDatabase = false;

	if( bLoadDataFromDatabase == false )
	{
		bLoadDataFromDatabase = true;

		SqlDataReader* myReader;

		// DirZoneID
		{
			map< int, std::string >	mapDir;

			sqlCommand1->CommandText = "Select KeyStr, content from StringDB Where KeyStr LIKE 'DIR_ZONEID_%' ORDER BY KeyStr";
			myReader = sqlCommand1->ExecuteReader();
			CB_DirZoneID->Items->Clear();
			while( myReader->Read() )
			{                
				std::string sKey			=	DotNetStr::StringToChar( myReader->GetString( 0 ) );
				std::string sContent		=	DotNetStr::StringToChar( myReader->GetString( 1 ) );

				int		iID			=	GetStringID( sKey.c_str(), "DIR_ZONEID_" );
				mapDir[ iID ]		=	sContent;
				//comboBox1->Items->Add( Str );
			}
			myReader->Close();

			for( map< int, std::string >::iterator it = mapDir.begin(); it != mapDir.end(); it++ )
			{
				ComboBoxItem* newItem = new ComboBoxItem( it->first, (it->second).c_str() );
				CB_DirZoneID->Items->Add( newItem );		
			}
		}

		// DirVersionID
		{
			map< int, std::string >	mapDir;

			sqlCommand1->CommandText = "Select KeyStr, content from StringDB Where KeyStr LIKE 'DIR_VERSIONID_%' ORDER BY KeyStr";
			myReader = sqlCommand1->ExecuteReader();
			CB_DirVersionID->Items->Clear();
			while( myReader->Read() )
			{                
				std::string sKey			=	DotNetStr::StringToChar( myReader->GetString( 0 ) );
				std::string sContent		=	DotNetStr::StringToChar( myReader->GetString( 1 ) );

				int		iID			=	GetStringID( sKey.c_str(), "DIR_VERSIONID_" );
				mapDir[ iID ]		=	sContent;
				//comboBox1->Items->Add( Str );
			}
			myReader->Close();

			for( map< int, std::string >::iterator it = mapDir.begin(); it != mapDir.end(); it++ )
			{
				ComboBoxItem* newItem = new ComboBoxItem( it->first, (it->second).c_str() );
				CB_DirVersionID->Items->Add( newItem );
			}
		}

		// DirTagID
		{
			map< int, std::string >	mapDir;

			sqlCommand1->CommandText = "Select KeyStr, content from StringDB Where KeyStr LIKE 'DIR_TAGID_%' ORDER BY KeyStr";
			myReader = sqlCommand1->ExecuteReader();
			CB_DirTagID->Items->Clear();
			while( myReader->Read() )
			{                
				std::string sKey			=	DotNetStr::StringToChar( myReader->GetString( 0 ) );
				std::string sContent		=	DotNetStr::StringToChar( myReader->GetString( 1 ) );

				int		iID			=	GetStringID( sKey.c_str(), "DIR_TAGID_" );
				mapDir[ iID ]		=	sContent;
				//comboBox1->Items->Add( Str );
			}
			myReader->Close();

			for( map< int, std::string >::iterator it = mapDir.begin(); it != mapDir.end(); it++ )
			{	
				ComboBoxItem* newItem = new ComboBoxItem( it->first, (it->second).c_str() );
				CB_DirTagID->Items->Add( newItem );
			}
		}

		CB_DirZoneID->SelectedIndex		= 0;
		CB_DirTagID->SelectedIndex		= Global::GetStringDirTagID();
		CB_DirVersionID->SelectedIndex	= Global::GetDirVersionID();
		checkBoxTranslate->Checked		= true;
	}


}

System::Void StringForm::OnKeySelectCheckChanged(System::Object*  sender, System::EventArgs*  e)
{
	_IsNeedFill = true;
	TB_SelectKey->Enabled = CKB_SelectKeyChecked->Checked;
}

System::Void StringForm::OnAddNewData(System::Object*  sender, System::EventArgs*  e)
{
	_IsNeedFill = true;
	//檢查 Key 資料是否已經存在
	if(	CB_NewType->SelectedIndex == -1 )
	{
		CB_NewType->SelectedIndex = 0; 
	}
	if( CB_NewType->SelectedIndex == 1 )
	{
		MessageBox::Show( L"類型有問題，不可以用物件類型" , L"錯誤" , MessageBoxButtons::OK );			
		return;
	}
	if( TB_NewKey->Text->Length == 0 )
	{
		MessageBox::Show( L"Key值沒設" , L"錯誤" , MessageBoxButtons::OK );			
		return;
	}

	SqlDataReader* myReader;
	sqlCommand1->CommandText = String::Format( "SELECT Count(KeyStr) FROM StringDB WHERE KeyStr = '{0}'" , TB_NewKey->Text );
	myReader = sqlCommand1->ExecuteReader();        
	if( myReader->Read() )
	{
		if( myReader->GetInt32( 0 ) != 0 )
		{
			myReader->Close();
			_IsNeedFill = true;
			MessageBox::Show( L"此Key已存再" , L"警告" , MessageBoxButtons::OK );			
			return;
		}
	}
	
	myReader->Close();

	DataTable* myDataTable =  dataSet31->Tables->Item[ gridControl1->DataMember ];
	DataRow* myDataRow = myDataTable->NewRow();
	


	TB_NewKey->Text = TB_NewKey->Text->Replace( L" " , L""  );
//	String* Type = "0";
	myDataRow->Item[L"KeyStr"]		= TB_NewKey->Text->ToUpper();
	myDataRow->Item[L"Type"]		= String::Format( "{0}" , __box(CB_NewType->SelectedIndex) );
	myDataRow->Item[L"SubType"]		= TB_SubType->Text;
	myDataRow->Item[L"Note"]		= TB_NewNote->Text;
	myDataRow->Item[L"Content"]		= TB_NewContent->Text;

	myDataRow->Item[L"Content"]		= TB_NewContent->Text;

	myDataRow->Item[L"Translate"]		= String::Format( "{0}" , __box( checkBoxTranslate->Checked ) );

	myDataRow->Item[L"DirZoneID"]	= String::Format( "{0}" , __box( ((ComboBoxItem*)CB_DirZoneID->SelectedItem)->m_Key) );
	myDataRow->Item[L"DirTagID"]	= String::Format( "{0}" , __box( ((ComboBoxItem*)CB_DirTagID->SelectedItem)->m_Key) );
	myDataRow->Item[L"DirVersionID"]= String::Format( "{0}" , __box( ((ComboBoxItem*)CB_DirVersionID->SelectedItem)->m_Key) );

	myDataTable->Rows->Add(myDataRow);    

	TB_NewKey->Text = "";
	TB_NewNote->Text = "";
	TB_NewContent->Text = "";

	//CB_DirTagID->SelectedIndex		= Global::GetStringDirTagID();
	//CB_DirVersionID->SelectedIndex	= Global::GetDirVersionID();

	
	_IsNeedUpdate = true;

}
System::Void StringForm::gridView1_FocusedRowChanged(System::Object*  sender, DevExpress::XtraGrid::Views::Base::FocusedRowChangedEventArgs*  e)
{
	_IsNeedUpdate = true;
}
/*
System::Void StringForm::OutputDataClick(System::Object*  sender, System::EventArgs*  e)
{
	OutputFile( );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
*/
System::Void StringForm::OutputLanguageDesignClick(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( -2 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage0Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 0 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage1Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 1 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage2Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 2 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage3Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 3 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage4Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 4 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage5Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 5 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}System::Void StringForm::OutputLanguage6Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 6 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage7Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 7 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage8Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 8 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage9Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 9 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage10Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 10 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage11Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 11 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage12Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 12 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage13Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 13 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage14Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 14 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage15Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 15 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage16Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 16 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage17Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 17 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage18Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 18 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage19Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 19 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage20Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 20 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage21Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 21 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
System::Void StringForm::OutputLanguage22Click(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileLanguage( 22 );
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
/*
System::Void StringForm::OutputDataByStringDBClick(System::Object*  sender, System::EventArgs*  e)
{
	OutputFileByStringTable();
	MessageBox::Show( L"完成" , L"訊息" , MessageBoxButtons::OK );			
}
*/
System::Void StringForm::TB_SelectKey_TextChanged(System::Object*  sender, System::EventArgs*  e)
{
	//_IsNeedFill = true;
}
System::Void StringForm::CB_SelectType_SelectedIndexChanged(System::Object*  sender, System::EventArgs*  e)
{
	_IsNeedFill = false;
	switch( CB_SelectType->SelectedIndex )
	{
	case 0:
		timer1->Interval = 500;
		break;
	case 1:
		timer1->Interval = 2000;
		break;
	case 2:
		timer1->Interval = 2000;
		break;
	}
}
System::Void StringForm::DelString_Click(System::Object*  sender, System::EventArgs*  e)
{
	System::Windows::Forms::DialogResult Result;

	try
	{
		DataTable* myDataTable =  dataSet31->Tables->Item[ gridControl1->DataMember ];
	
		DevExpress::XtraGrid::Views::Grid::GridView* RowView =  static_cast< DevExpress::XtraGrid::Views::Grid::GridView* >(gridControl1->FocusedView);

		DataRow* myDataRow = RowView->GetDataRow( RowView->FocusedRowHandle );

		String* Msg = String::Format( "刪除 Key = {0}" , myDataRow->Item[L"KeyStr"] );

		Result = MessageBox::Show( Msg , L"警告" , MessageBoxButtons::OKCancel );

		if( Result != DialogResult::OK  )
			return;
		//...........刪除
		//DELETE FROM [StringDB] WHERE (([KeyStr] = 
		sqlCommand1->CommandText = String::Format( "DELETE FROM StringDB WHERE KeyStr = '{0}'" , myDataRow->Item[L"KeyStr"] );
		sqlCommand1->ExecuteReader()->Close();        
		myDataTable->Rows->Remove( myDataRow );
	}
	catch(...)
	{

	}

}

int StringForm::GetStringID( const char* pSource, const char* pKey )
{
	if( pSource == NULL || pKey == NULL )
		return 0;

	int iSourceLen	= strlen( pSource );
	int iKeyLen		= strlen( pKey );
	int iValueLen	= iSourceLen - iKeyLen;

	char szValue[1024];

	ZeroMemory( szValue, sizeof( szValue ));
	memcpy( szValue, pSource + iKeyLen, iValueLen );

	int iVal		= atoi( szValue );

	return iVal;

}

void StringForm::PrepareCheckStringFormat()
{
	g_mapSysString.clear();
	g_mapCliString.clear();
	g_mapLoginString.clear();

	std::string strKey;
	std::string strContent;

	SqlDataReader* myReader;

	sqlCommand1->CommandText = "SELECT KeyStr,Content FROM StringDB Where Type <> 0";

	myReader = sqlCommand1->ExecuteReader(); 

	while( myReader->Read() )
	{
		strKey     = DotNetStr::StringToChar( myReader->GetString(0) );
		strContent = DotNetStr::StringToChar( myReader->GetString(1) );
		g_mapSysString[strKey] = strContent;
	}

	myReader->Close();

	sqlCommand1->CommandText = "SELECT KeyStr,Content,Note FROM StringDB Where Type = 0";

	myReader = sqlCommand1->ExecuteReader(); 

	while( myReader->Read() )
	{
		strKey     = DotNetStr::StringToChar( myReader->GetString(0) );
		strContent = DotNetStr::StringToChar( myReader->GetString(1) );
		g_mapCliString[strKey] = strContent;
	}

	myReader->Close();

	sqlCommand1->CommandText = "SELECT KeyStr,Content,Note FROM StringDB Where Type = 3";

	myReader = sqlCommand1->ExecuteReader(); 

	while( myReader->Read() )
	{
		strKey     = DotNetStr::StringToChar( myReader->GetString(0) );
		strContent = DotNetStr::StringToChar( myReader->GetString(1) );
		g_mapLoginString[strKey] = strContent;
	}

	myReader->Close();

	_sbList->Clear();
}



void StringForm::EndCheckStringFormat()
{
	g_mapSysString.clear();
	g_mapCliString.clear();
	g_mapLoginString.clear();


	for (int i = 0; i < _sbList->Count; i++)
	{
		StringBuilder* sb = (StringBuilder*)_sbList->get_Item(i);

		MessageDialog* dlg = new MessageDialog();

		dlg->ShowMessage(sb->ToString(), "Warning");
	}
}

void StringForm::SelectString(System::Object*  sender, System::EventArgs*  e)
{
	_IsNeedFill = true;
}