#include "character.h"
#include "core/renderer.h"
#include "world.h"
#include <cassert>
#include <cstdlib>

namespace rogue {
CharacterLogic::~CharacterLogic() {}

void CharacterLogic::set_character(Character *character) {
	this->character = character;
}

Character::Character(Tile location, CharacterLogic *logic, CharacterData const *stats)
: data{stats}
, health{stats->health}
, location{location}
, world{nullptr}
, logic{logic} {
	this->logic->set_character(this);
}

void Character::act() {
	assert(this->world != nullptr && "World generation did not initialize character properly");
	if(this->health <= 0) {
		return;
	}
	this->logic->set_character(this);
	// get motion from logic
	Tile target{this->logic->move()};
	if(target == this->location
	|| std::abs(target.x - this->location.x) + std::abs(target.y - this->location.y) != 1) {
		return;
	}
	// check resulting tile
	TileData tile{world->query_tile(target)};
	// if character, deal damage
	if(tile.character != nullptr) {
		tile.character->deal_damage(this->data->damage);
	} else if(!tile.is_wall) { // if empty, move
		this->location = target;
	} // if wall, do nothing
}

void Character::draw() {
	if(this->health > 0) {
		Render::draw(this->location, this->data->sprite);
	}
}

bool Character::deal_damage(int damage) {
	return (this->health -= damage) <= 0;
}

Tile NullCharacterLogic::move() {
	return this->character->location;
}
}
