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

#include <Animation/System/ObjectAnimation.h>
#include <Animation/Model/CharacterModelAnimationData.h>

namespace Lamp{

class CharacterModel;
class Bone;

//------------------------------------------------------------------------------
/**
 * キャラクタモデルアニメーション
 */
class CharacterModelAnimation : public ObjectAnimation{
friend class AnimationManager;
public:
	//--------------------------------------------------------------------------
	// アニメーションデータ
	//--------------------------------------------------------------------------
	/**
	 * アニメーションデータの取得
	 * @return アニメーションデータ
	 */
	virtual AnimationData* getAnimationData(){ return animationData_; }

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

	//--------------------------------------------------------------------------
	// キャラクタモデルアニメーションデータ
	//--------------------------------------------------------------------------
	/**
	 * キャラクタモデルアニメーションデータの設定
	 * @param animationData キャラクタモデルアニメーションデータ
	 */
	virtual void setCharacterModelAnimationData(
		CharacterModelAnimationData* animationData){
		if(animationData_ != NULL){ animationData_->removeReference(); }
		animationData_ = animationData;
		if(animationData_ != NULL){ animationData_->addReference(); }
	}

	/**
	 * キャラクタモデルアニメーションデータの取得
	 */
	virtual CharacterModelAnimationData* getCharacterModelAnimationData(){
		return animationData_;
	}

	/**
	 * キャラクタモデルアニメーションデータの取得
	 */
	virtual const CharacterModelAnimationData*
		getCharacterModelAnimationData() const{
		return animationData_;
	}

	//--------------------------------------------------------------------------
	// バインド
	//--------------------------------------------------------------------------
	/**
	 * バインド
	 * @param scene バインド対象シーン
	 * @return 成功すればtrue
	 */
	virtual bool bind(Scene* scene);

	/**
	 * バインド
	 * @param model バインド対象キャラクタモデル
	 * @return 成功すればtrue
	 */
	virtual bool bind(CharacterModel* model);

	/**
	 * バインド解除
	 */
	virtual void unbind(){
		target_ = NULL;
		for(int i = 0; i < boneCount_; i++){ targetBones_[i] = NULL; }
	}

	/**
	 * ターゲットの取得
	 * @return ターゲット
	 */
	virtual CharacterModel* getTarget() const{ return target_; }

	/**
	 * ターゲットボーンの取得
	 * @param index ターゲットボーンのインデックス
	 */
	virtual Bone* getTargetBone(int index) const{
		Assert(index >= 0);
		Assert(index < boneCount_);
		return targetBones_[index];
	}

	//--------------------------------------------------------------------------
	// ボーン
	//--------------------------------------------------------------------------
	/**
	 * ボーン数の設定
	 * @param boneCount ボーン数
	 */
	virtual void setBoneCount(int boneCount){
		boneCount_ = boneCount;
		SafeArrayDelete(targetBones_);
		SafeArrayDelete(boneNames_);
		if(boneCount_ != 0){
			boneNames_ = new String[boneCount_];
			targetBones_ = new Bone*[boneCount_];
			for(int i = 0; i < boneCount_; i++){ targetBones_[i] = NULL; }
		}
	}

	/**
	 * ボーン数の取得
	 * @return ボーン数
	 */
	virtual int getBoneCount() const{ return boneCount_; }

	//--------------------------------------------------------------------------
	/**
	 * ボーン名の設定
	 * @param index ボーンのインデックス
	 * @param boneName ボーン名
	 */
	virtual void setBoneName(int index, const String& boneName){
		Assert(index >= 0);
		Assert(index < boneCount_);
		boneNames_[index] = boneName;
	}

	/**
	 * ボーン名の取得
	 * @param index ボーンのインデックス
	 * @return ボーン名
	 */
	virtual const String& getBoneName(int index) const{
		Assert(index >= 0);
		Assert(index < boneCount_);
		return boneNames_[index];
	}

	//--------------------------------------------------------------------------
	// アニメーション
	//--------------------------------------------------------------------------
	/**
	 * アニメーション
	 * @param deltaTime デルタタイム
	 * @param mask アニメーションマスク
	 * @return アニメーションが終了していればtrue
	 */
	virtual bool animate(float deltaTime, AnimationMask mask);

	//--------------------------------------------------------------------------
	// コピー
	//--------------------------------------------------------------------------
	/**
	 * コピー
	 * @param dataCopyMask データコピーマスク
	 * @return コピーされたアニメーション
	 */
	virtual Animation* copy(DataCopyMask dataCopyMask = copyNone) const{
		return copyCharacterModelAnimation(dataCopyMask);
	}

	/**
	 * キャラクタモデルアニメーションのコピー
	 * @param dataCopyMask データコピーマスク
	 * @return コピーされたアニメーション
	 */
	virtual CharacterModelAnimation* copyCharacterModelAnimation(
		DataCopyMask dataCopyMask = copyNone) const;

	//--------------------------------------------------------------------------
	// RTTI
	//--------------------------------------------------------------------------
	/**
	 * キャラクタモデルアニメーションかどうか
	 * @return キャラクタモデルアニメーションならtrue
	 */
	virtual bool isCharacterModelAnimation() const{ return true; }

	//--------------------------------------------------------------------------
protected:
	/**
	 * コンストラクタ
	 * @param name 名前
	 * @param manager アニメーションマネージャ
	 */
	CharacterModelAnimation(String name, AnimationManager* manager);

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

private:
	// アニメーションデータ
	CharacterModelAnimationData* animationData_;
	// ターゲット
	CharacterModel* target_;
	// ボーン数
	int boneCount_;
	// ボーン名
	String* boneNames_;
	// ターゲットボーン
	Bone** targetBones_;

};

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

