//------------------------------------------------------------------------------
// 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_H_
#define GRAPHICS_DEVICE_H_

namespace Lamp{

class GraphicsDeviceSettings;

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

	//--------------------------------------------------------------------------
	// デバイス構築オプション
	//--------------------------------------------------------------------------
	/**
	 * カーソルクリップの設定
	 * @param clipFlag trueならカーソルをクリップする
	 */
	void setClipCursor(bool clipFlag){ clipCursor_ = clipFlag; }

	/**
	 * カーソルクリップの取得
	 * @return trueならカーソルがクリップされる
	 */
	bool getClipCursor(){ return clipCursor_; }

	//--------------------------------------------------------------------------
	// デバイス操作
	//--------------------------------------------------------------------------
	/**
	 * クリア
	 * @param color クリアカラー
	 * @param zValue Zクリア値
	 * @param stencilValue ステンシルクリア値
	 */
	void clear(Color4c color = Color4c(0, 0, 0, 0),
		float zValue = 1.0f, u_int stencilValue = 0);

	/**
	 * プレゼンテーション
	 * @return デバイスがロストしていればtrueを返す
	 */
	bool presentation();

	/**
	 * フルスクリーンモードとウィンドウモードを切り替える
	 */
	void toggleFullscreen();

	/**
	 * 強制的にウィンドウモードにする
	 */
	void forceWindowed();

	/**
	 * デバイスを再構築します
	 * @return 成功したらtrueを返す
	 */
	bool rebuild();

protected:
	//--------------------------------------------------------------------------
	// 初期化、デバイス管理
	//--------------------------------------------------------------------------
	/**
	 * コンストラクタ
	 */
	GraphicsDevice();

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

	/**
	 * ウィンドウハンドルの初期化
	 * @param windowHandle ウィンドウハンドル
	 */
	void initializeWindowHandle(HWND windowHandle);

	/**
	 * 初期化
	 * @return 成功したらtrueを返す
	 */
	bool initialize();

	/**
	 * リセット
	 * @return 成功したらtrueを返す
	 */
	bool reset();

	/**
	 * カーソルのクリップ
	 */
	void clipCursor();

	/**
	 * 後始末
	 */
	void cleanup();

	/**
	 * Direct3Dデバイスの取得
	 * @return Direct3Dデバイス
	 */
	Direct3DDevice* getDirect3DDevice(){ return direct3DDevice_; }

	//--------------------------------------------------------------------------
	// ウィンドウ関係
	//--------------------------------------------------------------------------
	/**
	 * ウィンドウプロシージャ
	 * @param windowHandle ウィンドウハンドル
	 * @param message メッセージ
	 * @param wParam wメッセージパラメータ
	 * @param lParam lメッセージパラメータ
	 */
	LRESULT windowProcedure(
		HWND windowHandle, u_int message, WPARAM wParam, LPARAM lParam);

	/**
	 * ウィンドウの調整
	 */
	void adjustWindowForChange();

	/**
	 * ウィンドウサイズ変更
	 */
	void handlePossibleSizeChange();

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

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

	// Direct3Dデバイス
	Direct3DDevice* direct3DDevice_;
	// プレゼンテーションパラメータ
	D3DPRESENT_PARAMETERS presentationParameter_;
	// グラフィックスデバイス設定
	GraphicsDeviceSettings* settings_;
	// ウィンドウハンドル
	HWND windowHandle_;
	// ウィンドウスタイル
	u_int windowStyle_;
	// ウィンドウバウンズサイズ
	RECT windowBoundsSize_;
	// ウィンドウクライアントサイズ
	RECT windowClientSize_;
	// メニューハンドル
	HMENU menuHandle_;

	// デバイスがロストしていないか
	bool deviceLost_;
	// カーソルをクリップするか
	bool clipCursor_;
	// 最大化されているかどうか
	bool windowMaximized_;
	// 最小化されているかどうか
	bool windowMinimized_;
	// サイズ変更を無視する
	bool ignoreSizeChange_;

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

};

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

