//------------------------------------------------------------------------------
// 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 "Enemy/System/EnemySystem.h"
#include "Enemy/Gelaim/Gelaim.h"
#include "Enemy/Tanue/Tanue.h"
#include "Enemy/Azalinna/Azalinna.h"

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

//------------------------------------------------------------------------------
// 生成、破棄
//------------------------------------------------------------------------------
// コンストラクタ
EnemySystem::EnemySystem() : enemyNode_(NULL), random_(123456),
	killCount_(0), gelaimCount_(0), tanueCount_(0), azalinnaCount_(0){
	// インスタンスポインタ設定
	Assert(instance_ == NULL);
	instance_ = this;
}
//------------------------------------------------------------------------------
// デストラクタ
EnemySystem::~EnemySystem(){
	Assert(getCount() == 0);

	// インスタンスポインタ後始末
	Assert(instance_ == this);
	instance_ = NULL;
}
//------------------------------------------------------------------------------
// ロード
//------------------------------------------------------------------------------
// ロード
void EnemySystem::load(Enemy::Type type){
	// 敵ノードが無ければ作成
	if(enemyNode_ == NULL){
		// 敵ノードはルートノードに連結されていない
		enemyNode_ =
			getScene()->getSceneNodeManager()->createSceneNode("EnemyNode");
	}
	// 敵のロード
	if(type == Enemy::typeGelaim){
		Gelaim::load(enemyNode_);
	}else if(type == Enemy::typeTanue){
		Tanue::load(enemyNode_);
	}else if(type == Enemy::typeAzalinna){
		Azalinna::load(enemyNode_);
	}else{
		ErrorOut("EnemySystem::load() 対応していないタイプです %d", type);
	}
}
//------------------------------------------------------------------------------
// 実行
void EnemySystem::run(){

if(LampInput::getKeyboard()->down(Keyboard::keyR)){ killCount_ += 50; }
if(LampInput::getKeyboard()->down(Keyboard::keyT)){
	int count = getCount();
	for(int i = 0; i < count; i++){ get(i)->damage(Vector3::unitY, killCount_ + 100); }
}

	// 敵の生成
	generate();

	// 実行
	int count = getCount();
	for(int i = 0; i < count; i++){ get(i)->run(); }

	for(int i = count - 1; i >= 0; i--){
		Enemy* enemy = get(i);
		if(enemy->isAnnihilated()){
			destroy(enemy);
			killCount_++;
		}
	}
}
//------------------------------------------------------------------------------
// 敵の生成
void EnemySystem::generate(){
	int count = getCount();
	Enemy* newEnemy = NULL;
	int maxEnemyCount = (killCount_ / 5);

	// 最高100匹
	if(maxEnemyCount > 100){ maxEnemyCount = 100; }

	if(count <= maxEnemyCount){
		int rate = random_.get() % 100;
		if(rate < 40){
			if(gelaimCount_ <= (maxEnemyCount / 2)){
				newEnemy = create(Enemy::typeGelaim, 20 + (killCount_ / 2));
			}else{
				newEnemy = create(Enemy::typeTanue, 80 + (killCount_));
			}
		}else if(rate < 70){
			if(azalinnaCount_ <= (maxEnemyCount / 2)){
				newEnemy = create(Enemy::typeAzalinna, 50 + (killCount_));
			}else{
				newEnemy = create(Enemy::typeTanue, 80 + (killCount_));
			}
		}else{
			if(tanueCount_ <= (maxEnemyCount / 2)){
				newEnemy = create(Enemy::typeTanue, 80 + (killCount_));
			}else{
				newEnemy = create(Enemy::typeAzalinna, 50 + (killCount_));
			}
		}
	}
	if(newEnemy != NULL){
		float range = 50.f + killCount_;
		if(range >= 120.f){ range = 120.f; }
		newEnemy->setPosition(Vector3(random_.getSignedFloat() * range,
			50.f, random_.getSignedFloat() * range));
	}
}
//------------------------------------------------------------------------------
// 敵
//------------------------------------------------------------------------------
// 敵の作成
Enemy* EnemySystem::create(Enemy::Type type, int health){
	Enemy* enemy = NULL;
	if(type == Enemy::typeGelaim){
		enemy = new Gelaim(health, random_.get());
		gelaimCount_++;
	}else if(type == Enemy::typeTanue){
		enemy = new Tanue(health, random_.get());
		tanueCount_++;
	}else if(type == Enemy::typeAzalinna){
		enemy = new Azalinna(health, random_.get());
		azalinnaCount_++;
	}else{
		ErrorOut("EnemySystem::load() 対応していないタイプです %d", type);
	}
	enemys_.add(enemy);
	return enemy;
}
//------------------------------------------------------------------------------
// 敵の破棄
void EnemySystem::destroy(Enemy* enemy){
	int result = enemys_.removeByValue(enemy);
	Assert(result != -1);
	if(enemy->isGelaim()){ gelaimCount_--; }
	else if(enemy->isTanue()){ tanueCount_--; }
	else if(enemy->isAzalinna()){ azalinnaCount_--; }
	delete enemy;
}
//------------------------------------------------------------------------------
// 敵のクリア
void EnemySystem::clear(){
	for(int i = getCount() - 1; i >= 0; i--){ delete get(i); }
	enemys_.clear();
	// 敵ノードの破棄
	if(enemyNode_ != NULL){
		SceneNode::recursiveDestroy(enemyNode_);
		enemyNode_ = NULL;
	}
	killCount_ = 0;
	gelaimCount_ = tanueCount_ = azalinnaCount_ = 0;
}
//------------------------------------------------------------------------------
