#include "register_types.h"
#include "action.hpp"
#include "character_actor.hpp"
#include "character_data.hpp"
#include "enemy.hpp"
#include "global_world_state.hpp"
#include "goal_marker.hpp"
#include "health.hpp"
#include "pellet_projectile.hpp"
#include "planner.hpp"
#include "projectile_pool.hpp"
#include "state.hpp"
#include "tunnels_game_mode.hpp"
#include "tunnels_game_state.hpp"
#include "tunnels_player.hpp"
#include "weapon_data.hpp"
#include "weapon_muzzle.hpp"
#include "utils/game_mode.hpp"
#include "utils/game_root.hpp"
#include "utils/game_state.hpp"
#include "utils/level.hpp"
#include "utils/player_input.hpp"
#include "utils/spawn_point.hpp"
#include <gdextension_interface.h>
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/core/defs.hpp>
#include <godot_cpp/godot.hpp>

using namespace godot;

void initialize_gdextension_types(ModuleInitializationLevel p_level)
{
    if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
        return;
    }
    ClassDB::register_abstract_class<GameRoot>();
    ClassDB::register_class<GameMode>();
    ClassDB::register_class<GameRoot3D>();
    ClassDB::register_class<GameState>();
    ClassDB::register_class<Level3D>();
    ClassDB::register_class<PlayerInput>();
    ClassDB::register_class<SpawnPoint3D>();

    ClassDB::register_class<TunnelsGameMode>();
    ClassDB::register_class<TunnelsGameState>();
    ClassDB::register_class<TunnelsPlayer>();

    ClassDB::register_class<Enemy>();
    ClassDB::register_class<Health>();
    ClassDB::register_class<CharacterActor>();
    ClassDB::register_class<ProjectilePool>();
    ClassDB::register_class<WeaponMuzzle>();

    ClassDB::register_class<WeaponData>();
    ClassDB::register_class<CharacterData>();

    ClassDB::register_class<Projectile>();
    ClassDB::register_class<PelletProjectile>();

    ClassDB::register_class<goap::Action>();
    ClassDB::register_class<goap::GlobalWorldState>();
    ClassDB::register_abstract_class<goap::StateArgs>();
    ClassDB::register_class<goap::MoveStateArgs>();
    ClassDB::register_class<goap::AnimateStateArgs>();
    ClassDB::register_class<goap::ActivateStateArgs>();
    ClassDB::register_class<goap::Goal>();
    ClassDB::register_class<goap::Planner>();
    ClassDB::register_class<GoalMarker>();
    ClassDB::register_class<LineGoalMarker>();
}

extern "C"
{
    // Initialization
    GDExtensionBool GDE_EXPORT tunnels_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization)
    {
        GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);
        init_obj.register_initializer(initialize_gdextension_types);
        init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE);

        return init_obj.init();
    }
}
