#include "stdafx.h"
#include "resource.h"

////////////////////////////////////////////////////////////////////////////////////////////////////
// Src テーブル
////////////////////////////////////////////////////////////////////////////////////////////////////

static const unsigned char* SRC_TABLE[] =
{
	PRJ_BASEMENT,
	PRJ_BONEFIRE_LAND,
	PRJ_BONEFIRE_WOODPILE,
	PRJ_BOX,
	PRJ_FLOOR,
	PRJ_HALL,
	PRJ_HILL,
	PRJ_HUMAN,
	PRJ_MOUNTAINS,
	PRJ_PARTICLE,
	PRJ_POOL,
	PRJ_PRIVACY_CHAIR,
	PRJ_PRIVACY_LIGHT,
	PRJ_PRIVACY_ROOM,
	PRJ_PRIVACY_TABLE,
	PRJ_SPHERE,
	PRJ_WAREHOUSE_BOX_M,
	PRJ_WAREHOUSE_BOX_S,
	PRJ_WAREHOUSE_ROOM,
	PRJ_BLOCKS,
	PRJ_CAVE,
	PRJ_CONTINENT,
	PRJ_PLANTER,
	PRJ_SUZANNE,
	PRJ_TEST,
	PRJ_CIRCUIT_LAND,
	PRJ_CIRCUIT_BALL,
	PRJ_SAMPLE_PDD,
};

static const size_t SRC_NUM = sizeof( SRC_TABLE ) / sizeof( char* );

static const size_t SRC_SIZE_TABLE[SRC_NUM] =
{
	sizeof( PRJ_BASEMENT ),
	sizeof( PRJ_BONEFIRE_LAND ),
	sizeof( PRJ_BONEFIRE_WOODPILE ),
	sizeof( PRJ_BOX ),
	sizeof( PRJ_FLOOR ),
	sizeof( PRJ_HALL ),
	sizeof( PRJ_HILL ),
	sizeof( PRJ_HUMAN ),
	sizeof( PRJ_MOUNTAINS ),
	sizeof( PRJ_PARTICLE ),
	sizeof( PRJ_POOL ),
	sizeof( PRJ_PRIVACY_CHAIR ),
	sizeof( PRJ_PRIVACY_LIGHT ),
	sizeof( PRJ_PRIVACY_ROOM ),
	sizeof( PRJ_PRIVACY_TABLE ),
	sizeof( PRJ_SPHERE ),
	sizeof( PRJ_WAREHOUSE_BOX_M ),
	sizeof( PRJ_WAREHOUSE_BOX_S ),
	sizeof( PRJ_WAREHOUSE_ROOM ),
	sizeof( PRJ_BLOCKS ),
	sizeof( PRJ_CAVE ),
	sizeof( PRJ_CONTINENT ),
	sizeof( PRJ_PLANTER ),
	sizeof( PRJ_SUZANNE ),
	sizeof( PRJ_TEST ),
	sizeof( PRJ_CIRCUIT_LAND ),
	sizeof( PRJ_CIRCUIT_BALL ),
	sizeof( PRJ_SAMPLE_PDD ),
};

static const char* SRC_PATH = "g:\\project\\mix"; //必ず小文字にすること
static const size_t SRC_PATH_SIZE = strlen( SRC_PATH );

////////////////////////////////////////////////////////////////////////////////////////////////////
// Dst テーブル
////////////////////////////////////////////////////////////////////////////////////////////////////

static const char* DST_FILEPATH_TABLE[SRC_NUM] =
{
	"Engine\\Build\\Examples\\Resources\\basement\\project\\project.prj",
	"Engine\\Build\\Examples\\Resources\\bonfire\\project_land\\project_land.prj",
	"Engine\\Build\\Examples\\Resources\\bonfire\\project_woodPile\\project_woodPile.prj",
	"Engine\\Build\\Examples\\Resources\\box\\project\\project.prj",
	"Engine\\Build\\Examples\\Resources\\floor\\project\\project.prj",
	"Engine\\Build\\Examples\\Resources\\hall\\project\\project.prj",
	"Engine\\Build\\Examples\\Resources\\hill\\project\\project.prj",
	"Engine\\Build\\Examples\\Resources\\human\\project\\project.prj",
	"Engine\\Build\\Examples\\Resources\\mountains\\project\\project.prj",
	"Engine\\Build\\Examples\\Resources\\particle\\project\\project.prj",
	"Engine\\Build\\Examples\\Resources\\pool\\project\\project.prj",
	"Engine\\Build\\Examples\\Resources\\privacy\\project_chair\\project_chair.prj",
	"Engine\\Build\\Examples\\Resources\\privacy\\project_light\\project_light.prj",
	"Engine\\Build\\Examples\\Resources\\privacy\\project_room\\project_room.prj",
	"Engine\\Build\\Examples\\Resources\\privacy\\project_table\\project_table.prj",
	"Engine\\Build\\Examples\\Resources\\sphere\\project\\project.prj",
	"Engine\\Build\\Examples\\Resources\\warehouse\\project_box_m\\project_box_m.prj",
	"Engine\\Build\\Examples\\Resources\\warehouse\\project_box_s\\project_box_s.prj",
	"Engine\\Build\\Examples\\Resources\\warehouse\\project_room\\project_room.prj",
	"Engine\\Build\\Examples\\Resources\\blocks\\project\\project.prj",
	"Engine\\Build\\Examples\\Resources\\cave\\project\\project.prj",
	"Engine\\Build\\Examples\\Resources\\continent\\project\\project.prj",
	"Engine\\Build\\Examples\\Resources\\planter\\project\\project.prj",
	"Engine\\Build\\Examples\\Resources\\suzanne\\project\\project.prj",
	"Engine\\Build\\Examples\\Resources\\test\\project\\project.prj",
	"Engine\\Build\\Examples\\Resources\\circuit\\project\\project.prj",
	"Engine\\Build\\Examples\\Resources\\circuit\\project_ball\\project_ball.prj",
	"Engine\\Build\\Examples\\Resources\\sample.pdd",
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// サブ
////////////////////////////////////////////////////////////////////////////////////////////////////

bool Replace( const unsigned char* pSrc, size_t srcSize, const char* pNewPath, size_t newPathSize, HANDLE hDst )
{
	size_t pathSize = strlen( SRC_PATH );

	if( srcSize >= pathSize )
	{
		const char* pComp = reinterpret_cast<const char*>( &( pSrc[0] ) );
		const char* pCompEnd = pComp + ( srcSize - pathSize );

		const char* pWrite = pComp;
		size_t writeCount = 0;
		size_t writeTotal = 0;

		while( pComp != pCompEnd )
		{
			bool bFind = true;

			for( size_t i = 0; ( SRC_PATH[i] != '\0' ) && ( bFind == true ); i++ )
			{
				if( ::tolower( pComp[i] ) != SRC_PATH[i] )
				{
					bFind = false;
				}
			}

			if( bFind == true )
			{
				DWORD writeSize;

				if( writeCount > 0 )
				{
					writeSize = 0;
					if( ::WriteFile( hDst, pWrite, writeCount, &writeSize, NULL ) == FALSE )
					{
						return false;
					}

					writeTotal += writeCount;
					writeCount = 0;
				}

				writeSize = 0;
				if( ::WriteFile( hDst, pNewPath, newPathSize, &writeSize, NULL ) == FALSE )
				{
					return false;
				}

				pComp += pathSize;
				writeTotal += SRC_PATH_SIZE;
				pWrite = pComp;
			}
			else
			{
				writeCount++;
				pComp++;
			}
		}

		if( writeTotal < srcSize )
		{
			DWORD writeSize = 0;

			if( ::WriteFile( hDst, &pSrc[writeTotal], ( srcSize - writeTotal ), &writeSize, NULL ) == FALSE )
			{
				return false;
			}
		}
	}

	return true;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// メイン
////////////////////////////////////////////////////////////////////////////////////////////////////

int _tmain( int argc, _TCHAR* argv[] )
{
	if( ( argc < 2 ) ||
		( argc > 3 ) )
	{
		return -1;
	}

	char relPath[4096] = { 0 };
	bool bRollback = false;

	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( int i = 1; i < argc; i++ )
	{
		if( ::strcmp( argv[i], "-b" ) == 0 )
		{
			bRollback = true;
		}
		else
		{
			::strcpy_s( relPath, sizeof( relPath ), argv[i] );
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	char curDir[4096] = { 0 };
	char newPath[4096] = { 0 };
	size_t newPathSize = 0;

	if( ::GetCurrentDirectoryA( sizeof( curDir ), curDir ) == 0 )
	{
		return -2;
	}

	if( ::PathCombine( newPath, curDir, relPath ) != NULL )
	{
		size_t lastIndex = strlen( newPath ) - 1;

		if( newPath[lastIndex] == '\\' )
		{
			newPath[lastIndex] = '\0';
		}

		newPath[0] = ::toupper( newPath[0] );

		newPathSize = strlen( newPath );
	}
	else
	{
		return -3;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	printf( "----------------------------------------------------------------------\n" );

	if( bRollback == true )
	{
		printf( "サンプルをロールバックします\n" );
		printf( "\n" );

		for( size_t i = 0; i < SRC_NUM; i++ )
		{
			char filePath[4096] = { 0 };

			if( ::PathCombine( filePath, newPath, DST_FILEPATH_TABLE[i] ) != NULL )
			{
				printf( "\"%s\"...", filePath );

				HANDLE hFile = ::CreateFile( filePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
				if( hFile != INVALID_HANDLE_VALUE )
				{
					DWORD writeSize = 0;

					if( ::WriteFile( hFile, SRC_TABLE[i], SRC_SIZE_TABLE[i], &writeSize, NULL ) == FALSE )
					{
						printf( "ファイルの書き込みに失敗！\n" );
					}

					printf( "成功\n" );
				}

				::CloseHandle( hFile );
			}
			else
			{
				printf( "\"%s\"...パスの変換に失敗！\n", DST_FILEPATH_TABLE[i] );
			}
		}
	}
	else
	{
		printf( "サンプルを修正します\n" );
		printf( "\n" );

		for( size_t i = 0; i < SRC_NUM; i++ )
		{
			char filePath[4096] = { 0 };

			if( ::PathCombine( filePath, newPath, DST_FILEPATH_TABLE[i] ) != NULL )
			{
				printf( "\"%s\"...", filePath );

				HANDLE hFile = ::CreateFile( filePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
				if( hFile != INVALID_HANDLE_VALUE )
				{
					if( Replace( SRC_TABLE[i], SRC_SIZE_TABLE[i], newPath, newPathSize, hFile ) == true )
					{
						printf( "成功\n" );
					}
					else
					{
						printf( "ファイルの書き込みに失敗！\n" );
					}

					::CloseHandle( hFile );
				}
				else
				{
					printf( "ファイルの作成に失敗！\n" );
				}
			}
			else
			{
				printf( "\"%s\"...パスの変換に失敗！\n", DST_FILEPATH_TABLE[i] );
			}
		}
	}

	printf( "----------------------------------------------------------------------\n" );

	////////////////////////////////////////////////////////////////////////////////////////////////////

#ifdef _DEBUG
	::system( "pause" );
#endif //_DEBUG

	return 0;
}

