//------------------------------------------------------------------------------
// 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_COMBO_INFORMATION_H_
#define GRAPHICS_DEVICE_COMBO_INFORMATION_H_

#include <Core/Container/ArrayList.h>
#include <Graphics/Primitive/VertexProcessingType.h>

namespace Lamp{

class GraphicsDeviceEnumeration;
class GraphicsDeviceInformation;
class ConfirmGraphicsDevice;

//------------------------------------------------------------------------------
/**
 * グラフィックスデバイスコンボ情報
 */
class GraphicsDeviceComboInformation{
friend class GraphicsDeviceInformation;
public:
	//--------------------------------------------------------------------------
	/**
	 * アダプタフォーマットの取得
	 * @return アダプタフォーマット
	 */
	virtual D3DFORMAT getAdapterFormat(){ return adapterFormat_; }

	/**
	 * バックバッファフォーマットの取得
	 * @return バックバッファフォーマット
	 */
	virtual D3DFORMAT getBackBufferFormat(){ return backBufferFormat_; }

	/**
	 * ウィンドウフラグの取得
	 * @return ウィンドウフラグ
	 */
	virtual bool isWindowed(){ return isWindowed_; }

	//--------------------------------------------------------------------------
	/**
	 * アダプタ番号の取得
	 * @return アダプタ番号
	 */
	virtual int getAdapterOrdinal(){ return adapterOrdinal_; }

	/**
	 * デバイスタイプの取得
	 * @return デバイスタイプ
	 */
	virtual D3DDEVTYPE getDeviceType(){ return deviceType_; }

	//--------------------------------------------------------------------------
	/**
	 * 深度、ステンシルフォーマット数の取得
	 * @return 深度、ステンシルフォーマット数
	 */
	virtual int getDepthStencilFormatCount() const{
		return depthStencilFormats_.getCount();
	}

	/**
	 * 深度、ステンシルフォーマットの取得
	 * @param index インデックス
	 * @return 深度、ステンシルフォーマット
	 */
	virtual D3DFORMAT getDepthStencilFormat(int index){
		return depthStencilFormats_.get(index);
	}

	//--------------------------------------------------------------------------
	/**
	 * マルチサンプルタイプ数の取得
	 * @return マルチサンプルタイプ数
	 */
	virtual int getMultiSampleTypeCount() const{
		return multiSampleTypes_.getCount();
	}

	/**
	 * マルチサンプルタイプの取得
	 * @param index インデックス
	 * @return マルチサンプルタイプ
	 */
	virtual D3DMULTISAMPLE_TYPE getMultiSampleType(int index){
		return multiSampleTypes_.get(index);
	}

	/**
	 * マルチサンプルタイプのクォリティの取得
	 *
	 * マルチサンプルタイプのクォリティ数はgetMultiSampleTypeCount()で取得する。
	 * @param index インデックス
	 * @return マルチサンプルタイプのクォリティ
	 */
	virtual u_int getMultiSampleTypeQuality(int index){
		return multiSampleTypeQualities_.get(index);
	}

	//--------------------------------------------------------------------------
	/**
	 * マルチサンプルコンフリクト数の取得
	 * @return マルチサンプルと深度、ステンシルフォーマットとのコンフリクト数
	 */
	virtual int getMultiSampleConflictCount() const{
		return multiSampleConflictFormats_.getCount();
	}

	/**
	 * マルチサンプルコンフリクトフォーマットの取得
	 * @param index インデックス
	 * @return マルチサンプルとコンフリクトした深度、ステンシルフォーマット
	 */
	virtual D3DFORMAT getMultiSampleConflictFormat(int index){
		return multiSampleConflictFormats_.get(index);
	}

	/**
	 * マルチサンプルコンフリクトタイプの取得
	 * @param index インデックス
	 * @return 深度、ステンシルフォーマットとコンフリクトしたマルチサンプルタイプ
	 */
	virtual D3DMULTISAMPLE_TYPE getMultiSampleConflictType(int index){
		return multiSampleConflictTypes_.get(index);
	}

	//--------------------------------------------------------------------------
	/**
	 * 頂点プロセスタイプ数の取得
	 * @return 頂点プロセスタイプ数
	 */
	virtual int getVertexProcessingTypeCount() const{
		return vertexProcessingTypes_.getCount();
	}

	/**
	 * 頂点プロセスタイプの取得
	 * @param index インデックス
	 * @return 頂点プロセスタイプ
	 */
	virtual VertexProcessingType getVertexProcessingType(int index){
		return vertexProcessingTypes_.get(index);
	}

	//--------------------------------------------------------------------------
	/**
	 * プレゼンテーション間隔数の取得
	 * @return プレゼンテーション間隔数
	 */
	virtual int getPresentationIntervalCount() const{
		return presentationInterval_.getCount();
	}

	/**
	 * プレゼンテーション間隔の取得
	 * @param index インデックス
	 * @return プレゼンテーション間隔
	 */
	virtual u_int getPresentationInterval(int index){
		return presentationInterval_.get(index);
	}

	//--------------------------------------------------------------------------
	/**
	 * 文字列への変換
	 * @return GraphicsDeviceComboInformationの文字列表記
	 */
	virtual String toString();

	//--------------------------------------------------------------------------
protected:
	/**
	 * コンストラクタ
	 */
	GraphicsDeviceComboInformation(
		D3DFORMAT adapterFormat, D3DFORMAT backBufferFormat, bool isWindowed);

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

	/**
	 * 列挙
	 * @param enumeration グラフィックスデバイス列挙
	 * @param deviceInformation グラフィックスデバイス情報
	 * @return 列挙が成功すればtrue
	 */
	virtual bool enumerate(GraphicsDeviceEnumeration* enumeration,
		GraphicsDeviceInformation* deviceInformation);

	/**
	 * 深度、ステンシルフォーマットの構築
	 * @param minimumDepthBits 最小深度ビット
	 * @param minimumStencilBits 最小ステンシルビット
	 */
	virtual void buildDepthStencilFormats(
		u_int minimumDepthBits, u_int minimumStencilBits);

	/**
	 * マルチサンプルタイプの構築
	 */
	virtual void buildMultiSampleType();

	/**
	 * マルチサンプルコンフリクトの構築
	 */
	virtual void buildMultiSampleConflict();

	/**
	 * 頂点プロセスタイプの構築
	 * @param deviceCapability デバイス能力
	 * @param usesMixedVertexProcessing 混合頂点プロセスを使用するならtrue
	 * @param confirmDevice デバイス確認インターフェース
	 */
	virtual void buildVertexProcessingType(
		const D3DCapacity& deviceCapability, bool usesMixedVertexProcessing,
		ConfirmGraphicsDevice* confirmDevice);

	/**
	 * プレゼンテーション間隔の構築
	 * @param deviceCapability デバイス能力
	 */
	virtual void buildPresentationInterval(const D3DCapacity& deviceCapability);

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

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

	// 深度、ステンシルフォーマット
	ArrayList<D3DFORMAT> depthStencilFormats_;
	// マルチサンプルタイプ
	ArrayList<D3DMULTISAMPLE_TYPE> multiSampleTypes_;
	// マルチサンプルタイプクォリティ
	ArrayList<u_int> multiSampleTypeQualities_;
	// マルチサンプルコンフリクトフォーマット
	ArrayList<D3DFORMAT> multiSampleConflictFormats_;
	// マルチサンプルコンフリクトタイプ
	ArrayList<D3DMULTISAMPLE_TYPE> multiSampleConflictTypes_;
	// 頂点プロセスタイプ
	ArrayList<VertexProcessingType> vertexProcessingTypes_;
	// プレゼンテーション間隔
	ArrayList<u_int> presentationInterval_;

	// アダプタ番号
	int adapterOrdinal_;
	// デバイスタイプ
	D3DDEVTYPE deviceType_;
	// アダプタフォーマット
	D3DFORMAT adapterFormat_;
	// バックバッファフォーマット
	D3DFORMAT backBufferFormat_;
	// ウィンドウフラグ
	bool isWindowed_;
};

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