#include "stdafx.h"
#include "PatcherApp.h"
#include "PatcherDlg.h"

#include "FileSystem.h"
#include "HttpDownloader.h"

#define PATCHER_MUTEX			"IrisPatcher Mutex"
#define PATCHER_CMD_LINE		"-dkdlfltmeoqkr"

cPatcherApp theApp;

cPatcherApp::cPatcherApp()
{
	mMutex = 0;
	mSkinManager = 0;

	/// 파일 시스템 생성
	new cFileSystem;
}

cPatcherApp::~cPatcherApp()
{
	if( mSkinManager )
	{
		delete mSkinManager;
		mSkinManager = 0;
	}

	delete FILESYSTEM;

	if( mMutex )
		::CloseHandle( mMutex );
}

BOOL cPatcherApp::InitInstance()
{
	CWinApp::InitInstance();

	/// 프로그램 중복 실행 방지
	if( CheckMutex() == false )
	{
		return FALSE;
	}

	/// 명령줄
	if( ::strcmp(m_lpCmdLine, PATCHER_CMD_LINE) != 0 )
	{
		MessageBox( 0, "This program must be executed by Launcher", PATCHER, MB_OK );
		return 0;
	}

	/// 실행 파일의 경로를 기반 디렉토리로 설정
	//TCHAR exePathName[MAX_PATH];
	//::GetModuleFileName( AfxGetApp()->m_hInstance, exePathName, MAX_PATH );

	//cString exePath = exePathName;
	//::GetFilePath( &exePath, exePath );

	//::SetCurrentDirectory( exePath.Cstr() );

	/// Initialize COM Library - INTERNET API(wininet.h/wininet.lib)를 사용하기 위해
	if( CoInitialize( 0 ) != S_OK )
	{
		MessageBox( 0, "CoInitialize Failed!", PATCHER, MB_OK );
		return 0;
	}

	/// 기본 설정을 로딩
	bool initFailed = false;

// 	if( LoadConfig() == false )
// 	{
// 		MessageBox( 0, "Failed to load config.", PATCHER, MB_OK );
// 		initFailed = true;
// 	}

	/// 스킨 정보 로딩
	if( LoadSkin() == false )
	{ 
		MessageBox( 0, "Failed to load skin info.", PATCHER, MB_OK );
		initFailed = true;
	}


// 	if( initFailed )
// 	{
// 		/// 초기화 실패시 최신 패처를 다시 받음
// 		cHttpDownloader downloader;
// 		if( downloader.Open( mHostName.Cstr() ) == false )
// 		{
// 			MessageBox( 0, "Failed to connect to patch server.", PATCHER, MB_OK );
// 			return FALSE;
// 		}
// 
// 		tArray<BYTE> buffer;
// 		cString downName;
// 		downName.Format( "%s%s", mBaseDir.Cstr(), PATCHER_FILENAME );
// 
// 		if( downloader.ReadFile( buffer, downName ) == false )
// 		{
// 			MessageBox( 0, "Failed to download server patcher file.", PATCHER, MB_OK );
// 			return FALSE;
// 		}
// 
// 		cFileSaver saver;
// 		if( saver.Open( PATCHER_NEW_FILENAME ) == false )
// 			return FALSE;
// 
// 		if( saver.Write( &buffer[0], buffer.GetSize() ) != buffer.GetSize() )
// 			return FALSE;
// 
// 
// 		cString path;
// 		path.Format( ".\\%s", LAUNCHER_FILENAME );
// 		int ret = (int)::ShellExecute( 0, "open", path.Cstr(), "-updatePatcher", 0, SW_HIDE );
// 
// 		if( ret <= 32 )
// 			return FALSE;
// 	}
// 	else
// 	{
		/// 다이얼로그 띄움
		cPatcherDlg dlg( mPath, mHostName, mBaseDir, mCmdLine );
		m_pMainWnd = &dlg;

		dlg.DoModal( mSkinManager->GetContainer( "main" ) );
//	}

	return TRUE;
}

int cPatcherApp::ExitInstance()
{
	CoUninitialize();
	return 0;
}

bool cPatcherApp::CheckMutex()
{
	/// 뮤텍스 생성
	HANDLE mutex = ::CreateMutex( 0, TRUE, PATCHER_MUTEX );

	/// 뮤텍스가 이미 존재하는지 검사
	bool alreadyExist = false;
	if( ::GetLastError() == ERROR_ALREADY_EXISTS )
		alreadyExist = true;

	if( alreadyExist == false )
		mMutex = mutex;
	else if( mutex )
		::ReleaseMutex( mutex );

	return !alreadyExist;
}

// bool cPatcherApp::LoadConfig()
// {
// 	//int windowed;
// 	//fscanf( pfile, "%d", &windowed );
// 	//fclose( pfile );
// 
// 	cFileLoader loader;
// 	if( loader.Open( PATCH_CONFIG_FILENAME, true ) == false )
// 		return false;
// 
// 	cLexer lexer( loader.GetBufferPtr(), loader.GetSize() );
// 	cParser parser( &lexer, PATCH_CONFIG_FILENAME );
// 
// 	if( parser.ExpectTokenString( "IrisPatchConfig" ) == false )
// 		return false;
// 
// 	parser.ParseInt();
// 
// 	/// 언어
// 	cString local;
// 	if( parser.ExpectTokenString( "local" ) == false )
// 		return false;
// 	if( parser.ParseString( &local ) == false )
// 		return false;
// 
// 	/// 호스트 이름
// 	if( parser.ExpectTokenString( "host" ) == false )
// 		return false;
// 	if( parser.ParseString( &mHostName ) == false )
// 		return false;
// 	if( mHostName.IsEmpty() )
// 		return false;
// 
// 	/// 기반 디렉토리
// 	if( parser.ExpectTokenString( "base" ) == false )
// 		return false;
// 	if( parser.ParseString( &mBaseDir ) == false )
// 		return false;
// 	if( mBaseDir.IsEmpty() )
// 		return false;
// 
// 	/// 명령인수
// 	if( parser.ExpectTokenString( "cmdline" ) == false )
// 		return false;
// 	if( parser.ParseString( &mCmdLine ) == false )
// 		return false;
// 	if( mCmdLine.IsEmpty() )
// 		return false;
// 
// 	mBaseDir.TrimRight( "/\\" );
// 	mBaseDir += '/';
// 
// 	/// 경로 설정
// 	mPath.Format( "Launcher/%s/", local.Cstr() );
// 	
// 	if( ::FileExist( mPath ) == false )
// 	{
// 		MessageBox( 0, "Failed to access local path", PATCHER, MB_OK );
// 	}
// 	return true;
// }

bool cPatcherApp::LoadSkin()
{

	char local[ 1024 ];
	memset( local, 0, sizeof( local ) );
	::LoadString( AfxGetInstanceHandle(), IDS_UPDATE_LOCAL, local, sizeof(local) );

	/// 경로 설정
	mPath.Format( "Launcher/%s/", local );

	if( ::FileExist( mPath ) == false )
	{
		MessageBox( 0, "Failed to access local path", PATCHER, MB_OK );
	}

	/// 스킨 관리자 생성
	mSkinManager = new cSkinManager( mPath );

	/// 스킨 리소스 로딩
	return mSkinManager->Load( mPath + SKNINFO_FILENAME );
}
