//------------------------------------------------------------------------------
// 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 SPRITE_GRAPHICS_BUFFER_H_
#define SPRITE_GRAPHICS_BUFFER_H_

#include <Graphics/System/GraphicsDeviceObjectHolder.h>

namespace Lamp{

//------------------------------------------------------------------------------
/**
 * スプライトグラフィックスバッファ
 */
class SpriteGraphicsBuffer : public GraphicsDeviceObjectHolder{
friend class SpriteRenderer;
public:
	//--------------------------------------------------------------------------
	// 描画
	//--------------------------------------------------------------------------
	/**
	 * リクエスト
	 * @param minPosition 最小位置
	 * @param maxPosition 最大位置
	 * @param minUV 最小UV
	 * @param maxUV 最大UV
	 */
	virtual void request(
		const Point2f& minPosition, const Point2f& maxPosition,
		const TexCoord2& minUV, const TexCoord2& maxUV);

	/**
	 * レンダリング
	 */
	virtual void render();

	//--------------------------------------------------------------------------
	// デバイスオブジェクト
	//--------------------------------------------------------------------------
	/**
	 * デバイスオブジェクトの初期化
	 * @return 成功したらtrueを返す
	 */
	virtual bool initializeGraphicsDeviceObjects(){ return true; }

	/**
	 * デバイスオブジェクトの削除
	 */
	virtual void deleteGraphicsDeviceObjects(){}

	/**
	 * デバイスオブジェクトのリストア
	 * @return 成功したらtrueを返す
	 */
	virtual bool restoreGraphicsDeviceObjects(){ return true; }

	/**
	 * デバイスオブジェクトの無効化
	 */
	virtual void invalidateGraphicsDeviceObjects(){
		SafeRelease(vertexDeclaration_);
		SafeRelease(vertexBuffer_);
		SafeRelease(indexBuffer_);
	}

protected:
	//--------------------------------------------------------------------------
	// 生成、破棄
	//--------------------------------------------------------------------------
	/**
	 * コンストラクタ
	 */
	SpriteGraphicsBuffer();

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

	//--------------------------------------------------------------------------
	// 描画
	//--------------------------------------------------------------------------
	/**
	 * セットアップ
	 */
	virtual void setup();

	/**
	 * インデックスバッファの構築
	 */
	virtual void buildIndexBuffer();

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

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

	//--------------------------------------------------------------------------
	// 定数
	//--------------------------------------------------------------------------
	// 頂点サイズ
	static const int vertexSize_ = (sizeof(Vector3) + sizeof(TexCoord2));
	// インデックスサイズ
	static const int indexSize_ = sizeof(u_short);
	// 最大スプライト数
	static const int maxSpriteCount_ = 256;
	// スプライトあたりの頂点数
	static const int vertexPerSprite_ = 4;
	// 頂点バッファサイズ
	static const int vertexBufferSize_ = maxSpriteCount_ * vertexPerSprite_;
	// スプライト当たりのインデックス数
	static const int indexPerSprite_ = 6;
	// インデックスバッファサイズ
	static const int indexBufferSize_ = maxSpriteCount_ * indexPerSprite_;

	//--------------------------------------------------------------------------
#pragma pack(1)
	/// スプライトデータ
	class SpriteData{
	public:
		Vector3 position0;
		TexCoord2 uv0;
		Vector3 position1;
		TexCoord2 uv1;
		Vector3 position2;
		TexCoord2 uv2;
		Vector3 position3;
		TexCoord2 uv3;
	};
#pragma pack()

	//--------------------------------------------------------------------------
	// メンバ
	//--------------------------------------------------------------------------
	// インデックスバッファ
	Direct3DIndexBuffer* indexBuffer_;
	// 頂点バッファ
	Direct3DVertexBuffer* vertexBuffer_;
	// 頂点記述
	Direct3DVertexDeclaration* vertexDeclaration_;
	// データバッファ
	SpriteData dataBuffer_[maxSpriteCount_];
	// 先頭インデックス
	int topIndex_;
	// 末尾インデックス
	int bottomIndex_;

};

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