//------------------------------------------------------------------------------
// 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
 */

#include "Core/Utility/stdafx.h"
#include "Stage/Spore/SporeStage.h"
#include "Game/System/GameSystem.h"
#include "Game/Rendering/RenderingSystem.h"
#include "Game/Animation/AnimationSystem.h"
#include "Game/Collision/CollisionSystem.h"
#include "Game/Sound/SoundSystem.h"
#include "Load/System/LoadTask.h"
#include "Player/System/PlayerSystem.h"
#include "Player/System/Player.h"
#include "Player/System/PlayerState.h"
#include "Enemy/System/EnemySystem.h"
#include "Enemy/System/Enemy.h"
#include "Game/Input/GamePad.h"
#include "Title/TitleTask.h"

//------------------------------------------------------------------------------
// 生成、破棄
//------------------------------------------------------------------------------
// コンストラクタ
SporeStage::SporeStage() : Stage(),
	sceneNode_(NULL), lightNode_(NULL), collisionNode_(NULL),
	cameraTargetPosition_(Vector3::zero), cameraTargetRotation_(Vector3::zero){
}
//------------------------------------------------------------------------------
// デストラクタ
SporeStage::~SporeStage(){
}
//------------------------------------------------------------------------------
// ロード
//------------------------------------------------------------------------------
// ロード
void SporeStage::load(){
	// ロードタスクの構築
	LoadTask* loadTask = getGameSystem()->getLoadTask();
	loadTask->setNextTask(this);

	// プレイヤのロード
	getPlayerSystem()->load(Player::typeAnzu);

	// 敵のロード
	getEnemySystem()->load(Enemy::typeGelaim);
	getEnemySystem()->load(Enemy::typeTanue);
	getEnemySystem()->load(Enemy::typeAzalinna);

	// サウンドリストのロード
	loadTask->requestSoundList(
		"SporeStage.txt", getSoundSystem()->getStageSound());

	// シーンのロード
	Assert(sceneNode_ == NULL);
	sceneNode_ =
		getScene()->getSceneNodeManager()->createSceneNode("SporeStage");
	getScene()->getRootNode()->addSceneNode(sceneNode_);
	loadTask->requestScene(
		"Media/Stage/Spore/SporeStage.bsn", getScene(), sceneNode_);

	// コリジョンのロード
	Assert(collisionNode_ == NULL);
	collisionNode_ = getCollisionScene()->createCollisionNode("SporeStage");
	getCollisionScene()->getRootNode()->addChild(collisionNode_);
	loadTask->requestCollision("Media/Stage/Spore/SporeStageCollision.tcl",
		getCollisionScene(), collisionNode_);

	// ロードタスクの登録
	getGameSystem()->setNextTask(loadTask);
}
//------------------------------------------------------------------------------
// 初期化、後始末
//------------------------------------------------------------------------------
// 初期化
void SporeStage::initialize(){
	// フラグのクリア
	debugCamera_ = false;
	drawCollision_ = false;
//drawCollision_ = true;

	// プレイヤの作成
	getPlayerSystem()->create(Player::typeAnzu);

	// ライトノード
	Assert(lightNode_ == NULL);
	lightNode_ = getScene()->getSceneNodeManager()->createSceneNode(
		"CameraLightNode");
	getScene()->getRootNode()->addSceneNode(lightNode_);
	PointLight* cameraLight = getScene()->getLightManager()->createPointLight(
		"CameraLight");
	lightNode_->addSceneLeaf(cameraLight);
	cameraLight->setColor(Color3f(800.f, 600.f, 800.f));
	cameraLight->setAttenuation(0.f, 0.f, 1.f);
	cameraLight->setRange(150.f);
	cameraLight->setLightMask(3);

	// フォグ設定
	getScene()->getFog()->setMode(Fog::modeLinear);
	getScene()->getFog()->setEnabled(true);
	getScene()->getFog()->setNear(100.f);
	getScene()->getFog()->setFar(500.f);
	getScene()->getFog()->setColor(Color4c(192, 128,  255, 0));

	// HUDの準備
	gauge_[0] = new Sprite();
	gauge_[0]->loadPicture("Media/HUD/Gauge.tga");
	gauge_[0]->setAlign(Sprite::alignBottomLeft);
	gauge_[0]->setRectangle(128.f, 0.f, 512.f, 128.f);

	gauge_[1] = new Sprite();
	gauge_[1]->loadPicture("Media/HUD/Face.tga");
	gauge_[1]->setAlign(Sprite::alignBottomLeft);
	gauge_[1]->setRectangle(0.f, 0.f, 128.f, 128.f);
	gauge_[1]->setAnimation(DimensionI(2, 2), 0);

	gauge_[2] = new Sprite();
	gauge_[2]->loadPicture("Media/HUD/Health.tga");
	gauge_[2]->setAlign(Sprite::alignBottomLeft);
	gauge_[2]->setRectangle(104.f, 0.f, 512.f, 32.f);

	life_[0] = new Sprite();
	life_[0]->loadPicture("Media/HUD/Life.tga");
	life_[0]->setAlign(Sprite::alignBottomLeft);
	life_[0]->setRectangle(496.f, -46.f, 32.f, 16.f);
	life_[1] = new Sprite(*life_[0]);
	life_[1]->setRectangle(536.f, -46.f, 32.f, 16.f);
	life_[2] = new Sprite(*life_[0]);
	life_[2]->setRectangle(576.f, -46.f, 32.f, 16.f);

	score_[0] = new Sprite();
	score_[0]->loadPicture("Media/HUD/Score.tga");
	score_[0]->setAlign(Sprite::alignBottomLeft);
	score_[0]->setRectangle(384.f, -38.f, 32.f, 32.f);
	score_[0]->setAnimation(DimensionI(4, 4), 0);
	score_[1] = new Sprite(*score_[0]);
	score_[1]->setRectangle(384.f - 36.f, -38.f, 32.f, 32.f);
	score_[2] = new Sprite(*score_[0]);
	score_[2]->setRectangle(384.f - 72.f, -38.f, 32.f, 32.f);
	score_[3] = new Sprite(*score_[0]);
	score_[3]->setRectangle(384.f - 108.f, -38.f, 32.f, 32.f);


	gameOver_ = new Sprite();
	gameOver_->loadPicture("Media/HUD/GameOver.tga");
	gameOver_->setAlign(Sprite::alignCenter);
	gameOver_->setRectangle(0.f, 0.f, 512.f, 128.f);

	// BGMの再生
	bgm_ = getSoundManager()->createStreamSound("Media/BGM/Kinoko.ogg");
	bgm_->applyCommentOption();
	bgm_->play();

	// ゲームオーバカウンタ初期化
	gameOverCounter_ = 480;
}
//------------------------------------------------------------------------------
// 後始末
void SporeStage::finalize(){
	// BGMの停止
	bgm_->stop();
	getSoundManager()->destroy(bgm_);

	// HUDの後始末
	SafeDelete(gameOver_);
	for(int i = 3; i >= 0; i--){ SafeDelete(score_[i]); }
	for(int i = 2; i >= 0; i--){ SafeDelete(life_[i]); }
	for(int i = 2; i >= 0; i--){ SafeDelete(gauge_[i]); }
	
	// サウンドリストのアンロード
	getSoundSystem()->unloadStageSound();

	// 敵のクリア
	getEnemySystem()->clear();
	// プレイヤのクリア
	getPlayerSystem()->clear();

	// コリジョンの破棄
	CollisionNode::recursiveDestroy(collisionNode_);
	collisionNode_ = NULL;

	// アニメーションのクリア、部分クリアを行いたい
	getAnimationSystem()->clear();

	// ライトノードの破棄
	SceneNode::recursiveDestroy(lightNode_);
	lightNode_ = NULL;
	// シーンの破棄
	SceneNode::recursiveDestroy(sceneNode_);
	sceneNode_ = NULL;

}
//------------------------------------------------------------------------------
// 実行
//------------------------------------------------------------------------------
// 実行
void SporeStage::run(){
#ifdef _DEBUG
	// Vでデバッグカメラ切り替え
	if(getKeyboard()->down(Keyboard::keyV)){ debugCamera_ = !debugCamera_; }

	// Cでコリジョン表示切替
	if(getKeyboard()->down(Keyboard::keyC)){ drawCollision_ = !drawCollision_; }

	if(debugCamera_){
		// デバッグカメラのコントロール
		getRenderingSystem()->runCameraController();
	}else{
		// カメラ制御
		cameraControl();
	}
	// Rでダメージ
	if(getKeyboard()->down(Keyboard::keyR)){
		getPlayerSystem()->get(0)->damage(Vector3(-1.f, 1.f, 0.f), 100);

	}
#else
	// カメラ制御
	cameraControl();
#endif

	// コリジョンのトラバース
	getCollisionSystem()->traverse();

	// プレイヤ実行
	getPlayerSystem()->run();
	// 敵実行
	getEnemySystem()->run();

	// ゲームオーバー
	if(getPlayerSystem()->get(0)->isAnnihilated()){
		if(gameOverCounter_ == 480){ bgm_->fade(2000, 1.f, 0.f); }
		if(gameOverCounter_ == 360){
			bgm_->stop();
			getSoundSystem()->play("GameOver");
		}
		gameOverCounter_--;
		if(gameOverCounter_ == 0){
			getGameSystem()->getTitleTask()->load();
		}
	}
}
//------------------------------------------------------------------------------
// カメラ制御
void SporeStage::cameraControl(){
	Camera* camera = getRenderingSystem()->getCamera();
	// カメラの対象位置
	Vector3 playerPosition = getPlayerSystem()->get(0)->getPosition();
	Vector3 playerRotation = getPlayerSystem()->get(0)->getRotation();
	Vector3 lookAtPosition = playerPosition;
	lookAtPosition.y += 10.f;

	GamePad* pad = getGamePad();
	if(pad != NULL){
		if(pad->buttonDown(GamePad::buttonL1) ||
			pad->buttonDown(GamePad::buttonL2) ||
			pad->buttonDown(GamePad::buttonR1) ||
			pad->buttonDown(GamePad::buttonR2)){
			cameraTargetRotation_ = playerRotation;
		}
	}
	if((getMouse()->buttonDown(2) ||
		getKeyboard()->down(Keyboard::keyL) ||
		getKeyboard()->down(Keyboard::keyZ))){
		cameraTargetRotation_ = playerRotation;
	}

	// カメラ位置
	Vector3 cameraDistance(0.f, 30.f, -50.f);
	Matrix33 matrix;
	matrix.setRotationXYZ(cameraTargetRotation_);
	cameraTargetPosition_ = playerPosition + matrix * cameraDistance;
	Vector3 cameraPosition = camera->getPosition();
	cameraPosition = cameraTargetPosition_ * 0.1f + cameraPosition * 0.9f;
	camera->setLookAt(cameraPosition, lookAtPosition, Vector3::unitY);

	// ライト位置の設定
	Vector3 lightPosition = lookAtPosition * 0.7f + cameraPosition * 0.3f;
	lightPosition.y += 10.f;
	lightNode_->setTranslation(lightPosition);

}
//------------------------------------------------------------------------------
// 描画準備
//------------------------------------------------------------------------------
// 描画準備
void SporeStage::renderSetup(){
	// シーンのトラバース
	getRenderingSystem()->traverse();

	// レンダリング準備
	getRenderingSystem()->renderingSetup();

	// コリジョンの描画準備
	if(drawCollision_){
		collisionNode_->setEnabled(false);
		collisionNode_->traverse();
		getCollisionSystem()->renderingSetup();
		collisionNode_->setEnabled(true);
	}

	//--------------------------------------------------------------------------
	// HUDの描画
	Player* player = getPlayerSystem()->get(0);
	SpriteRenderer* spriteRenderer = getRenderingSystem()->getSpriteRenderer();

	// ゲームオーバー表示
	if(player->isAnnihilated()){ spriteRenderer->request(gameOver_); }

	// ゲージ表示
	spriteRenderer->request(gauge_[0]);

	// 顔表示
	PlayerState* playerState = player->getState();
	if(playerState->isDeathState()){
		gauge_[1]->setAnimation(DimensionI(2, 2), 3);
	}else if(playerState->isDamageState()){
		gauge_[1]->setAnimation(DimensionI(2, 2), 2);
	}else{
		gauge_[1]->setAnimation(DimensionI(2, 2), 0);
	}
	spriteRenderer->request(gauge_[1]);

	// 体力表示
	float healthRate = player->getHealth() / 500.f;
	gauge_[2]->setRectangle(104.f, 0.f, 11.f + healthRate * 500.f, 32.f);
	gauge_[2]->setImageRectangle(0.f, 0.f,
		(11.f / 512.f) + (500.f / 512.f) * healthRate, 1.f);
	spriteRenderer->request(gauge_[2]);

	// ライフ表示
	int life = player->getLife();
	for(int i = 0; i < life; i++){ spriteRenderer->request(life_[i]); }

	// スコア表示
	int score = getEnemySystem()->getKillCount();
	score_[0]->setAnimation(DimensionI(4, 4), (score % 10));
	spriteRenderer->request(score_[0]);
	if(score >= 10){
		score_[1]->setAnimation(DimensionI(4, 4), ((score / 10) % 10));
		spriteRenderer->request(score_[1]);
	}
	if(score >= 100){
		score_[2]->setAnimation(DimensionI(4, 4), ((score / 100) % 10));
		spriteRenderer->request(score_[2]);
	}
	if(score >= 1000){
		score_[3]->setAnimation(DimensionI(4, 4), ((score / 1000) % 10));
		spriteRenderer->request(score_[3]);
	}

}
//------------------------------------------------------------------------------
// 描画
//------------------------------------------------------------------------------
// 描画
void SporeStage::render(){
	// 背景クリア
	getRenderingSystem()->clearBackground();

	// レンダリング
	getRenderingSystem()->rendering();

	// コリジョンのレンダリング
	if(drawCollision_){ getCollisionSystem()->rendering(); }

}
//------------------------------------------------------------------------------
