//------------------------------------------------------------------------------
// Lamp : Open source game middleware
// Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//------------------------------------------------------------------------------

/** @file
 * 実装
 * @author Junpee
 */

#include "LampBasic.h"
#include "Graphics/DeviceSelector/GraphicsDeviceSelector.h"
#include "Graphics/System/GraphicsDeviceSettings.h"
#include "Graphics/Enumeration/GraphicsDeviceEnumeration.h"

namespace Lamp{

//------------------------------------------------------------------------------
// デバイス設定の選択
bool GraphicsDeviceSelector::chooseDeviceSettings(
	HWND windowHandle, bool startFullscreen){
	GraphicsDeviceSettings* settings = GraphicsDeviceSettings::getInstance();
	bool foundWindowed = findBestWindowedMode(windowHandle, false, false);
	bool foundFullscreen = findBestFullscreenMode(windowHandle, false, false);
	// デフォルトはウィンドウモード
	settings->setWindowed(true);
	// フルスクリーンを要求されればフルスクリーン
	if(startFullscreen && foundFullscreen){ settings->setWindowed(false); }
	// フルスクリーンしか見つからなければフルスクリーン
	if((!foundWindowed) && foundFullscreen){ settings->setWindowed(false); }
	// 両方見つからなければ失敗
	if((!foundWindowed) && (!foundFullscreen)){ return false; }
	return true;
}
//------------------------------------------------------------------------------
// ウインドウモード設定の構築
void GraphicsDeviceSelector::buildWindowModeSettings(
	HWND windowHandle, const D3DDISPLAYMODE& displayMode,
	GraphicsAdapterInformation* bestAdapter,
	GraphicsDeviceInformation* bestDevice,
	GraphicsDeviceComboInformation* bestDeviceCombo){
	// 設定にコピーする
	GraphicsDeviceEnumeration* enumeration =
		GraphicsDeviceEnumeration::getInstance();
	GraphicsDeviceSettings* settings = GraphicsDeviceSettings::getInstance();
	settings->setWindowed(true);
	settings->setAdapterInformation(bestAdapter);
	settings->setDeviceInformation(bestDevice);
	settings->setDeviceComboInformation(bestDeviceCombo);
	settings->setDisplayMode(displayMode);
	if(enumeration->getUsesDepthStencilBuffer()){
		// 列挙で制限していなければ、主にD3DFMT_D16が使用される。
		settings->setDepthStencilFormat(
			bestDeviceCombo->getDepthStencilFormat(0));
	}
	// マルチサンプルモードはD3DMULTISAMPLE_NONEがデフォルト
	settings->setMultiSampleType(bestDeviceCombo->getMultiSampleType(0));
	settings->setMultiSampleQuality(0);
	// Pure Hardware Mixed Softwareの順で使用できるものが使用される。
	settings->setVertexProcessingType(
		bestDeviceCombo->getVertexProcessingType(0));
	// プレゼンテーション間隔はD3DPRESENT_INTERVAL_IMMEDIATEがデフォルト
	settings->setPresentationInterval(
		bestDeviceCombo->getPresentationInterval(0));
	// ウィンドウサイズ設定
	RECT windowRect;
	::GetClientRect(windowHandle, &windowRect);
	DimensionI windowSize(windowRect.right - windowRect.left,
		windowRect.bottom - windowRect.top);
	settings->setWindowSize(windowSize);

DebugOut("BestWindow %s %s\n%s\n",
	bestAdapter->toString().getBytes(),
	bestDevice->toString().getBytes(),
	bestDeviceCombo->toString().getBytes());
DebugOut("( %d x %d ) %dHz window (%d x %d)\n\n",
	displayMode.Width, displayMode.Height,
	displayMode.RefreshRate, windowSize.width, windowSize.height);

}
//------------------------------------------------------------------------------
// フルスクリーンモード設定の構築
void GraphicsDeviceSelector::buildFullscreenModeSettings(
	const D3DDISPLAYMODE& displayMode,
	GraphicsAdapterInformation* bestAdapter,
	GraphicsDeviceInformation* bestDevice,
	GraphicsDeviceComboInformation* bestDeviceCombo){
	// 設定にコピーする
	GraphicsDeviceEnumeration* enumeration =
		GraphicsDeviceEnumeration::getInstance();
	GraphicsDeviceSettings* settings = GraphicsDeviceSettings::getInstance();
	settings->setWindowed(false);
	settings->setAdapterInformation(bestAdapter);
	settings->setDeviceInformation(bestDevice);
	settings->setDeviceComboInformation(bestDeviceCombo);
	settings->setDisplayMode(displayMode);
	if(enumeration->getUsesDepthStencilBuffer()){
		// 列挙で制限していなければ、主にD3DFMT_D16が使用される。
		settings->setDepthStencilFormat(
			bestDeviceCombo->getDepthStencilFormat(0));
	}
	// マルチサンプルモードはD3DMULTISAMPLE_NONEがデフォルト
	settings->setMultiSampleType(bestDeviceCombo->getMultiSampleType(0));
	settings->setMultiSampleQuality(0);
	// Pure Hardware Mixed Softwareの順で使用できるものが使用される。
	settings->setVertexProcessingType(
		bestDeviceCombo->getVertexProcessingType(0));
	// プレゼンテーション間隔はD3DPRESENT_INTERVAL_IMMEDIATEがデフォルト
	settings->setPresentationInterval(
		bestDeviceCombo->getPresentationInterval(0));

DebugOut("BestFullscreen %s %s\n%s\n",
	bestAdapter->toString().getBytes(),
	bestDevice->toString().getBytes(),
	bestDeviceCombo->toString().getBytes());
DebugOut("( %d x %d ) %dHz\n\n",
	displayMode.Width, displayMode.Height,
	displayMode.RefreshRate);
}
//------------------------------------------------------------------------------
} // End of namespace Lamp
//------------------------------------------------------------------------------
