//
// Created by slinky on 5/7/26.
//

#ifndef B_ENGINE_SCENE_H
#define B_ENGINE_SCENE_H

#include "Camera.h"
#include "ShaderProgram.h"
#include "entt/entt.hpp"

class Scene {
public:
    Scene();
    ~Scene() = default;

    entt::entity create_game_object();
    entt::entity create_game_object(entt::entity parent);

    template<typename T>
    T& attach_component(entt::entity e) {
        return _registry.emplace<T>(e);
    }

    template<typename T>
    T& attach_component(entt::entity e, T data) {
        return _registry.emplace<T>(e, data);
    }

    template<typename T>
    T& fetch_component(entt::entity e) {
        return _registry.get<T>(e);
    }

    template<typename T>
    bool has_component(entt::entity e) {
        return _registry.all_of<T>(e);
    }

    void update_transforms();
    void draw_scene(ShaderProgram* program);

    [[nodiscard]] entt::entity get_root() const;
    [[nodiscard]] std::vector<entt::entity> get_children(entt::entity parent);

    void set_active_camera(Camera *camera);
private:
    entt::registry _registry{};
    entt::entity root{entt::null};

    void add_child(entt::entity parent, entt::entity child);
    void update_transforms(entt::entity parent);

    Camera* activeCamera {nullptr};
};

#endif //B_ENGINE_SCENE_H