#include "npc_unit.h"
#include "enemy_body.h"
#include "macros.h"
#include "patrol_path.h"
#include "player_detector.h"

void NpcUnit::_bind_methods() {
	BIND_HPROPERTY(Variant::OBJECT, patrol_path, PROPERTY_HINT_NODE_TYPE, "PatrolPath");
	BIND_PROPERTY(Variant::FLOAT, patrol_speed);
}

void NpcUnit::on_npc_awareness_changed(bool value) {
	if (value) {
		this->aware_of_player = true;
	}
}

void NpcUnit::child_added(Node *node) {
	if (EnemyBody * npc{ cast_to<EnemyBody>(node) }) {
		this->npcs.push_back(npc);
		npc->set_unit(this);
		Vector3 const offset{ npc->get_global_position() - get_global_position() };
		npc->set_unit_offset({ offset.x, offset.z });
		if (PlayerDetector * detector{ cast_to<PlayerDetector>(npc->get_node(NodePath("%PlayerDetector"))) }) {
			detector->connect(PlayerDetector::sig_awareness_changed, callable_mp(this, &self_type::on_npc_awareness_changed));
		}
	}
}

void NpcUnit::enter_tree() {
	this->connect("child_entered_tree", callable_mp(this, &self_type::child_added));
}

void NpcUnit::_notification(int what) {
	if (Engine::get_singleton()->is_editor_hint()) {
		return;
	}
	switch (what) {
		default:
			return;
		case NOTIFICATION_ENTER_TREE:
			enter_tree();
			return;
	}
}

void NpcUnit::set_patrol_path(PatrolPath *path) {
	this->patrol_path = path;
}

PatrolPath *NpcUnit::get_patrol_path() const {
	return this->patrol_path;
}

bool NpcUnit::is_aware_of_player() const {
	return this->aware_of_player;
}

void NpcUnit::set_patrol_speed(float speed) {
	this->patrol_speed = speed;
}

float NpcUnit::get_patrol_speed() const {
	return this->patrol_speed;
}
