#include "stdafx.h"
#include "devsystem.h"
#include "rendersystem.h"
#include "ResourceManager.h"
#include "AppTimer.h"

#include "CameraManager.h"
#include "SceneManager.h"
#include "Terrain.h"

cDevSystem* cDevSystem::mSingleton = 0;

cDevSystem::cDevSystem( NiRenderer* renderer )
: mFont( 0 )
, mRenderer( renderer )
, mInfoString0( 0 )
{
	assert( mSingleton == 0 && "bad singleton!" );
	mSingleton = this;

	mLastTime = 0;
	mFrames = 0;
	mFPS = 0;
}

cDevSystem::~cDevSystem()
{
	mSingleton = 0;
}

bool cDevSystem::Init()
{
	if( mRenderer == 0 )
	{
		NiMessageBox( "[DevSystem] 초기화 실패.", "Error!" );
		return false;
	}

	mFont = NiFont::Create( mRenderer, "MapData/CourierNew10.NFF" );

	if( mFont == 0 )
	{
		NiMessageBox( "[DevSystem] 기본 font를 생성하지 못했음.", "Error!" );
		return false;
	}

	mInfoString0 = NiNew NiOldString2D( mFont, NiFontString::COLORED, 5000, "", NiColorA::BLACK, 11, 11 );

	if( mInfoString0 == 0 )
	{
		NiMessageBox( "[DevSystem] Font입력에 사용할 Texture 생성 실패.", "Error!" );
		return false;
	}

	mInfoString1 = NiNew NiOldString2D( mFont, NiFontString::COLORED, 5000, "", NiColorA(0.7f, 0.7f, 1.0f, 1), 10, 10 );

	return true;
}

void cDevSystem::Process(float time)
{
	mFrames++;

	if( time - mLastTime > 1 )
	{
		mFPS = (float) (mFrames / (long double)(time - mLastTime));
		mLastTime = time;
		mFrames = 0;
	}

	UpdateDevInfo();
}

void cDevSystem::Render()
{
	mInfoString0->Draw( mRenderer );
	mInfoString1->Draw( mRenderer );
}

void cDevSystem::UpdateDevInfo()
{
	const cRenderOption* option = RENDERSYS->GetOption();

	char flag[512] = {0,};
	char devtype[256] = {0,};
	char fbformat[256] = {0,};
	char dsformat[256] = {0,};
	char interval[256] = {0,};
	char swapeffect[256] = {0,};
	char fbmode[256] = {0,};

	if( option->mFlags == 0)
		strcpy(flag ,"USE_NOFLAGS");
	else
	{
		if(option->mFlags & NiDX9Renderer::USE_MANUALDEPTHSTENCIL)
			strcat(flag, "[USE_MANUALDEPTHSTENCIL]");
		if(option->mFlags & NiDX9Renderer::USE_FULLSCREEN)
			strcat(flag, "[USE_FULLSCREEN]");
		if(option->mFlags & NiDX9Renderer::USE_STENCIL)
			strcat(flag, "[USE_STENCIL]");
		if(option->mFlags & NiDX9Renderer::USE_16BITBUFFERS)
			strcat(flag, "[USE_16BITBUFFERS]");
		if(option->mFlags & NiDX9Renderer::USE_MULTITHREADED)
			strcat(flag, "[USE_MULTITHREADED]");
		if(option->mFlags & NiDX9Renderer::USE_FPU_PRESERVE)
			strcat(flag, "[USE_FPU_PRESERVE]");
	}
	switch( option->mDeviceDesc )
	{
	case NiDX9Renderer::DEVDESC_PURE: strcat(devtype, "DEVDESC_PURE");break;
	case NiDX9Renderer::DEVDESC_HAL_HWVERTEX:strcat(devtype, "DEVDESC_HAL_HWVERTEX");break;
	case NiDX9Renderer::DEVDESC_HAL_MIXEDVERTEX:strcat(devtype, "DEVDESC_HAL_MIXEDVERTEX");break;
	case NiDX9Renderer::DEVDESC_HAL_SWVERTEX:strcat(devtype, "DEVDESC_HAL_SWVERTEX");break;
	case NiDX9Renderer::DEVDESC_REF:strcat(devtype, "DEVDESC_REF");break;
	case NiDX9Renderer::DEVDESC_REF_HWVERTEX:strcat(devtype, "DEVDESC_REF_HWVERTEX");break;
	case NiDX9Renderer::DEVDESC_REF_MIXEDVERTEX:strcat(devtype, "DEVDESC_REF_MIXEDVERTEX");break;
	}
	switch( option->mFrameBufferFormat )
	{
	case NiDX9Renderer::FBFMT_UNKNOWN:strcat(fbformat, "FBFMT_UNKNOWN");break;
	case NiDX9Renderer::FBFMT_R8G8B8:strcat(fbformat, "FBFMT_R8G8B8");break;
	case NiDX9Renderer::FBFMT_A8R8G8B8:strcat(fbformat, "FBFMT_A8R8G8B8");break;
	case NiDX9Renderer::FBFMT_X8R8G8B8:strcat(fbformat, "FBFMT_X8R8G8B8");break;
	case NiDX9Renderer::FBFMT_R5G6B5:strcat(fbformat, "FBFMT_R5G6B5");break;
	case NiDX9Renderer::FBFMT_X1R5G5B5:strcat(fbformat, "FBFMT_X1R5G5B5");break;
	case NiDX9Renderer::FBFMT_A1R5G5B5:strcat(fbformat, "FBFMT_A1R5G5B5");break;
	case NiDX9Renderer::FBFMT_A4R4G4B4:strcat(fbformat, "FBFMT_A4R4G4B4");break;
	case NiDX9Renderer::FBFMT_R3G3B2:strcat(fbformat, "FBFMT_R3G3B2");break;
	case NiDX9Renderer::FBFMT_A8:strcat(fbformat, "FBFMT_A8");break;
	case NiDX9Renderer::FBFMT_A8R3G3B2:strcat(fbformat, "FBFMT_A8R3G3B2");break;
	case NiDX9Renderer::FBFMT_X4R4G4B4:strcat(fbformat, "FBFMT_X4R4G4B4");break;
	case NiDX9Renderer::FBFMT_R16F:strcat(fbformat, "FBFMT_R16F");break;
	case NiDX9Renderer::FBFMT_G16R16F:strcat(fbformat, "FBFMT_G16R16F");break;
	case NiDX9Renderer::FBFMT_A16B16G16R16F:strcat(fbformat, "FBFMT_A16B16G16R16F");break;
	case NiDX9Renderer::FBFMT_R32F:strcat(fbformat, "FBFMT_R32F");break;
	case NiDX9Renderer::FBFMT_G32R32F:strcat(fbformat, "FBFMT_G32R32F");break;
	case NiDX9Renderer::FBFMT_A32B32G32R32F:strcat(fbformat, "FBFMT_A32B32G32R32F");break;
	}
	switch( option->mDepthStencilFormat )
	{
	case NiDX9Renderer::DSFMT_UNKNOWN:strcat(dsformat, "DSFMT_UNKNOWN");break;
	case NiDX9Renderer::DSFMT_D16_LOCKABLE:strcat(dsformat, "DSFMT_D16_LOCKABLE");break;
	case NiDX9Renderer::DSFMT_D32:strcat(dsformat, "DSFMT_D32");break;
	case NiDX9Renderer::DSFMT_D15S1:strcat(dsformat, "DSFMT_D15S1");break;
	case NiDX9Renderer::DSFMT_D24S8:strcat(dsformat, "DSFMT_D24S8");break;
	case NiDX9Renderer::DSFMT_D16:strcat(dsformat, "DSFMT_D16");break;
	case NiDX9Renderer::DSFMT_D24X8:strcat(dsformat, "DSFMT_D24X8");break;
	case NiDX9Renderer::DSFMT_D24X4S4:strcat(dsformat, "DSFMT_D24X4S4");break;
	}
	switch( option->mPresentationInterval )
	{
	case NiDX9Renderer::PRESENT_INTERVAL_IMMEDIATE:strcat(interval, "PRESENT_INTERVAL_IMMEDIATE");break;
	case NiDX9Renderer::PRESENT_INTERVAL_ONE:strcat(interval, "PRESENT_INTERVAL_ONE");break;
	case NiDX9Renderer::PRESENT_INTERVAL_TWO:strcat(interval, "PRESENT_INTERVAL_TWO");break;
	case NiDX9Renderer::PRESENT_INTERVAL_THREE:strcat(interval, "PRESENT_INTERVAL_THREE");break;
	case NiDX9Renderer::PRESENT_INTERVAL_FOUR:strcat(interval, "PRESENT_INTERVAL_FOUR");break;
	}
	switch( option->mSwapEffect )
	{
	case NiDX9Renderer::SWAPEFFECT_DEFAULT:strcat(swapeffect, "SWAPEFFECT_DEFAULT");break;
	case NiDX9Renderer::SWAPEFFECT_DISCARD:strcat(swapeffect, "SWAPEFFECT_DISCARD");break;
	case NiDX9Renderer::SWAPEFFECT_FLIP:strcat(swapeffect, "SWAPEFFECT_FLIP");break;
	case NiDX9Renderer::SWAPEFFECT_COPY:strcat(swapeffect, "SWAPEFFECT_COPY");break;
	}
	switch( option->mFrameBufferMode )
	{
	case NiDX9Renderer::FBMODE_DEFAULT:strcat(fbmode, "FBMODE_DEFAULT");break;
	case NiDX9Renderer::FBMODE_LOCKABLE:strcat(fbmode, "FBMODE_LOCKABLE");break;
	case NiDX9Renderer::FBMODE_MULTISAMPLES_2:strcat(fbmode, "FBMODE_MULTISAMPLES_2");break;
	case NiDX9Renderer::FBMODE_MULTISAMPLES_3:strcat(fbmode, "FBMODE_MULTISAMPLES_3");break;
	case NiDX9Renderer::FBMODE_MULTISAMPLES_4:strcat(fbmode, "FBMODE_MULTISAMPLES_4");break;
	case NiDX9Renderer::FBMODE_MULTISAMPLES_5:strcat(fbmode, "FBMODE_MULTISAMPLES_5");break;
	case NiDX9Renderer::FBMODE_MULTISAMPLES_6:strcat(fbmode, "FBMODE_MULTISAMPLES_6");break;
	case NiDX9Renderer::FBMODE_MULTISAMPLES_7:strcat(fbmode, "FBMODE_MULTISAMPLES_7");break;
	case NiDX9Renderer::FBMODE_MULTISAMPLES_8:strcat(fbmode, "FBMODE_MULTISAMPLES_8");break;
	case NiDX9Renderer::FBMODE_MULTISAMPLES_9:strcat(fbmode, "FBMODE_MULTISAMPLES_9");break;
	case NiDX9Renderer::FBMODE_MULTISAMPLES_10:strcat(fbmode, "FBMODE_MULTISAMPLES_10");break;
	case NiDX9Renderer::FBMODE_MULTISAMPLES_11:strcat(fbmode, "FBMODE_MULTISAMPLES_11");break;
	case NiDX9Renderer::FBMODE_MULTISAMPLES_12:strcat(fbmode, "FBMODE_MULTISAMPLES_12");break;
	case NiDX9Renderer::FBMODE_MULTISAMPLES_13:strcat(fbmode, "FBMODE_MULTISAMPLES_13");break;
	case NiDX9Renderer::FBMODE_MULTISAMPLES_14:strcat(fbmode, "FBMODE_MULTISAMPLES_14");break;
	case NiDX9Renderer::FBMODE_MULTISAMPLES_15:strcat(fbmode, "FBMODE_MULTISAMPLES_15");break;
	case NiDX9Renderer::FBMODE_MULTISAMPLES_16:strcat(fbmode, "FBMODE_MULTISAMPLES_16");break;
	case NiDX9Renderer::FBMODE_MULTISAMPLES_NONMASKABLE:strcat(fbmode, "FBMODE_MULTISAMPLES_NONMASKABLE");break;
	}

	///
	unsigned int numVisibleSolidNodes = SCENEMAN->GetNumVisibleSolidNodes();
	unsigned int numVisibleAlphaNodes = SCENEMAN->GetNumVisibleAlphaNodes();
	unsigned int numVisibleTerrainNodes = TERRAIN->GetNumVisibleNodes();

	mInfoString0->sprintf(
		"FPS: %3.2f\n"
		"Solid Geometries: %d\n"
		"Alpha Geometries: %d\n"
		"Terrain Geometries: %d",
		mFPS,
		numVisibleSolidNodes,
		numVisibleAlphaNodes,
		numVisibleTerrainNodes);

	mInfoString1->sprintf(
		"FPS: %3.2f\n"
		"Solid Geometries: %d\n"
		"Alpha Geometries: %d\n"
		"Terrain Geometries: %d",
		mFPS,
		numVisibleSolidNodes,
		numVisibleAlphaNodes,
		numVisibleTerrainNodes);
}
