#pragma once

#include "Render_3D_Core.h"

#include <datoviz/scene.h>

#include <cstdint>
#include <unordered_map>

namespace renderive::detail {

class Datoviz_Scene_Binding final {
public:
    Datoviz_Scene_Binding(DvzScene* scene, Extent_2D initial_extent);

    Datoviz_Scene_Binding(const Datoviz_Scene_Binding&) = delete;
    Datoviz_Scene_Binding& operator=(const Datoviz_Scene_Binding&) = delete;

    [[nodiscard]] bool apply(const Render_3D_State& state, std::uint64_t revision);
    [[nodiscard]] DvzSceneFrameArtifact* emit(
        const DvzCapabilitySnapshot& capabilities, const DvzFramePlanEmitConfig& configuration);

private:
    struct Visual_Binding {
        DvzVisual* visual{};
        std::uint64_t applied_revision{};
    };

    [[nodiscard]] bool apply_camera(const Camera_3D& camera);
    [[nodiscard]] static bool apply_object(
        const Object_3D_State& object, Visual_Binding& binding);

    DvzScene* scene_{};
    DvzFigure* figure_{};
    DvzPanel* panel_{};
    std::unordered_map<std::uint64_t, Visual_Binding> visuals_;
    std::uint64_t applied_revision_{};
};

} // namespace renderive::detail
