	strPath.Format("%s\\SP-Console.exe",szPath);// ConsoleUpdater.cpp : 응용 프로그램에 대한 클래스 동작을 정의합니다.
//

#include "stdafx.h"
#include "ConsoleUpdater.h"
#include "ConsoleUpdaterDlg.h"
#include "FileVersionInfo.h"
#include "../Common/MyPing.h"
#include <afxsock.h>		// MFC socket extensions

#include "../Common/RegUtil.h"

#import <msxml3.dll>
using namespace MSXML2;

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#include <afxsock.h>

// CConsoleUpdaterApp

BEGIN_MESSAGE_MAP(CConsoleUpdaterApp, CWinApp)
	ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()


// CConsoleUpdaterApp 생성

CConsoleUpdaterApp::CConsoleUpdaterApp()
{
	// TODO: 여기에 생성 코드를 추가합니다.
	// InitInstance에 모든 중요한 초기화 작업을 배치합니다.
}


// 유일한 CConsoleUpdaterApp 개체입니다.

CConsoleUpdaterApp theApp;


// CConsoleUpdaterApp 초기화
int GetCurrentPath(char* pszPath)
{
	char	szPath[MAX_PATH]={0};
	char* pData;

	GetModuleFileName(NULL,szPath,MAX_PATH);

	pData = strrchr(szPath,'\\');

	strncpy(pszPath,szPath,pData-szPath);
	return int(strlen(pszPath));
}

BOOL MyCreateDirectory(CString sDirectory)
{
	CString sPath = "";

	int     iToken = 0;
	CString sText  = sDirectory.Tokenize("\\", iToken);
	while (sText != "")
	{
		sPath += sText + "\\";

		if (sPath.GetLength() > 3 && !CreateDirectory(sPath, NULL))
		{
			DWORD dwError = GetLastError();
			if (dwError != ERROR_ALREADY_EXISTS)
			{
				SetLastError(dwError);
				return false;
			}
		}

		sText  = sDirectory.Tokenize("\\", iToken);
		if(iToken<0)
			break;
	}

	return true;
}

BOOL CConsoleUpdaterApp::CheckServer()
{
	CMyPing	p;

	BOOL bRet = TRUE;
	bRet = p.Ping2(1, DOWN_HOST);

	if (!bRet)
	{
		MessageBox(NULL,"서버에 연결할수 없습니다. 네트웍 연결상태를 확인하세요","SP-Console 업데이터",MB_OK);
		return TRUE;
	}

	return TRUE;
}

BOOL CConsoleUpdaterApp::InitInstance()
{
	HANDLE hMutex = ::CreateMutex(NULL, TRUE, _T("SP-UpdaterXXXXXXXXXXXXXXX"));
	if (!hMutex && ::GetLastError() == ERROR_ALREADY_EXISTS) {
		CloseHandle(hMutex);
		return FALSE;
	}

	// 응용 프로그램 매니페스트가 ComCtl32.dll 버전 6 이상을 사용하여 비주얼 스타일을
	// 사용하도록 지정하는 경우, Windows XP 상에서 반드시 InitCommonControls()가 필요합니다. 
	// InitCommonControls()를 사용하지 않으면 창을 만들 수 없습니다.
	InitCommonControls();

	CWinApp::InitInstance();

	AfxEnableControlContainer();

	if (CheckServer() == FALSE)
		return FALSE;

	CStringArray saFile;
	GetUpdateFileList(saFile);
	
	CString	sUpdater="2";

	if (saFile.GetCount() > 0) 
	{
		CConsoleUpdaterDlg dlg;

		dlg.SetFileList(saFile);
		if (dlg.DoModal() != IDOK)
			return FALSE;

		sUpdater = dlg.m_bIsSelfUpdate? "1":"0";
	}
	
	char	szPath[MAX_PATH]={0};
	CString strPath;
	
	GetCurrentPath(szPath);

#ifdef _OPENDISK
	strPath.Format("%s\\OD-Console.exe",szPath);	
#else
	strPath.Format("%s\\SP-Console.exe",szPath);
#endif
	
	ShellExecute(NULL, NULL, strPath, sUpdater, NULL, SW_SHOW);

	CloseHandle(hMutex);

	// 대화 상자가 닫혔으므로 응용 프로그램의 메시지 펌프를 시작하지 않고
	// 응용 프로그램을 끝낼 수 있도록 FALSE를 반환합니다.
	return FALSE;
}

CStringArray& VersionSplit(CString string, CStringArray& array)
{
	while (string.GetLength() > 0)
	{
		int Pos = string.Find(".");
		if (Pos != -1)
		{
			array.Add(string.Left(Pos));
			string = string.Mid(Pos + 1);
		}
		else
		{
			array.Add(string);
			string = "";
		}
	}
	return array;
}

BOOL CConsoleUpdaterApp::CheckUpdate(CString &strLocal,  CString &strRemote)
{
	CStringArray localver, remotver;
	VersionSplit(strLocal, localver);
	VersionSplit(strRemote, remotver);

	// 버전 형식이 맞지 않으면 업데이트 서버 우선 시 함
	if( localver.GetCount() != remotver.GetCount() )
		return TRUE;

	// 버전 단위 체크
	for (int i = 0; i < remotver.GetCount(); ++i)
	{
		if( atoi( localver[i] ) < atoi( remotver[i] ) )
			return TRUE;
	}

	return FALSE;
}

void CConsoleUpdaterApp::GetUpdateFileList(CStringArray& saFile)
{
	CString		strPath;
	CString		sURL = DOWN_URL;
	CString		sFileName;
	CString		strTemp;
	CString		LocalVersion;
	CString		RemotVersion;
	CString		strLocalFile;
	int			nIndex=1;
	char		szBuffer[MAX_PATH]={0};
	char		szPath[MAX_PATH]={0};
	DWORD		dwRet;
	CFileVersionInfo	FileInfo;
	char		szVersion[20]={0};	

	if(GetCurrentPath(szPath) >0)
	{
		strPath.Format("%s\\update\\",szPath);
		MyCreateDirectory(strPath);
	}
	else
		return;

	strPath += "update.ini";
	if (URLDownloadToFile(NULL, sURL + "/update.ini", strPath, 0, NULL) != S_OK)
		return;

	do
	{
		strTemp.Format("%d",nIndex);
		
		dwRet = GetPrivateProfileString("FILES",strTemp,NULL,szBuffer,sizeof(szBuffer),strPath);

		if (dwRet)
		{
			strLocalFile.Format("%s\\%s",szPath,szBuffer);
			FileInfo.Create(strLocalFile);
			LocalVersion = FileInfo.GetFileVersion();
			GetPrivateProfileString(szBuffer,"Version",NULL,szVersion,sizeof(szVersion),strPath);
			RemotVersion = szVersion;

			if(CheckUpdate(LocalVersion, RemotVersion))
				saFile.Add(strLocalFile);
		}
		nIndex ++;
	}while(dwRet);
	return;
}

CString GetErrorMessage(DWORD dwError)
{
	CString sError;
	LPVOID lpBuffer;

	if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpBuffer, 0, NULL))
		sError = "알 수 없는 오류입니다.";
	else
		sError = (LPCTSTR)lpBuffer;
 
	LocalFree(lpBuffer);

	return sError;
}
