#include "tunnels_game_mode.hpp"
#include "character_actor.hpp"
#include "utils/game_root.hpp"
#include "utils/godot_macros.h"
#include <godot_cpp/classes/node.hpp>
#include <godot_cpp/core/object.hpp>
#include <godot_cpp/variant/callable.hpp>
#include <godot_cpp/variant/callable_method_pointer.hpp>
#include <godot_cpp/variant/variant.hpp>

namespace godot {
void TunnelsGameMode::_bind_methods() {
#define CLASSNAME TunnelsGameMode
    GDFUNCTION_ARGS(on_player_spawned, "player");
}

void TunnelsGameMode::_begin() {
    GameRoot::get_singleton()->connect("player_spawned", Callable(this, "on_player_spawned"));
}

void TunnelsGameMode::on_player_spawned(Node *player) {
    this->player = Object::cast_to<TunnelsPlayer>(player);
}

TunnelsPlayer *TunnelsGameMode::get_player_instance() const {
    return this->player;
}

void TunnelsGameMode::register_player_character(CharacterActor *actor) {
    if(!this->player_characters.has(actor)) {
        this->player_characters.push_back(actor);
        actor->connect("tree_exited", callable_mp(this, &TunnelsGameMode::on_character_destroyed).bind(actor));
    }
}

void TunnelsGameMode::set_manual_character(CharacterActor *actor) {
    if(!this->player_characters.has(actor))
        this->register_player_character(actor);
    this->manual_character = actor;
}

void TunnelsGameMode::on_character_destroyed(CharacterActor *actor) {
    this->player_characters.erase(actor);
    if(this->manual_character == actor)
        this->manual_character = nullptr;
}

Vector<CharacterActor*> const &TunnelsGameMode::get_player_characters() const {
    return this->player_characters;
}
}
