#ifndef SPAWNER_HPP
#define SPAWNER_HPP

#include "enemy_spawnpoint.hpp"
#include "godot_cpp/classes/packed_scene.hpp"
#include "godot_cpp/classes/random_number_generator.hpp"
#include "godot_cpp/templates/vector.hpp"
#include "rally_rush_game_mode.hpp"
#include <godot_cpp/classes/node.hpp>

namespace godot {
class EnemySpawnpoint;
//! Singleton managing enemy and key spawning. Spawns a single enemy at an interval, selecting drone or car based on which is required or taking turns if both. Spawns three keys at the start of the game.
class Spawner : public Node {
    GDCLASS(Spawner, Node);
    //! Register editor properties.
    static void _bind_methods();
public:
    //! Spawn three keys. Store gamemode reference.
    virtual void _enter_tree() override;
    //! Update timer, spawn new enemy as required.
    virtual void _process(double delta_time) override;

    //! The max number of cars, increases with number of keys found.
    int max_enemy_cars();
    //! The max number of drones, increases with number of enemies found.
    int max_enemy_drones();
protected:
    //! Spawn an enemy car at a random spawnpoint. Increases car counter.
    void spawn_enemy_car();
    //! Spawn an enemy drone at a random spawnpoint. Increases drone counter.
    void spawn_enemy_drone();
    //! Spawn a key at a random spawnpoint.
    void spawn_key();
    //! Listener for when a car is destroyed somehow. Decreases car counter.
    void decrement_cars();
    //! Listener for when a drone is destroyed somehow. Decreases drone counter.
    void decrement_drones();
    //! The scene to instantiate for drones.
    void set_drone_scene(Ref<PackedScene> scene);
    //! The scene to instantiate for drones.
    Ref<PackedScene> get_drone_scene() const;
    //! The scene to instantiate for cars.
    void set_car_scene(Ref<PackedScene> scene);
    //! The scene to instantiate for cars.
    Ref<PackedScene> get_car_scene() const;
    //! The scene to instantiate for keys.
    void set_key_scene(Ref<PackedScene> scene);
    //! The scene to instantiate for keys.
    Ref<PackedScene> get_key_scene() const;
private:
    //! Time at which the next spawn tick will go.
    double next{0};
    //! The number of spawn ticks that have happened, could overflow, though that's not a problem.
    unsigned tick{0};
    Ref<PackedScene> drone_scene{};
    Ref<PackedScene> car_scene{};
    Ref<PackedScene> key_scene{};
    RandomNumberGenerator rng{};
    unsigned num_cars{0};
    unsigned num_drones{0};

    //! Reference to the game mode.
    RallyRushGameMode *game_mode;
};
}

#endif // !SPAWNER_HPP
