//------------------------------------------------------------------------------
// 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
 */

#ifndef GRAPHICS_DEVICE_ENUMERATION_H_
#define GRAPHICS_DEVICE_ENUMERATION_H_

#include <Core/Container/ArrayList.h>
#include <Graphics/Enumeration/ConfirmGraphicsDevice.h>
#include <Graphics/Enumeration/GraphicsDeviceComboInformation.h>
#include <Graphics/Enumeration/GraphicsDeviceInformation.h>
#include <Graphics/Enumeration/GraphicsAdapterInformation.h>

namespace Lamp{

//------------------------------------------------------------------------------
/**
 * グラフィックスデバイス列挙
 */
class GraphicsDeviceEnumeration : public ConfirmGraphicsDevice{
friend class LampGraphics;
public:
	//--------------------------------------------------------------------------
	/**
	 * インスタンス取得
	 * @return インスタンス
	 */
	static GraphicsDeviceEnumeration* getInstance(){
		Assert(instance_ != NULL);
		return instance_;
	}

	//--------------------------------------------------------------------------
	// 列挙用パラメータ
	//--------------------------------------------------------------------------
	/**
	 * 許可するフォーマットの追加
	 * @param allowedFormat 許可するフォーマット
	 */
	virtual void addAllowedFormat(D3DFORMAT allowedFormat){
		allowedFormats_.add(allowedFormat);
	}

	/**
	 * 許可するフォーマットの削除
	 * @param allowedFormat 許可するフォーマット
	 */
	virtual void removeAllowedFormat(D3DFORMAT allowedFormat){
		allowedFormats_.removeByValue(allowedFormat);
	}

	/**
	 * 許可するフォーマット数の取得
	 * @return 許可するフォーマット数
	 */
	virtual int getAllowedFormatCount() const{
		return allowedFormats_.getCount();
	}

	/**
	 * 許可するフォーマットの取得
	 * @return 許可するフォーマット
	 */
	virtual D3DFORMAT getAllowedFormat(int index){
		return allowedFormats_.get(index);
	}

	//--------------------------------------------------------------------------
	/**
	 * グラフィックスデバイス確認インターフェースの設定
	 * @param confirm グラフィックスデバイス確認インターフェース
	 */
	virtual void setConfirmGraphicsDevice(ConfirmGraphicsDevice* confirm){
		Assert(confirm != NULL);
		confirmGraphicsDevice_ = confirm;
	}

	/**
	 * グラフィックスデバイス確認インターフェースの取得
	 * @return グラフィックスデバイス確認インターフェース
	 */
	virtual ConfirmGraphicsDevice* getConfirmGraphicsDevice() const{
		return confirmGraphicsDevice_;
	}

	/**
	 * グラフィックスデバイスの確認
	 * @param deviceCapability デバイス能力
	 * @param vertexProcessingType 頂点プロセスタイプ
	 * @param adapterFormat アダプタのフォーマット
	 * @param backBufferFormat バックバッファのフォーマット
	 * @return デバイスの使用を許可するならばtrueを返す。
	 */
	virtual bool confirmGraphicsDevice(
		const D3DCapacity& deviceCapability, u_int vertexProcessingType,
		D3DFORMAT adapterFormat, D3DFORMAT backBufferFormat){ return true; }

	//--------------------------------------------------------------------------
	/**
	 * 最小フルスクリーン幅の設定
	 * @param width 最小フルスクリーン幅
	 */
	virtual void setMinimumFullscreenWidth(u_int width){
		minimumFullscreenWidth_ = width;
	}

	/**
	 * 最小フルスクリーン幅の取得
	 * @return 最小フルスクリーン幅
	 */
	virtual u_int getMinimumFullscreenWidth() const{
		return minimumFullscreenWidth_;
	}

	//--------------------------------------------------------------------------
	/**
	 * 最小フルスクリーン高さの設定
	 * @param height 最小フルスクリーン高さ
	 */
	virtual void setMinimumFullscreenHeight(u_int height){
		minimumFullscreenHeight_ = height;
	}

	/**
	 * 最小フルスクリーン高さの取得
	 * @return 最小フルスクリーン高さ
	 */
	virtual u_int getMinimumFullscreenHeight() const{
		return minimumFullscreenHeight_;
	}

	//--------------------------------------------------------------------------
	/**
	 * 最小アダプタカラーチャンネルビットの設定
	 * @param bits 最小アダプタカラーチャンネルビット
	 */
	virtual void setMinimumAdapterColorChannelBits(u_int bits){
		minimumAdapterColorChannelBits_ = bits;
	}

	/**
	 * 最小アダプタカラーチャンネルビットの取得
	 * @return 最小アダプタカラーチャンネルビット
	 */
	virtual u_int getMinimumAdapterColorChannelBits() const{
		return minimumAdapterColorChannelBits_;
	}

	//--------------------------------------------------------------------------
	/**
	 * 最小バックバッファアルファチャンネルビットの設定
	 * @param bits 最小バックバッファアルファチャンネルビット
	 */
	virtual void setMinimumBackBufferAlphaChannelBits(u_int bits){
		minimumBackBufferAlphaChannelBits_ = bits;
	}

	/**
	 * 最小バックバッファアルファチャンネルビットの取得
	 * @return 最小バックバッファアルファチャンネルビット
	 */
	virtual u_int getMinimumBackBufferAlphaChannelBits() const{
		return minimumBackBufferAlphaChannelBits_;
	}

	//--------------------------------------------------------------------------
	/**
	 * 最小深度ビットの設定
	 * @param bits 最小深度ビット
	 */
	virtual void setMinimumDepthBits(u_int bits){
		minimumDepthBits_ = bits;
	}

	/**
	 * 最小深度ビットの取得
	 * @return 最小深度ビット
	 */
	virtual u_int getMinimumDepthBits() const{
		return minimumDepthBits_;
	}

	//--------------------------------------------------------------------------
	/**
	 * 最小ステンシルビットの設定
	 * @param bits 最小ステンシルビット
	 */
	virtual void setMinimumStencilBits(u_int bits){
		minimumStencilBits_ = bits;
	}

	/**
	 * 最小ステンシルビットの取得
	 * @return 最小ステンシルビット
	 */
	virtual u_int getMinimumStencilBits() const{
		return minimumStencilBits_;
	}

	//--------------------------------------------------------------------------
	/**
	 * ウィンドウモードが必要かどうかの設定
	 * @param requires ウィンドウモードが必要ならtrue
	 */
	virtual void setRequiresWindowMode(bool requires){
		requiresWindowMode_ = requires;
	}

	/**
	 * ウィンドウモードが必要かどうかの取得
	 * @return ウィンドウモードが必要ならtrue
	 */
	virtual bool getRequiresWindowMode() const{
		return requiresWindowMode_;
	}

	//--------------------------------------------------------------------------
	/**
	 * フルスクリーンモードが必要かどうかの設定
	 * @param requires フルスクリーンモードが必要ならtrue
	 */
	virtual void setRequiresFullscreenMode(bool requires){
		requiresFullscreenMode_ = requires;
	}

	/**
	 * フルスクリーンモードが必要かどうかの取得
	 * @return フルスクリーンモードが必要ならtrue
	 */
	virtual bool getRequiresFullscreenMode() const{
		return requiresFullscreenMode_;
	}

	//--------------------------------------------------------------------------
	/**
	 * 深度、ステンシルバッファを使用するかの設定
	 * @param uses 深度、ステンシルバッファを使用するならtrue
	 */
	virtual void setUsesDepthStencilBuffer(bool uses){
		usesDepthStencilBuffer_ = uses;
	}

	/**
	 * 深度、ステンシルバッファを使用するかの取得
	 * @return 深度、ステンシルバッファを使用するならtrue
	 */
	virtual bool getUsesDepthStencilBuffer() const{
		return usesDepthStencilBuffer_;
	}

	//--------------------------------------------------------------------------
	/**
	 * 混合頂点演算を使用するかの設定
	 * @param uses 混合頂点演算を使用するならtrue
	 */
	virtual void setUsesMixedVertexProcessing(bool uses){
		usesMixedVertexProcessing_ = uses;
	}

	/**
	 * 混合頂点演算を使用するかの取得
	 * @return 混合頂点演算を使用するならtrue
	 */
	virtual bool getUsesMixedVertexProcessing() const{
		return usesMixedVertexProcessing_;
	}

	//--------------------------------------------------------------------------
	// 列挙の結果取得
	//--------------------------------------------------------------------------
	/**
	 * アダプタ数の取得
	 * @return アダプタ数
	 */
	virtual int getAdapterCount(){ return adapters_.getCount(); }

	/**
	 * アダプタの取得
	 * @param index アダプタのインデクス
	 * @return アダプタ
	 */
	virtual GraphicsAdapterInformation* getAdapter(int index){
		return adapters_.get(index);
	}

	//--------------------------------------------------------------------------
protected:
	/**
	 * コンストラクタ
	 */
	GraphicsDeviceEnumeration();

	/**
	 * デストラクタ
	 */
	virtual ~GraphicsDeviceEnumeration();

	//--------------------------------------------------------------------------
	/**
	 * 列挙
	 * @return 使用できるデバイスが存在すればtrue
	 */
	virtual bool enumerate();

private:
	// コピーコンストラクタの隠蔽
	GraphicsDeviceEnumeration(const GraphicsDeviceEnumeration& copy);

	// 代入コピーの隠蔽
	void operator =(const GraphicsDeviceEnumeration& copy);

	//--------------------------------------------------------------------------
	// 列挙用パラメータ
	//--------------------------------------------------------------------------
	// 許可するフォーマット
	ArrayList<D3DFORMAT> allowedFormats_;
	// グラフィックスデバイス確認
	ConfirmGraphicsDevice* confirmGraphicsDevice_;
	// 最小フルスクリーン幅
	u_int minimumFullscreenWidth_;
	// 最小フルスクリーン高さ
	u_int minimumFullscreenHeight_;
	// 最小アダプタカラーチャンネルビット
	u_int minimumAdapterColorChannelBits_;
	// 最小バックバッファアルファチャンネルビット
	u_int minimumBackBufferAlphaChannelBits_;
	// 最小深度ビット
	u_int minimumDepthBits_;
	// 最小ステンシルビット
	u_int minimumStencilBits_;
	// ウィンドウモードが必要か
	bool requiresWindowMode_;
	// フルスクリーンモードが必要か
	bool requiresFullscreenMode_;
	// 深度、ステンシルバッファを使用するか
	bool usesDepthStencilBuffer_;
	// 混合頂点演算を使用するか
	bool usesMixedVertexProcessing_;

	// アダプタ
	ArrayList<GraphicsAdapterInformation*> adapters_;
	// 列挙済みかどうか
	bool enumerated_;

	// インスタンス
	static GraphicsDeviceEnumeration* instance_;

};

//------------------------------------------------------------------------------
} // End of namespace Lamp
#endif // End of GRAPHICS_DEVICE_ENUMERATION_H_
//------------------------------------------------------------------------------

