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

#include "Game/System/SystemReference.h"

class Stage;
class PlayerState;

//------------------------------------------------------------------------------
/**
 * プレイヤ
 */
class Player : public SystemReference{
friend class PlayerSystem;
friend class PlayerState;
public:
	//--------------------------------------------------------------------------
	/// プレイヤータイプ
	enum Type{
		typeAnzu
	};

	//--------------------------------------------------------------------------
	/**
	 * 状態の設定
	 * @param state 状態
	 */
	virtual void setState(PlayerState* state);

	/**
	 * 状態の取得
	 * @return 状態
	 */
	virtual PlayerState* getState() const{ return state_; }

	//--------------------------------------------------------------------------
	/**
	 * ダメージ
	 * @param damageDirection ダメージ方向
	 * @param damegeValue ダメージ値
	 */
	virtual void damage(const Vector3& damageDirection, int damageValue){
		damageDirection_ = damageDirection;
		damageValue_ = damageValue;
	}

	/**
	 * ダメージコリジョンの取得
	 * @return ダメージコリジョン
	 */
	virtual StaticSphereCollision* getDamageCollision(){
		return damageCollision_;
	}

	//--------------------------------------------------------------------------
	// メンバの取得
	//--------------------------------------------------------------------------
	/**
	 * 位置の取得
	 * @return 位置
	 */
	virtual const Vector3& getPosition() const{ return position_; }

	/**
	 * 回転の取得
	 * @return 回転
	 */
	virtual const Vector3& getRotation(){ return rotation_; }

	/**
	 * 向きの取得
	 * @return 向き
	 */
	virtual const Vector3& getDirection(){ return direction_; }

	/**
	 * 速度の取得
	 * @return 速度
	 */
	virtual const Vector3& getVelocity() const{ return velocity_; }

	/**
	 * 空中フラグの取得
	 * @return 空中ならtrue
	 */
	virtual bool isAerial() const{ return isAerial_; }

	//--------------------------------------------------------------------------
	// ライフ
	//--------------------------------------------------------------------------
	/**
	 * 命の取得
	 * @return 命
	 */
	virtual int getLife() const{ return life_; }

	/**
	 * 体力の取得
	 * @return 体力
	 */
	virtual int getHealth() const{ return health_; }

	/**
	 * 死んでいるか
	 * @return 死んでいるならtrue
	 */
	virtual bool isDeath() const{ return (health_ == 0); }

	/**
	 * 全滅しているか
	 * @return 全滅していればtrue
	 */
	virtual bool isAnnihilated() const{ return (isDeath() && (life_ == 0)); }

protected:
	//--------------------------------------------------------------------------
	// 生成、破棄
	//--------------------------------------------------------------------------
	/**
	 * コンストラクタ
	 */
	Player();

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

	//--------------------------------------------------------------------------
	// 初期化
	//--------------------------------------------------------------------------
	/**
	 * モデルの初期化
	 * @param name 名前
	 * @return コピーされたノード
	 */
	virtual SceneNode* initializeModel(const String& name);

	/**
	 * アニメーションの初期化
	 * @param name 名前
	 * @return コピーされたアニメーション
	 */
	virtual Animation* initializeAnimation(const String& name);

	/**
	 * コリジョンの初期化
	 * @param name 名前
	 * @param landSize 地形サイズ
	 * @param damageSize ダメージサイズ
	 * @return コリジョンノード
	 */
	virtual CollisionNode* initializeCollision(const String& name,
		float landSize, float damageSize);

	//--------------------------------------------------------------------------
	// 実行
	//--------------------------------------------------------------------------
	/**
	 * 実行
	 */
	virtual void run();

	//--------------------------------------------------------------------------
	// シーンノード
	//--------------------------------------------------------------------------
	/**
	 * シーンノードの取得
	 * @return シーンノード
	 */
	virtual SceneNode* getSceneNode(){ return sceneNode_; }

	//--------------------------------------------------------------------------
	// モデル
	//--------------------------------------------------------------------------
	/**
	 * モデルの取得
	 * @return モデル
	 */
	virtual CharacterModel* getModel(){ return model_; }

	/**
	 * 右手ボーンの取得
	 * @return 右手ボーン
	 */
	virtual Bone* getRightHandBone(){ return rightHandBone_; }

	/**
	 * 体ボーンの取得
	 * @return 体ボーン
	 */
	virtual Bone* getBodyBone(){ return bodyBone_; }

	//--------------------------------------------------------------------------
	// アニメーション
	//--------------------------------------------------------------------------
	/**
	 * アニメーションの取得
	 * @return アニメーション
	 */
	virtual Animation* getAnimation(){ return animation_; }

	//--------------------------------------------------------------------------
	// コリジョン
	//--------------------------------------------------------------------------
	/**
	 * コリジョンノードの取得
	 * @return コリジョンノード
	 */
	virtual CollisionNode* getCollisionNode(){ return collisionNode_; }

	/**
	 * 地形コリジョンの取得
	 * @return 地形コリジョン
	 */
	virtual StaticSphereCollision* getLandCollision(){ return landCollision_; }

	/**
	 * 攻撃コリジョンの取得
	 * @return 攻撃コリジョン
	 */
	virtual StaticSphereCollision* getAttackCollision(){
		return attackCollision_;
	}

	//--------------------------------------------------------------------------
	// メンバの設定
	//--------------------------------------------------------------------------
	/**
	 * 位置の設定
	 * @param position 位置
	 */
	virtual void setPosition(const Vector3& position){ position_ = position; }

	/**
	 * 向きの設定
	 * @param direction 向き
	 */
	virtual void setDirection(const Vector3& direction);

	/**
	 * 速度の設定
	 * @param velocity 速度
	 */
	virtual void setVelocity(const Vector3& velocity){ velocity_ = velocity; }

	/**
	 * 空中フラグの設定
	 * @param isAerial 空中ならtrue
	 */
	virtual void setAerial(bool isAerial){ isAerial_ = isAerial; }

	//--------------------------------------------------------------------------
	// ライフ
	//--------------------------------------------------------------------------
	/**
	 * 命の設定
	 * @param life 命
	 */
	virtual void setLife(int life){
		life_ = life;
		if(life_ < 0){ life_ = 0; }
		else if(life_ > 4){ life_ = 4; }
	}

	/**
	 * 体力の設定
	 * @param health 体力
	 */
	virtual void setHealth(int health){
		health_ = health;
		if(health_ < 0){ health_ = 0; }
		else if(health_ > 500){ health_ = 500; }
	}

	//--------------------------------------------------------------------------
	// ダメージ
	//--------------------------------------------------------------------------
	/**
	 * ダメージ方向の取得
	 * @return ダメージ方向
	 */
	virtual const Vector3& getDamageDirection() const{
		return damageDirection_;
	}

	/**
	 * ダメージ値の取得
	 * @return ダメージ値
	 */
	virtual int getDamageValue() const{ return damageValue_; }

	/**
	 * ダメージのクリア
	 */
	virtual void clearDamage(){
		damageDirection_ = Vector3::zero;
		damageValue_ = 0;
	}

	/**
	 * 無敵カウンタの取得
	 * @return 無敵カウンタ
	 */
	virtual int getMatchlessCounter() const{ return matchlessCounter_; }

	/**
	 * 無敵カウンタの設定
	 * @param matchlessCounter 無敵カウンタ
	 */
	virtual void setMatchlessCounter(int matchlessCounter){
		Assert(matchlessCounter >= 0);
		matchlessCounter_ = matchlessCounter;
	}

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

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

	//--------------------------------------------------------------------------
	// メンバ
	//--------------------------------------------------------------------------
	// ステージ
	Stage* stage_;
	// シーンノード
	SceneNode* sceneNode_;
	// モデル
	CharacterModel* model_;
	// 右手ボーン
	Bone* rightHandBone_;
	// 体ボーン
	Bone* bodyBone_;
	// アニメーション
	Animation* animation_;
	// コリジョンノード
	CollisionNode* collisionNode_;
	// 地形コリジョン
	StaticSphereCollision* landCollision_;
	// ダメージコリジョン
	StaticSphereCollision* damageCollision_;
	// 攻撃コリジョン
	StaticSphereCollision* attackCollision_;

	// 状態
	PlayerState* state_;
	// 次の状態
	PlayerState* nextState_;
	// 位置
	Vector3 position_;
	// 回転
	Vector3 rotation_;
	// 向き
	Vector3 direction_;
	// 速度
	Vector3 velocity_;
	// 空中フラグ
	bool isAerial_;

	// 命
	int life_;
	// 体力
	int health_;

	// ダメージ方向
	Vector3 damageDirection_;
	// ダメージ値
	int damageValue_;
	// 無敵カウンタ
	int matchlessCounter_;
};

//------------------------------------------------------------------------------
#endif // End of PLAYER_H_
//------------------------------------------------------------------------------
