#include "Mix/Private/Graphics/DX11/Manager.h"

#include "Mix/Graphics/IVertexShader.h"
#include "Mix/Graphics/IPixelShader.h"

#include "Mix/Private/Graphics/DX11/Device.h"

namespace Mix{ namespace Graphics{ namespace DX11{

////////////////////////////////////////////////////////////////////////////////////////////////////
// Manager : シェーダーモデル４
////////////////////////////////////////////////////////////////////////////////////////////////////

static const UInt8 VS_CANVAS_4[] = {
	#include "Mix/Private/Graphics/Utility/DX11/Shader/4/canvas.vs.inc"
};

static const UInt8 PS_CANVAS_COLOR_4[] = {
	#include "Mix/Private/Graphics/Utility/DX11/Shader/4/canvasColor.ps.inc"
};

static const UInt8 PS_CANVAS_COLOR_AND_TEXTURE_4[] = {
	#include "Mix/Private/Graphics/Utility/DX11/Shader/4/canvasColorAndTexture.ps.inc"
};

static const UInt8 VS_LINE_4[] =
{
	#include "Mix/Private/Graphics/Utility/DX11/Shader/4/line.vs.inc"
};

static const UInt8 PS_LINE_4[] =
{
	#include "Mix/Private/Graphics/Utility/DX11/Shader/4/line.ps.inc"
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// Manager : シェーダーモデル５
////////////////////////////////////////////////////////////////////////////////////////////////////

//キャンバスレンダラー - テクスチャ無し( VS )
static const UInt8 VS_CANVAS_5[] = {
	#include "Mix/Private/Graphics/Utility/DX11/Shader/5/canvas.vs.inc"
};

//キャンバスレンダラー - テクスチャ有り( PS )
static const UInt8 PS_CANVAS_COLOR_5[] = {
	#include "Mix/Private/Graphics/Utility/DX11/Shader/5/canvasColor.ps.inc"
};

//キャンバスレンダラー( PS )
static const UInt8 PS_CANVAS_COLOR_AND_TEXTURE_5[] = {
	#include "Mix/Private/Graphics/Utility/DX11/Shader/5/canvasColorAndTexture.ps.inc"
};

//ライン( VS )
static const UInt8 VS_LINE_5[] =
{
	#include "Mix/Private/Graphics/Utility/DX11/Shader/5/line.vs.inc"
};

//ライン( PS )
static const UInt8 PS_LINE_5[] =
{
	#include "Mix/Private/Graphics/Utility/DX11/Shader/5/line.ps.inc"
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// Manager
////////////////////////////////////////////////////////////////////////////////////////////////////

Manager* Manager::CreateInstance( void )
{
	return MIX_LIB_NEW_T( Mix::Memory::SECTION_GRAPHICS, Manager );
}

Manager::Manager( void ) :
m_pDevice( NULL )
{
}

Manager::~Manager( void )
{
}

Boolean Manager::OnInitialize(	const Mix::Point& targetSize,
								Mix::Graphics::SHADER_MODEL shaderModel, Boolean bFullscreen, Boolean bWaitVSync,
								Mix::UserFile* pSysReport )
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバイスを作成
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pDevice = Mix::Graphics::DX11::Device::CreateInstance( bWaitVSync );
	if( m_pDevice == NULL )
	{
		return False;
	}

	if( m_pDevice->Initialize( targetSize, shaderModel, bFullscreen, pSysReport ) == False )
	{
		return False;
	}

	return True;
}

void Manager::OnDispose( void )
{
	if( m_pDevice != NULL )
	{
		m_pDevice->Dispose();
		MIX_RELEASE( m_pDevice );
	}
}

void Manager::GetShaderBinary( Common::Manager::SHADER_TYPES type, Common::Manager::SHADER_BINARY& out )
{
	Mix::Graphics::SHADER_MODEL shaderModel = m_pDevice->GetShaderModel();

	if( shaderModel == Mix::Graphics::SHADER_MODEL_4 )
	{
		switch( type )
		{
		case Manager::SHADER_CANVAS_VS:
			::wcscpy_s( out.name, Manager::SHADER_BINARY::NAME_SIZE, L"CanvasRenderer(DX11_4)" );
			out.pData = &( VS_CANVAS_4[0] );
			out.dataSize = sizeof( VS_CANVAS_4 );
			break;
		case Manager::SHADER_CANVAS_COLOR_PS:
			::wcscpy_s( out.name, Manager::SHADER_BINARY::NAME_SIZE, L"CanvasRendererColor(DX11_4)" );
			out.pData = &( PS_CANVAS_COLOR_4[0] );
			out.dataSize = sizeof( PS_CANVAS_COLOR_4 );
			break;
		case Manager::SHADER_CANVAS_COLOR_AND_TEXTURE_PS:
			::wcscpy_s( out.name, Manager::SHADER_BINARY::NAME_SIZE, L"CanvasRendererColorAndTexture(DX11_4)" );
			out.pData = &( PS_CANVAS_COLOR_AND_TEXTURE_4[0] );
			out.dataSize = sizeof( PS_CANVAS_COLOR_AND_TEXTURE_4 );
			break;

		case Manager::SHADER_LINE_VS:
			::wcscpy_s( out.name, Manager::SHADER_BINARY::NAME_SIZE, L"Line(DX11_4)" );
			out.pData = &( VS_LINE_4[0] );
			out.dataSize = sizeof( VS_LINE_4 );
			break;
		case Manager::SHADER_LINE_PS:
			::wcscpy_s( out.name, Manager::SHADER_BINARY::NAME_SIZE, L"Line(DX11_4)" );
			out.pData = &( PS_LINE_4[0] );
			out.dataSize = sizeof( PS_LINE_4 );
			break;

		default:
			MIX_ERROR_W( L"指定された常駐シェーダーは存在しません(SM4)" );
		}
	}
	else if( shaderModel == Mix::Graphics::SHADER_MODEL_5 )
	{
		switch( type )
		{
		case Manager::SHADER_CANVAS_VS:
			::wcscpy_s( out.name, Manager::SHADER_BINARY::NAME_SIZE, L"CanvasRenderer(DX11_5)" );
			out.pData = &( VS_CANVAS_5[0] );
			out.dataSize = sizeof( VS_CANVAS_5 );
			break;
		case Manager::SHADER_CANVAS_COLOR_PS:
			::wcscpy_s( out.name, Manager::SHADER_BINARY::NAME_SIZE, L"CanvasRendererColor(DX11_5)" );
			out.pData = &( PS_CANVAS_COLOR_5[0] );
			out.dataSize = sizeof( PS_CANVAS_COLOR_5 );
			break;
		case Manager::SHADER_CANVAS_COLOR_AND_TEXTURE_PS:
			::wcscpy_s( out.name, Manager::SHADER_BINARY::NAME_SIZE, L"CanvasRendererColorAndTexture(DX11_5)" );
			out.pData = &( PS_CANVAS_COLOR_AND_TEXTURE_5[0] );
			out.dataSize = sizeof( PS_CANVAS_COLOR_AND_TEXTURE_5 );
			break;

		case Manager::SHADER_LINE_VS:
			::wcscpy_s( out.name, Manager::SHADER_BINARY::NAME_SIZE, L"Line(DX11_5)" );
			out.pData = &( VS_LINE_5[0] );
			out.dataSize = sizeof( VS_LINE_5 );
			break;
		case Manager::SHADER_LINE_PS:
			::wcscpy_s( out.name, Manager::SHADER_BINARY::NAME_SIZE, L"Line(DX11_5)" );
			out.pData = &( PS_LINE_5[0] );
			out.dataSize = sizeof( PS_LINE_5 );
			break;

		default:
			MIX_ERROR_W( L"指定された常駐シェーダーは存在しません(SM5)" );
		}
	}
	else
	{
		MIX_ERROR_W( L"指定されたシェーダーモデルの常駐シェーダーは存在しません(SM4 or SM5)" );
	}
}

Mix::Graphics::Common::Device* Manager::GetDevicePtr( void )
{
	return m_pDevice;
}

}}}
