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

namespace Lamp{

class BinaryWriter;
class Scene;
class Fog;
class SceneNodeManager;
class LightManager;
class ModelManager;
class MeshManager;
class MeshDataManager;
class MaterialManager;
class TextureManager;
class PictureManager;

class SceneNode;
class LODSceneNode;
class Light;
class AmbientLight;
class DirectionalLight;
class PointLight;
class Model;
class StandardModel;
class CharacterModel;
class Bone;
class Mesh;
class RigidMesh;
class CharacterMesh;
class MeshData;
class Material;
class BasicMaterial;
class Texture;
class SurfaceTexture;
class Picture;

//------------------------------------------------------------------------------
/**
 * バイナリシーンセーバ
 */
class BinarySceneSaver{
public:
	/**
	 * コンストラクタ
	 */
	BinarySceneSaver();

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

	/**
	 * セーブ
	 * @param filePath ファイルパス
	 * @param scene セーブするシーン
	 */
	virtual void save(const String& filePath, Scene* scene);

	/**
	 * セーブ
	 * @param binaryWriter バイナリライタ
	 * @param scene セーブするシーン
	 * @param basePath ベースパス
	 */
	virtual void save(BinaryWriter* binaryWriter, Scene* scene,
		const String& basePath = "");

protected:
	/**
	 * ヘッダの書き出し
	 */
	virtual void writeHeader();

	/**
	 * オブジェクトリストの書き出し
	 * @return リンク数
	 */
	virtual int writeObjectList();

	/**
	 * リンクの書き出し
	 * @param linkCount リンク数
	 */
	virtual void writeLink(int linkCount);

	//--------------------------------------------------------------------------
	// フォグ
	//--------------------------------------------------------------------------
	/**
	 * フォグの書き出し
	 * @param fog フォグ
	 */
	virtual void writeFog(Fog* fog);

	//--------------------------------------------------------------------------
	// シーンノード
	//--------------------------------------------------------------------------
	/**
	 * シーンノードリストの書き出し
	 */
	virtual void writeSceneNodeList();

	/**
	 * シーンノードの書き出し
	 * @param sceneNode 書き出すシーンノード
	 */
	virtual void writeSceneNode(SceneNode* sceneNode);

	/**
	 * レベルオブディティールシーンノードの書き出し
	 * @param sceneNode 書き出すレベルオブディティールシーンノード
	 */
	virtual void writeLODSceneNode(LODSceneNode* sceneNode);

	//--------------------------------------------------------------------------
	// ライト
	//--------------------------------------------------------------------------
	/**
	 * ライトリストの書き出し
	 */
	virtual void writeLightList();

	/**
	 * ライトの書き出し
	 * @param light 書き出すライト
	 */
	virtual void writeLight(Light* light);

	/**
	 * アンビエントライトの書き出し
	 * @param light 書き出すライト
	 */
	virtual void writeAmbientLight(AmbientLight* light);

	/**
	 * ディレクショナルライトの書き出し
	 * @param light 書き出すライト
	 */
	virtual void writeDirectionalLight(DirectionalLight* light);

	/**
	 * ポイントライトの書き出し
	 * @param light 書き出すライト
	 */
	virtual void writePointLight(PointLight* light);

	//--------------------------------------------------------------------------
	// モデル
	//--------------------------------------------------------------------------
	/**
	 * モデルリストの書き出し
	 */
	virtual void writeModelList();

	/**
	 * 標準モデルの書き出し
	 * @param model 書き出すモデル
	 */
	virtual void writeStandardModel(StandardModel* model);

	/**
	 * キャラクタモデルの書き出し
	 * @param model 書き出すモデル
	 */
	virtual void writeCharacterModel(CharacterModel* model);

	/**
	 * ボーンの書き出し
	 * @param bone 書き出すボーン
	 */
	virtual void writeBone(Bone* bone);

	/**
	 * ボーンリンクの書き出し
	 * @param model 書き出すモデル
	 * @param bone 書き出すボーン
	 */
	virtual void writeBoneLink(CharacterModel* model, Bone* bone);

	//--------------------------------------------------------------------------
	// メッシュ
	//--------------------------------------------------------------------------
	/**
	 * メッシュリストの書き出し
	 */
	virtual void writeMeshList();

	/**
	 * 剛体メッシュの書き出し
	 * @param mesh 書き出すメッシュ
	 */
	virtual void writeRigidMesh(RigidMesh* mesh);

	/**
	 * キャラクタメッシュの書き出し
	 * @param mesh 書き出すメッシュ
	 */
	virtual void writeCharacterMesh(CharacterMesh* mesh);

	//--------------------------------------------------------------------------
	// メッシュデータ
	//--------------------------------------------------------------------------
	/**
	 * メッシュデータリストの書き出し
	 */
	virtual void writeMeshDataList();

	/**
	 * メッシュデータの書き出し
	 * @param meshData 書き出すメッシュデータ
	 */
	virtual void writeMeshData(MeshData* meshData);

	//--------------------------------------------------------------------------
	// マテリアル
	//--------------------------------------------------------------------------
	/**
	 * マテリアルリストの書き出し
	 */
	virtual void writeMaterialList();

	/**
	 * マテリアルの書き出し
	 * @param material 書き出すマテリアル
	 */
	virtual void writeMaterial(const Material* material);

	/**
	 * 基本マテリアルの書き出し
	 * @param material 書き出すマテリアル
	 */
	virtual void writeBasicMaterial(const BasicMaterial* material);

	//--------------------------------------------------------------------------
	// テクスチャ
	//--------------------------------------------------------------------------
	/**
	 * テクスチャリストの書き出し
	 */
	virtual void writeTextureList();

	/**
	 * サーフェーステクスチャの書き出し
	 * @param texture 書き出すテクスチャ
	 */
	virtual void writeSurfaceTexture(const SurfaceTexture* texture);

	//--------------------------------------------------------------------------
	// ピクチャ
	//--------------------------------------------------------------------------
	/**
	 * ピクチャの書き出し
	 * @param picture 書き出すピクチャ
	 */
	virtual void writePicture(const Picture* picture);

	//--------------------------------------------------------------------------
	// リンク
	//--------------------------------------------------------------------------
	/**
	 * シーンノードリンクの書き出し
	 * @param sceneNode 書き出すシーンノード
	 */
	virtual void writeSceneNodeLink(SceneNode* sceneNode);

	/**
	 * モデルリンクの書き出し
	 * @param model 書き出すモデル
	 */
	virtual void writeModelLink(const Model* model);

	/**
	 * メッシュリンクの書き出し
	 * @param mesh 書き出すメッシュ
	 */
	virtual void writeMeshLink(const Mesh* mesh);

	/**
	 * マテリアルリンクリストの書き出し
	 */
	virtual void writeMaterialLinkList();

	/**
	 * 基本マテリアルリンクの書き出し
	 * @param material 書き出すマテリアル
	 */
	virtual void writeBasicMaterialLink(const BasicMaterial* material);

	/**
	 * テクスチャリンクの書き出し
	 * @param texture 書き出すテクスチャ
	 */
	virtual void writeTextureLink(const Texture* texture);

	//--------------------------------------------------------------------------
	// 値の書き出し
	//--------------------------------------------------------------------------
	/**
	 * 文字列の書き出し
	 * @param string 文字列
	 */
	virtual void writeString(const String& string);

	/**
	 * 三次元ベクトルの書き出し
	 * @param vector 三次元ベクトル
	 */
	virtual void writeVector3(const Vector3& vector);

	/**
	 * 3×4行列の書き出し
	 * @return 3×4行列
	 */
	virtual void writeMatrix34(const Matrix34& matrix);

	/**
	 * 四要素整数カラー値の書き出し
	 * @param color 四要素整数カラー値
	 */
	virtual void writeColor4c(const Color4c& color);

	/**
	 * 三要素実数カラー値の書き出し
	 * @param color 三要素実数カラー値
	 */
	virtual void writeColor3f(const Color3f& color);

	/**
	 * 四要素実数カラー値の書き出し
	 * @param color 四要素実数カラー値
	 */
	virtual void writeColor4f(const Color4f& color);

	/**
	 * 二次元テクスチャ座標値の書き出し
	 * @param uv 二次元テクスチャ座標値
	 */
	virtual void writeTexCoord2(const TexCoord2& uv);

	/**
	 * 軸沿いボックスの書き出し
	 * @param box 軸沿いボックス
	 */
	virtual void writeAxisAlignedBox(const AxisAlignedBox& box);

	/**
	 * 球の書き出し
	 * @param sphere 球
	 */
	virtual void writeSphere(const Sphere& sphere);

	//--------------------------------------------------------------------------
	// ユーティリティ
	//--------------------------------------------------------------------------
	/**
	 * アライメントを取る
	 */
	virtual void align();

	/**
	 * IDの書き出し
	 * @param id 書き出すID
	 */
	virtual void writeID(const String& id);

	/**
	 * ブロックの開始
	 * @param blockName ブロック名
	 * @return プロック開始位置
	 */
	virtual int startBlock(const String& blockName);

	/**
	 * ブロックの終了
	 * @param blockStartAddress ブロック開始位置
	 */
	virtual void endBlock(int blockStartAddress);

	//--------------------------------------------------------------------------
	/// ライタ
	BinaryWriter* writer_;
	/// ベースパス
	String basePath_;
	/// シーン
	Scene* scene_;
	/// シーンノードマネージャ
	SceneNodeManager* sceneNodeManager_;
	/// ライトマネージャ
	LightManager* lightManager_;
	/// モデルマネージャ
	ModelManager* modelManager_;
	/// メッシュマネージャ
	MeshManager* meshManager_;
	/// メッシュデータマネージャ
	MeshDataManager* meshDataManager_;
	/// マテリアルマネージャ
	MaterialManager* materialManager_;
	/// テクスチャマネージャ
	TextureManager* textureManager_;
	/// ピクチャマネージャ
	PictureManager* pictureManager_;

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

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

};

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