#include "ItemEntity.h"
#include "Game.h"


ItemEntity::ItemEntity(Framework::Vec3<float> location, int dimensionId, int entityId)
	: Entity(ItemEntityType::INSTANCE, location, dimensionId, entityId)
{
	slot = new ItemSlot("Inventory", __INT32_MAX__, 0, 0, 0, ANY_DIRECTION, 0);
	addSlot(slot);
	faceOffset = { 0.f, 0.f, 0.f };
	maxHP = 10;
	currentHP = 10;
	stamina = 10;
	maxStamina = 10;
	hunger = 10;
	maxHunger = 10;
	thirst = 10;
	maxThirst = 10;
	targetDistanceLimit = 4;
	maxMovementSpeed = 1;
}

void ItemEntity::prepareTick(const Dimension* zDimension)
{
	if (slot->zStack() == 0 && !removed)
		throw "Illegal State exception";
	if (movements.getEintragAnzahl() <= 1)
	{
		Entity* zOther = Game::INSTANCE->zNearestEntity(currentDimensionId, location, [this](Entity* zOther)
			{
				return zOther != this && zOther->numberOfAddableItems(slot->zStack(), NO_DIRECTION);
			});
		if (zOther)
		{
			MovementFrame frame;
			frame.direction = zOther->getPosition() - getPosition();
			frame.duration = 0.25;
			frame.movementFlags = 0x1; // TODO: torn on flight mode
			frame.targetPosition = getPosition() + frame.direction * (0.5f * maxMovementSpeed);
			addMovementFrame(frame);
		}
	}
	Entity::prepareTick(zDimension);
}

void ItemEntity::tick(const Dimension* zDimension)
{
	Entity* zOther = Game::INSTANCE->zNearestEntity(currentDimensionId, location, [this](Entity* zOther)
		{
			return zOther != this && zOther->numberOfAddableItems(slot->zStack(), NO_DIRECTION);
		});
	if (zOther)
	{
		float d = location.abstand(zOther->getPosition());
		if (d < 0.5f)
		{
			// add items of this entity to the other entity
			zOther->interactWith(this, NO_DIRECTION).pullItems(slot->getNumberOfItems(), 0);
			if (slot->getNumberOfItems() == 0)
				onDeath();
		}
	}
	Entity::tick(zDimension);
}

void ItemEntity::onFall(float collisionSpeed)
{
	if (collisionSpeed >= 50.f)
		this->currentHP = 0;
}

bool ItemEntity::hasDefaultModel() const
{
	return 0;
}

ModelInfo ItemEntity::getSpecialModel() const
{
	const ItemType* zItemType = 0;
	if (!slot->isEmpty())
		zItemType = slot->zStack()->zItem()->zItemType();
	return !zItemType ? ModelInfo("", "", 0) : zItemType->getModel();
}


ItemEntityType::ItemEntityType()
	: EntityType(ID, ModelInfo("", "", 0))
{}

Entity* ItemEntityType::createEntity(Framework::Vec3<float> position, int dimensionId, int entityId) const
{
	return new ItemEntity(position, dimensionId, entityId);
}