//------------------------------------------------------------------------------
// 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_ANIMATION_SAVER_H_
#define BINARY_ANIMATION_SAVER_H_

namespace Lamp{

class BinaryWriter;
class AnimationManager;
class AnimationSet;
class CameraAnimation;
class CameraAnimationData;
class SceneNodeAnimation;
class SceneNodeAnimationData;
class CharacterModelAnimation;
class CharacterModelAnimationData;

class VectorInterpolator;
class VectorConstantInterpolator;
class VectorArrayInterpolator;
class VectorLinearInterpolator;
class RotationInterpolator;
class RotationConstantInterpolator;
class EulerArrayInterpolator;
class QuaternionArrayInterpolator;
class QuaternionLinearInterpolator;

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

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

	//--------------------------------------------------------------------------
	// セーブ
	//--------------------------------------------------------------------------
	/**
	 * セーブ
	 * @param filePath ファイルパス
	 * @param manager セーブするアニメーションマネージャ
	 */
	virtual void save(const String& filePath, AnimationManager* manager);

	/**
	 * セーブ
	 * @param binaryWriter バイナリライタ
	 * @param manager セーブするアニメーションマネージャ
	 */
	virtual void save(BinaryWriter* binaryWriter, AnimationManager* manager);

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

	/**
	 * オブジェクトのカウント
	 * @return オブジェクト数
	 */
	virtual int countObjects();

	/**
	 * オブジェクトカウンタのクリア
	 */
	virtual void clearObjectCount(){
		animationCount_ = animationDataCount_ = animationSetCount_ =
		cameraCount_ = cameraDataCount_ =
		sceneNodeCount_ = sceneNodeDataCount_ =
		characterModelCount_ = characterModelDataCount_ = 0;
	}

	//--------------------------------------------------------------------------
	// アニメーションリスト
	//--------------------------------------------------------------------------
	/**
	 * アニメーションリストの書き出し
	 */
	virtual void writeAnimationList();

	//--------------------------------------------------------------------------
	/**
	 * アニメーションセットの書き出し
	 * @param animation 書き出すアニメーションセット
	 */
	virtual void writeAnimationSet(AnimationSet* animation);

	//--------------------------------------------------------------------------
	/**
	 * カメラアニメーションの書き出し
	 * @param animation 書き出すカメラアニメーション
	 */
	virtual void writeCameraAnimation(CameraAnimation* animation);

	/**
	 * カメラアニメーションデータの書き出し
	 * @param data 書き出すカメラアニメーションデータ
	 */
	virtual void writeCameraAnimationData(CameraAnimationData* data);

	//--------------------------------------------------------------------------
	/**
	 * シーンノードアニメーションの書き出し
	 * @param animation 書き出すシーンノードアニメーション
	 */
	virtual void writeSceneNodeAnimation(SceneNodeAnimation* animation);

	/**
	 * シーンノードアニメーションデータの書き出し
	 * @param data 書き出すシーンノードアニメーションデータ
	 */
	virtual void writeSceneNodeAnimationData(SceneNodeAnimationData* data);

	//--------------------------------------------------------------------------
	/**
	 * キャラクタモデルアニメーションの書き出し
	 * @param animation 書き出すキャラクタモデルアニメーション
	 */
	virtual void writeCharacterModelAnimation(
		CharacterModelAnimation* animation);

	/**
	 * キャラクタモデルアニメーションデータの書き出し
	 * @param data 書き出すキャラクタモデルアニメーションデータ
	 */
	virtual void writeCharacterModelAnimationData(
		CharacterModelAnimationData* data);

	//--------------------------------------------------------------------------
	// リンク
	//--------------------------------------------------------------------------
	/**
	 * リンクの書き出し
	 */
	virtual void writeLink();

	/**
	 * アニメーションセットリンクの書き出し
	 * @param animation リンクを書き出すアニメーションセット
	 */
	virtual void writeAnimationSetLink(AnimationSet* animation);

	/**
	 * カメラアニメーションリンクの書き出し
	 * @param animation リンクを書き出すカメラアニメーション
	 */
	virtual void writeCameraAnimationLink(CameraAnimation* animation);

	/**
	 * シーンノードアニメーションリンクの書き出し
	 * @param animation リンクを書き出すシーンノードアニメーション
	 */
	virtual void writeSceneNodeAnimationLink(SceneNodeAnimation* animation);

	/**
	 * キャラクタモデルアニメーションリンクの書き出し
	 * @param animation リンクを書き出すキャラクタモデルアニメーション
	 */
	virtual void writeCharacterModelAnimationLink(
		CharacterModelAnimation* animation);

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

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

	/**
	 * 四元数の書き出し
	 * @param quaternion 四元数
	 */
	virtual void writeQuaternion(const Quaternion& quaternion);

	//--------------------------------------------------------------------------
	// ベクトル補間
	//--------------------------------------------------------------------------
	/**
	 * ベクトル補間の書き出し
	 * @param interpolator ベクトル補間
	 */
	virtual void writeVectorInterpolator(
		VectorInterpolator* interpolator);

	/**
	 * ベクトル定数補間の書き出し
	 * @param interpolator ベクトル定数補間
	 */
	virtual void writeVectorConstantInterpolator(
		VectorConstantInterpolator* interpolator);

	/**
	 * ベクトル配列補間の書き出し
	 * @param interpolator ベクトル配列補間
	 */
	virtual void writeVectorArrayInterpolator(
		VectorArrayInterpolator* interpolator);

	/**
	 * ベクトル線形補間の書き出し
	 * @param interpolator ベクトル線形補間
	 */
	virtual void writeVectorLinearInterpolator(
		VectorLinearInterpolator* interpolator);

	//--------------------------------------------------------------------------
	// 回転補間
	//--------------------------------------------------------------------------
	/**
	 * 回転補間の書き出し
	 * @param interpolator 回転補間
	 */
	virtual void writeRotationInterpolator(
		RotationInterpolator* interpolator);

	/**
	 * 回転定数補間の書き出し
	 * @param interpolator 回転定数補間
	 */
	virtual void writeRotationConstantInterpolator(
		RotationConstantInterpolator* interpolator);

	/**
	 * オイラー回転配列補間の書き出し
	 * @param interpolator オイラー回転配列補間
	 */
	virtual void writeEulerArrayInterpolator(
		EulerArrayInterpolator* interpolator);

	/**
	 * 四元数回転配列補間の書き出し
	 * @param interpolator 四元数回転配列補間
	 */
	virtual void writeQuaternionArrayInterpolator(
		QuaternionArrayInterpolator* interpolator);

	/**
	 * 四元数回転線形補間の書き出し
	 * @param interpolator 四元数回転線形補間
	 */
	virtual void writeQuaternionLinearInterpolator(
		QuaternionLinearInterpolator* interpolator);

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

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

	/**
	 * ブロックの終了
	 * @param blockStartAddress ブロック開始位置
	 * @param objectCount オブジェクト数
	 */
	virtual void endBlock(int blockStartAddress, int objectCount);

	//--------------------------------------------------------------------------
	// メンバ
	//--------------------------------------------------------------------------
	/// ライタ
	BinaryWriter* writer_;
	/// アニメーションマネージャ
	AnimationManager* manager_;

	/// アニメーションカウント
	int animationCount_;
	/// アニメーションデータカウント
	int animationDataCount_;
	/// アニメーションセットカウント
	int animationSetCount_;
	/// カメラアニメーションカウント
	int cameraCount_;
	/// カメラアニメーションデータカウント
	int cameraDataCount_;
	/// シーンノードアニメーションカウント
	int sceneNodeCount_;
	/// シーンノードアニメーションデータカウント
	int sceneNodeDataCount_;
	/// キャラクタモデルアニメーションカウント
	int characterModelCount_;
	/// キャラクタモデルアニメーションデータカウント
	int characterModelDataCount_;

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

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

};

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