//
// Created by sfd on 25-5-26.
//

#ifndef SCENE_H
#define SCENE_H


#include <box2d/id.h>
#include <Hazel/Core/TimeStep.h>
#include <Hazel/Core/UUID.h>
#include <Hazel/Renderer/EditorCamera.h>

#include "entt.hpp"
#include "Hazel/Core/Core.h"


namespace Hazel
{
    class Entity;

    class HAZEL_API Scene {
    public:
        Scene();
        ~Scene();

        static Ref<Scene> Copy(Ref<Scene> other);

        Entity CreateEntity(const std::string& name = std::string());
        Entity CreateEntityWithUUID(UUID uuid, const std::string& name = std::string());

        void DestoryEntity(Entity entity);

        void OnRuntimeStart();
        void OnRuntimeStop();

        void OnSimulationStart();
        void OnSimulationStop();

        void OnUpdateRuntime(TimeStep& ts);
        void OnUpdateSimulation(TimeStep& ts, const EditorCamera& camera);
        void OnUpdateEditor(TimeStep& ts, const EditorCamera& camera);
        void OnViewportResize(uint32_t width, uint32_t height);

        void DuplicateEntity(Entity entity);

        Entity GetPrimaryCameraEntity();

        template<typename... Components>
        auto GetAllEntitiesWith()
        {
            return m_Registry.view<Components...>();
        }

    private:

        void OnPhysics2DStart();
        void OnPhysics2DStop();

        void RenderScene(const EditorCamera& camera);

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

    private:
        entt::registry m_Registry;
        uint32_t m_ViewportWidth = 0, m_ViewportHeight = 0;

        b2WorldId* m_PhysicsWorld = nullptr;

        friend class Entity;
        friend class SceneSerializer;
        friend class SceneHierachyPanel;
    };
}


#endif //SCENE_H
