#ifndef SCENE_HPP
#define SCENE_HPP

#include "open_engine/core/uuid.hpp"
#include "open_engine/renderer/editor_camera.hpp"
#include "open_engine/physics.hpp"

#include <Jolt/Physics/Body/BodyInterface.h>
#include <entt/entity/fwd.hpp>
#include <entt/entt.hpp>
#include <cstdint>

namespace OpenEngine {

    class Entity;
    
    class Scene
    {
        public:
            Scene() = default;
            ~Scene() = default;
            Scene(Scene& other) {};

            void OnRuntimeStart();
            void OnRuntimeStop();

            Entity CreateEntity(const std::string& name = std::string());
            Entity CreateEntityWithUUID(UUID uuid, const std::string& name = std::string());
            void DeleteEntity(entt::entity entity);
            void MarkEntityForDeletion(Entity entity);

            void UpdateEntities();

            void OnUpdateRuntime();
            void OnUpdateEditor(EditorCamera& camera);
            void OnViewportResize(uint32_t width, uint32_t height);

            entt::registry& GetRegistry() { return registry; };
            PhysicsEngine& GetPhysicsEngine() { return physics_engine; };
            Entity GetPrimaryCamera();

        private:
            void OnUpdatePhysics();

            template<typename T>
                void OnComponentAdded(Entity entity, T& component);

        private:
            entt::registry registry;
            PhysicsEngine physics_engine;

            BodyInterface* body_interface;

            uint32_t viewport_width = 0, viewport_height = 0;

            std::vector<entt::entity> pending_deletion;

            friend class SceneSerializer;
            friend class Entity;
    };
}

#endif // SCENE_HPP
