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

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

namespace Lamp{

//------------------------------------------------------------------------------
/**
 * オブジェクトアニメーション
 */
class ObjectAnimation  : public Animation{
public:
	//--------------------------------------------------------------------------
	// アニメーションデータ
	//--------------------------------------------------------------------------
	/**
	 * アニメーションデータの取得
	 * @return アニメーションデータ
	 */
	virtual AnimationData* getAnimationData() = 0;

	/**
	 * アニメーションデータの取得
	 * @return アニメーションデータ
	 */
	virtual const AnimationData* getAnimationData() const = 0;

	//--------------------------------------------------------------------------
	// ターゲット名
	//--------------------------------------------------------------------------
	/**
	 * ターゲット名の設定
	 * @param targetName 設定するターゲット名
	 */
	virtual void setTargetName(const String& targetName){
		targetName_ = targetName;
	}

	/**
	 * ターゲット名の取得
	 * @return ターゲット名
	 */
	virtual const String& getTargetName() const{ return targetName_; }

	//--------------------------------------------------------------------------
	// シーケンス
	//--------------------------------------------------------------------------
	/**
	 * シーケンス数の取得
	 * @return シーケンス数
	 */
	virtual int getSequenceCount() const{
		const AnimationData* data = getAnimationData();
		if(data == NULL){ return 0; }
		return data->getSequenceCount();
	}

	/**
	 * シーケンスの設定
	 * @param sequence 設定するシーケンス
	 * @param time 設定する時間
	 */
	virtual void setSequence(int sequence, float time = 0.f){
		Assert(sequence >= 0);
		Assert((sequence == 0) || (sequence < getSequenceCount()));
		sequence_ = sequence;
		setTime(time);
	}

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

	//--------------------------------------------------------------------------
	// 時間
	//--------------------------------------------------------------------------
	/**
	 * 時間の設定
	 * @param time 設定する時間
	 */
	virtual void setTime(float time){ time_ = time; }

	/**
	 * 時間の取得
	 * @return 時間
	 */
	virtual float getTime() const{ return time_; }

	//--------------------------------------------------------------------------
	// アニメーション
	//--------------------------------------------------------------------------
	/**
	 * 終了しているか
	 * @return 終了していればtrue
	 */
	virtual bool isFinished() const{
		if(getAnimationData() == NULL){ return true; }
		// ループアニメーションはシーケンスが一周すれば終了フラグが立つ
		return (getTime() >= getLength());
	}

	/**
	 * 長さの取得
	 * @return 長さ
	 */
	virtual float getLength() const{
		const AnimationData* data = getAnimationData();
		if(data == NULL){ return 0.f; }
		return data->getLength(getSequence());
	}

	/**
	 * ループしているか
	 * @return ループしていればtrue
	 */
	virtual bool isLooped() const{
		const AnimationData* data = getAnimationData();
		if(data == NULL){ return false; }
		return data->isLooped(getSequence());
	}

	//--------------------------------------------------------------------------
	// RTTI
	//--------------------------------------------------------------------------
	/**
	 * オブジェクトアニメーションかどうか
	 * @return オブジェクトアニメーションならtrue
	 */
	virtual bool isObjectAnimation() const{ return true; }

	//--------------------------------------------------------------------------
protected:
	/**
	 * コンストラクタ
	 * @param name 名前
	 * @param manager アニメーションマネージャ
	 */
	ObjectAnimation(String name, AnimationManager* manager) :
		Animation(name, manager), sequence_(0), time_(0.f){}

	/**
	 * デストラクタ
	 */
	virtual ~ObjectAnimation(){}

	//--------------------------------------------------------------------------
	/**
	 * オブジェクトアニメーションの値コピー
	 * @param destination コピー対象
	 */
	virtual void copyObjectAnimationValue(
		ObjectAnimation* destination) const{
		destination->setEnabled(isEnabled());
		destination->setTargetName(getTargetName());
		destination->setSequence(getSequence());
		destination->setTime(getTime());
	}

private:
	// ターゲット名
	String targetName_;
	// シーケンス
	int sequence_;
	// 時間
	float time_;

};

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