//------------------------------------------------------------------------------
// 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 "Game/System/GameSystem.h"
// システム
#include "Game/Rendering/RenderingSystem.h"
#include "Game/Animation/AnimationSystem.h"
#include "Game/Collision/CollisionSystem.h"
#include "Game/Input/InputSystem.h"
#include "Game/Sound/SoundSystem.h"
#include "Player/System/PlayerSystem.h"
#include "Enemy/System/EnemySystem.h"
// タスク
#include "Game/System/GameTask.h"
#include "Stage/Spore/SporeStage.h"
#include "Title/TitleTask.h"
#include "Load/System/LoadTask.h"
// その他
#include "Core/Utility/Performance.h"

// インスタンス
GameSystem* GameSystem::instance_ = NULL;

//------------------------------------------------------------------------------
// 生成、破棄
//------------------------------------------------------------------------------
// コンストラクタ
GameSystem::GameSystem() : currentTask_(NULL), nextTask_(NULL){
	// インスタンスポインタ設定
	Assert(instance_ == NULL);
	instance_ = this;
	// 各システム生成
	renderingSystem_ = new RenderingSystem();
	animationSystem_ = new AnimationSystem();
	collisionSystem_ = new CollisionSystem();
	inputSystem_ = new InputSystem();
	soundSystem_ = new SoundSystem();
	playerSystem_ = new PlayerSystem();
	enemySystem_ = new EnemySystem();

	// タスクの生成
	sporeStage_ = new SporeStage();
	titleTask_ = new TitleTask();
	loadTask_ = new LoadTask();

	// カレントタスクのセットアップ
//	getSporeStage()->load();
	getTitleTask()->load();
	Assert(nextTask_ != NULL);
	currentTask_ = nextTask_;
	nextTask_ = NULL;
	currentTask_->initialize();
}
//------------------------------------------------------------------------------
// デストラクタ
GameSystem::~GameSystem(){
	// カレントタスクの後始末
	currentTask_->finalize();

	// タスクの破棄
	SafeDelete(loadTask_);
	SafeDelete(titleTask_);
	SafeDelete(sporeStage_);

	// 各システム破棄
	SafeDelete(enemySystem_);
	SafeDelete(playerSystem_);
	SafeDelete(soundSystem_);
	SafeDelete(inputSystem_);
	SafeDelete(collisionSystem_);
	SafeDelete(animationSystem_);
	SafeDelete(renderingSystem_)
	// インスタンスポインタ後始末
	Assert(instance_ == this);
	instance_ = NULL;
}
//------------------------------------------------------------------------------
// タスク
//------------------------------------------------------------------------------
// 次のタスク設定
void GameSystem::setNextTask(GameTask* nextTask){
	Assert((nextTask != NULL) && (nextTask_ == NULL));
	nextTask_ = nextTask;
}
//------------------------------------------------------------------------------
// 実行
//------------------------------------------------------------------------------
// 実行
void GameSystem::run(){
	// システム入力
	systemInput();

	// タスクの切り替え
	while(nextTask_ != NULL){
		currentTask_->finalize();
		currentTask_ = nextTask_;
		nextTask_ = NULL;
		// initializeで次のタスクを設定することが可能
		currentTask_->initialize();
	}

	// タスクの実行
	Assert(currentTask_ != NULL);
	currentTask_->run();
}
//------------------------------------------------------------------------------
// システム入力
void GameSystem::systemInput(){
	Keyboard* keyboard = LampInput::getKeyboard();

	// Alt+Enterキーでフルスクリーン切替
	if(keyboard->down(Keyboard::keyEnter) &&
		(keyboard->pressed(Keyboard::keyLeftAlt) ||
		keyboard->pressed(Keyboard::keyRightAlt))){
		GraphicsDevice::getInstance()->toggleFullscreen();
	}

	// Escキーで終了
	if(keyboard->down(Keyboard::keyEscape)){ PostQuitMessage(0); }

#ifdef _DEBUG
	// F9キーでデバイス再構築
	if(keyboard->down(Keyboard::keyF9)){
		GraphicsDevice::getInstance()->rebuild();
	}
#endif
}
//------------------------------------------------------------------------------
// 描画準備
//------------------------------------------------------------------------------
// 描画準備
void GameSystem::renderSetup(){
	// タスクの描画準備
	Assert(currentTask_ != NULL);
	currentTask_->renderSetup();
}
//------------------------------------------------------------------------------
// 描画
//------------------------------------------------------------------------------
// 描画
void GameSystem::render(){
	// タスクの描画
	Assert(currentTask_ != NULL);
	currentTask_->render();

	// FPSの表示
	DebugHUD::setTopRight(Performance::getFPSString());
	if(Performance::getDrawFPS() < 20.f){
		DebugHUD::setTopRightColor(Color4c::red);
	}else if(Performance::getDrawFPS() < 55.f){
		DebugHUD::setTopRightColor(Color4c::yellow);
	}else{
		DebugHUD::setTopRightColor(Color4c::white);
	}
}
//------------------------------------------------------------------------------
