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

#include <Animation/System/AnimationData.h>
#include <Animation/VectorInterpolator/VectorInterpolator.h>
#include <Animation/RotationInterpolator/RotationInterpolator.h>

namespace Lamp{

//------------------------------------------------------------------------------
/**
 * カメラアニメーションデータ
 */
class CameraAnimationData : public AnimationData{
friend class AnimationManager;
protected:
	//--------------------------------------------------------------------------
	/**
	 * カメラシーケンス
	 */
	class CameraSequence : public Sequence{
	public:
		/**
		 * コンストラクタ
		 */
		CameraSequence() : Sequence(),
			rotation_(NULL), translation_(NULL){}

		/**
		 * デストラクタ
		 */
		virtual ~CameraSequence(){
			SafeDelete(translation_);
			SafeDelete(rotation_);
		}

		/**
		 * 代入コピー
		 * @param copy コピー元
		 */
		virtual void operator =(const CameraSequence& copy){
			Sequence::operator=(copy);
			SafeDelete(translation_);
			SafeDelete(rotation_);
			if(copy.rotation_ != NULL){ 
				rotation_ = copy.rotation_->duplicate();
			}
			if(copy.translation_ != NULL){
				translation_ = copy.translation_->duplicate();
			}
		}

		/**
		 * 長さの計算
		 */
		virtual void calcLength(){
			length_ = 0.f;
			if((rotation_ != NULL) && (rotation_->getLength() > length_)){
				length_ = rotation_->getLength();
			}
			if((translation_ != NULL) &&
				(translation_->getLength() > length_)){
				length_ = translation_->getLength();
			}
		}

		/// 回転
		RotationInterpolator* rotation_;
		/// 移動
		VectorInterpolator* translation_;

	};

public:
	//--------------------------------------------------------------------------
	// コピー
	//--------------------------------------------------------------------------
	/**
	 * コピー
	 * @return コピーされたアニメーションデータ
	 */
	virtual AnimationData* copy() const{ return copyCameraAnimationData(); }

	/**
	 * カメラアニメーションデータのコピー
	 */
	virtual CameraAnimationData* copyCameraAnimationData() const;

	//--------------------------------------------------------------------------
	// シーケンス
	//--------------------------------------------------------------------------
	/**
	 * シーケンス数の設定
	 * @param sequenceCount シーケンス数
	 */
	virtual void setSequenceCount(int sequenceCount){
		SafeArrayDelete(sequences_);
		sequenceCount_ = sequenceCount;
		if(sequenceCount_ == 0){ return; }
		sequences_ = new CameraSequence[sequenceCount_];
	}

	/**
	 * シーケンス数の取得
	 * @return シーケンス数
	 */
	virtual int getSequenceCount() const{ return sequenceCount_; }

	//--------------------------------------------------------------------------
	// 回転
	//--------------------------------------------------------------------------
	/**
	 * 回転の設定
	 * @param sequence シーケンス
	 * @param rotation 設定する回転
	 */
	virtual void setRotation(int sequence, RotationInterpolator* rotation){
		Assert(sequence >= 0);
		Assert(sequence < sequenceCount_);
		CameraSequence& data = sequences_[sequence];
		SafeDelete(data.rotation_);
		data.rotation_ = rotation;
		data.calcLength();
	}

	/**
	 * 回転の取得
	 * @param sequence シーケンス
	 * @return 回転
	 */
	virtual RotationInterpolator* getRotation(int sequence) const{
		Assert(sequence >= 0);
		Assert(sequence < sequenceCount_);
		return sequences_[sequence].rotation_;
	}

	//--------------------------------------------------------------------------
	// 移動
	//--------------------------------------------------------------------------
	/**
	 * 移動の設定
	 * @param sequence シーケンス
	 * @param translation 設定する移動
	 */
	virtual void setTranslation(
		int sequence, VectorInterpolator* translation){
		Assert(sequence >= 0);
		Assert(sequence < sequenceCount_);
		CameraSequence& data = sequences_[sequence];
		SafeDelete(data.translation_);
		data.translation_ = translation;
		data.calcLength();
	}

	/**
	 * 移動の取得
	 * @param sequence シーケンス
	 * @return 移動
	 */
	virtual VectorInterpolator* getTranslation(int sequence) const{
		Assert(sequence >= 0);
		Assert(sequence < sequenceCount_);
		return sequences_[sequence].translation_;
	}

	//--------------------------------------------------------------------------
	// RTTI
	//--------------------------------------------------------------------------
	/**
	 * カメラアニメーションデータかどうか
	 * @return カメラアニメーションデータならtrue
	 */
	virtual bool isCameraAnimationData() const{ return true; }

	//--------------------------------------------------------------------------
protected:
	/**
	 * コンストラクタ
	 * @param name 名前
	 * @param manager アニメーションマネージャ
	 */
	CameraAnimationData(const String& name, AnimationManager* manager) :
		AnimationData(name, manager), sequenceCount_(0), sequences_(NULL){
	}

	/**
	 * デストラクタ
	 */
	virtual ~CameraAnimationData(){
		SafeArrayDelete(sequences_);
	}

	//--------------------------------------------------------------------------
	/**
	 * シーケンスの取得
	 * @param sequence シーケンス
	 * @return シーケンス
	 */
	virtual Sequence* getSequence(int sequence){
		Assert(sequence >= 0);
		Assert(sequence < sequenceCount_);
		return &sequences_[sequence];
	}

	/**
	 * シーケンスの取得
	 * @param sequence シーケンス
	 * @return シーケンス
	 */
	virtual const Sequence* getSequence(int sequence) const{
		Assert(sequence >= 0);
		Assert(sequence < sequenceCount_);
		return &sequences_[sequence];
	}

	//--------------------------------------------------------------------------
private:
	// シーケンス数
	int sequenceCount_;
	// シーケンス
	CameraSequence* sequences_;

};

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