#include "Enemy.h"
#include "Command.h"
#include "CommandManager.h"
#include "List.h"
#include "Level.h"
#include "Weapon.h"
#include "Parser.h"

#include <iostream>

using namespace std;

Enemy::Enemy(List *enemyInfo, int x, int y)
:Person(enemyInfo, x, y),_brainWait(0),_brainTime(0),_brain(NONE),_pointValue(10),_script(NULL),_active(true),
_scriptWait(0),_scriptTime(0),_deathScript(NULL), _brainBurst(1), _brainBurstTime(0)
{
	_depth = 1;
	_type = ENEMY;

	load(enemyInfo);
}

Enemy::~Enemy()
{
	delete _script;
	delete _deathScript;
}

Object *Enemy::copy()
{
	Enemy *copy = new Enemy(*this);
	copy->_primaryWeapon = _primaryWeapon->copy(copy);
	if(_script)
		copy->_script = new List(_script);
	if(_deathScript)
		copy->_deathScript = new List(_deathScript);
	return copy;
}

void Enemy::load(List *enemyInfo, bool fromConstructor)
{
	if(!fromConstructor)
		Person::load(enemyInfo,fromConstructor);

	while(!enemyInfo->empty())
	{
		List * current = enemyInfo->firstList();

		if(current->firstString() == "brain")
		{
			string braintype = current->rest()->firstString();

			if(braintype == "jump")
				_brain = JUMP;

			else if(braintype == "followshootahead")
				_brain = FOLLOWSHOOTAHEAD;

			else if(braintype == "followshoot")
				_brain = FOLLOWSHOOT;

			else if(braintype == "sitandshoot")
				_brain = SITANDSHOOT;

			else if(braintype == "factoryboss")
				_brain = FACTORYBOSS;

			else if(braintype == "streetboss")
				_brain = STREETBOSS;

			else if(braintype == "runaway")
				_brain = RUNAWAY;

			else if(braintype == "none")
				_brain = NONE;
		}
		else if(current->firstString() == "brainWait") {
			_brainWait = current->rest()->firstInt();
			_brainTime = _brainWait;
		}
		else if(current->firstString() == "brainBurst")
		{
			_brainBurst = current->rest()->firstInt();
		}
		else if(current->firstString() == "scriptWait") {
			_scriptWait = current->rest()->firstInt();
			_scriptTime = _scriptWait;
		}
		else if(current->firstString() == "script") {
			_script = new List(current->rest()->firstList());
		}
		else if(current->firstString() == "deathScript") {
			_deathScript = new List(current->rest()->firstList());
		}
		else if(current->firstString() == "pointValue")
			_pointValue = current->rest()->firstInt();
		else if(current->firstString() == "active") {
			string abool = current->rest()->firstString();
			if(abool == "true")
				_active = true;
			else
				_active = false;
		}
		else if(current->firstString() == "boss")
			_type = BOSS;
		else if(current->firstString() == "this") {
			_script->findAndReplace("this",id());
		}

		enemyInfo = enemyInfo->rest();
	}
}

void Enemy::update()
{
	Person::update();

	if(_active) {
		_brainTime++;
		_scriptTime++;

		if(_brainTime >= _brainWait) {
			if(_brainBurstTime >= _brainBurst){
				_brainTime = 0;
				_brainBurstTime = 0;
			}
			_brainBurstTime ++;

			if( _brain == FOLLOWSHOOTAHEAD)
			{
				FollowPlayerInRangeCommand(this, 200).execute();
				//FIXME MAJK NUMBER
				ShootInRangeCommand(this, 300).execute();
			}

			else if( _brain == JUMP)
		//		JumpCommand(this, _xDirection).execute();
				;
			else if( _brain == FOLLOWSHOOT)
			{
				FollowPlayerInRangeCommand(this, 200).execute();
				AimCommand(this).execute();
				ShootInRangeCommand(this, 400).execute();
			}
			else if(_brain == SITANDSHOOT)
			{
				AimCommand(this).execute();
				ShootInRangeCommand(this, 400).execute();
			}
			else if(_brain == FACTORYBOSS)
			{
				if(!touchingBelow()) {
					AimCommand(this,DOWN).execute();
					ShootCommand(this).execute();
				} else {
					ShootInRangeCommand(this,1000).execute();
				}
			}
			else if(_brain == STREETBOSS)
			{
				if(touchingBelow())
				{
					ShootInRangeCommand(this,1000).execute();
				}
			}
	
			else if(_brain == RUNAWAY)
			{
				RunFromPlayerInRangeCommand(this, 350).execute();
			}
			else if(_brain == NONE)
				;

			}
		if(_scriptTime >= _scriptWait) {
			_scriptTime = 0;

			if(_script)
				CommandManager::instance()->startPlaying(_script);
		}
	}
}

void Enemy::die()
{
	if(_deathScript) {
		_state = DEAD;
		CommandManager::instance()->startPlaying(_deathScript);
		delete _deathScript;
		_deathScript = NULL;
		delete _script;
		_script = NULL;
		_brain = NONE;
		_xVelocity = 0;
		_yVelocity = 0;
		_invincible = true;
	}
	else {
		Person::die();
		Level::instance()->addScore(_pointValue);
		Level::instance()->addKill();
	}
}