#include "Zombie.h"

#include "../../item/Item.h"
#include "../../level/Level.h"
#include "../../../util/Mth.h"
//#include "../MobType.h"
#include "../ai/goal/GoalSelector.h"
#include "../ai/control/JumpControl.h"
#include "../ai/goal/RandomStrollGoal.h"
#include "../ai/goal/MeleeAttackGoal.h"
#include "../ai/goal/target/NearestAttackableTargetGoal.h"
#include "../ai/goal/target/HurtByTargetGoal.h"
#include "../ai/goal/BreakDoorGoal.h"

Zombie::Zombie( Level* level )
:	super(level),
	fireCheckTick(0),
	_useNewAi(false)
{
	entityRendererId = ER_ZOMBIE_RENDERER;
	this->textureName = "mob/zombie.png";
	//pathfinderMask |= CAN_OPEN_DOORS;
	//navigation->canOpenDoors = true;

	runSpeed = 0.5f;
	attackDamage = 4;

	targetSelector = new GoalSelector();
	targetSelector->addGoal(1, new HurtByTargetGoal(this, false));
	targetSelector->addGoal(2, new NearestAttackableTargetGoal(this, 1, 16, 0, true));

	goalSelector = new GoalSelector();
	//goalSelector->addGoal(1, new BreakDoorGoal(this));
	goalSelector->addGoal(2, new MeleeAttackGoal(this, runSpeed, false, 0));
	goalSelector->addGoal(7, new RandomStrollGoal(this, runSpeed) );

	moveControl = new MoveControl(this);
	jumpControl = new JumpControl(this);
}

Zombie::~Zombie() {
	delete goalSelector;
	delete targetSelector;

	delete moveControl;
	delete jumpControl;
}

int Zombie::getMaxHealth() {
	return 12; // 16
}

void Zombie::aiStep() {
	if ((++fireCheckTick & 1) && level->isDay() && !level->isClientSide) {
		float br = getBrightness(1);
		if (br > 0.5f) {
			if (level->canSeeSky(Mth::floor(x), Mth::floor(y), Mth::floor(z)) && random.nextFloat() * 3.5f < (br - 0.4f)) {
			//	hurt(NULL, 1); // no use anymore since i restored setOnFire - shredder

				for (int i = 0; i < 5; ++i) {
					float xa = (2.0f * random.nextFloat() - 1.0f) * (2.0f * random.nextFloat() - 1.0f) * 0.02f;
					float ya = (2.0f * random.nextFloat() - 1.0f) * (2.0f * random.nextFloat() - 1.0f) * 0.02f;
					float za = (2.0f * random.nextFloat() - 1.0f) * (2.0f * random.nextFloat() - 1.0f) * 0.02f;
					level->addParticle(PARTICLETYPE(explode), x + random.nextFloat() * bbWidth * 2 - bbWidth, y + random.nextFloat() * bbHeight, z + random.nextFloat() * bbWidth * 2 - bbWidth, xa, ya, za);
				}
				setOnFire(8); //@todo
			}
		}
	}

	super::aiStep();
}

int Zombie::getEntityTypeId() const {
	return MobTypes::Zombie;
}

void Zombie::setUseNewAi( bool use ) {
	_useNewAi = use;
}

int Zombie::getArmorValue() {
	int armor = super::getArmorValue() + 2;
	if (armor > 20) armor = 20;
	return armor;
}

const char* Zombie::getAmbientSound() {
	return "mob.zombie";
}

std::string Zombie::getHurtSound() {
	return "mob.zombiehurt";
}

std::string Zombie::getDeathSound() {
	return "mob.zombiedeath";
}

int Zombie::getDeathLoot() {
	return 0; //@todo
	//return Item::rotten_flesh->id;
}

bool Zombie::useNewAi() {
	return _useNewAi;
}

void Zombie::die( Entity* source ) {
	super::die(source);
	if(!level->isClientSide) {
		if(random.nextInt(4) == 0) {
			spawnAtLocation(Item::feather->id, random.nextInt(1) + 1);
		}
	}	
}

int Zombie::getAttackDamage( Entity* target ) {
	ItemInstance* weapon = getCarriedItem();
	int damage = attackDamage;
	if(weapon != NULL) damage += weapon->getAttackDamage(this);
	return damage;
}

/*@Override*/ //@todo?
//MobType getMobType() {
//	return MobType::UNDEAD;
//}

