#pragma once
#include "Plottable.h"
#include "../axis/Axis.h"
#include "../renderable/Render_Partition.h"
#include <renderive/renderable/Render_Frame_Completion.hpp>
#include <memory_resource>
#include <span>
namespace renderive {
struct Afterglow_Properties {
    Range frequency_range{0.0, 10.0};
    Range power_range{0.0, 10.0};
    Nonnegative_Count frequency_point_size;
    Nonnegative_Count power_point_size;
    Render_Partition_Mode partition_mode{Render_Partition_Mode::Automatic};
    Positive_Count partition_count;
    bool interpolate = true;
    Unit_Interval attenuation_rate{0.2};
    Color_Map color_map;
};
namespace detail {
class LIB_DECL Afterglow_Control : public Plottable_State<Afterglow_Properties>,
                                   public ::Render_Frame_Completion {
public:
    Afterglow_Control(const Afterglow_Properties& properties, renderive_Owner<Frequency_Axis> frequency_axis, renderive_Owner<Axis> power_axis);
    ~Afterglow_Control() override;
    [[nodiscard]] std::size_t history_count() const;
    [[nodiscard]] std::size_t latest_spectrum_point_count() const;
    [[nodiscard]] std::size_t rendered_cell_count() const;
    void append_spectrum(std::span<const double> values);
    void append_spectrum(std::pmr::vector<double>&& values);
    template <class Values>
    void append_spectrum(const Values& values) {
        append_spectrum(std::span<const double>(values.data(), values.size()));
    }
protected:
    void prepare_frame(const Prepare_Render_Context& context) override;
    void paint(Painter& painter, const Paint_Render_Context& context) override;
    void build_prepare_graph(Renderable_Graph_Builder& builder) override;
    void build_paint_graph(Renderable_Graph_Builder& builder) override;
private:
    struct Impl;
    void prepare_render_frame(const Render_State_View& state, int graph_partition_count);
    void accumulate_partition(int partition_index);
    void normalize_render_frame();
    void color_partition(int partition_index);
    void paint_render_frame(Painter& painter);
    void render_frame_completed(std::uint64_t target_interval_ns) override;
    void publish() override;
};
}
using Afterglow = detail::Attach_Plottable<detail::Afterglow_Control, Afterglow_Properties>;
}
