#pragma once

#include "brush.h"
#include "legacy_node_stroke_preview_execution_services.h"
#include "rtt.h"
#include "texture.h"

#include <array>
#include <functional>
#include <vector>

namespace pp::panopainter {

struct LegacyNodeStrokePreviewFrame {
    glm::vec4 col {};
    float flow = 0.0f;
    float opacity = 0.0f;
    std::array<vertex_t, 4> shapes {};
    glm::vec4 mixer_rect {};
};

struct LegacyNodeStrokePreviewLiveRenderRequest {
    const Brush& brush;
    const LegacyNodeStrokePreviewPassOrchestrationPlan& pass_orchestration;
    const LegacyNodeStrokePreviewPreparedStrokes& prepared_strokes;
    Texture2D& stroke_texture;
    RTT& mixer_rtt;
    RTT& render_target;
    Texture2D& background_texture;
    Texture2D& dual_texture;
    Texture2D& preview_texture;
    Sampler& linear_sampler;
    Sampler& repeat_sampler;
    float zoom = 1.0f;
    float min_flow = 0.0f;
    bool copy_stroke_destination = false;
    glm::vec2 size {};
    std::function<void(const Brush&)> bind_dual_pass_textures;
    std::function<void(bool)> capture_background;
    std::function<std::vector<LegacyNodeStrokePreviewFrame>(const Stroke&, float)> compute_frames;
    std::function<glm::vec4(std::array<vertex_t, 4>&, Texture2D&, bool)> draw_samples;
    std::function<void(const glm::vec2&, const glm::vec2&)> draw_mix;
    std::function<void()> unbind_mixer_texture;
    std::function<void()> bind_pattern_texture;
    std::function<void()> draw_composite;
};

struct LegacyNodeStrokePreviewMixPassExecutionRequest {
    const Brush& brush;
    glm::vec2 preview_size {};
    RTT& mixer_rtt;
    glm::vec2 bb_min {};
    glm::vec2 bb_sz {};
    Sampler& linear_sampler;
    Texture2D& background_texture;
    Texture2D& stroke_texture;
    Texture2D& dual_texture;
    std::function<void()> draw_mix;
};

[[nodiscard]] bool execute_legacy_node_stroke_preview_mix_pass(
    const LegacyNodeStrokePreviewMixPassExecutionRequest& request);

[[nodiscard]] bool execute_legacy_node_stroke_preview_mix_pass(
    const Brush& brush,
    glm::vec2 preview_size,
    RTT& mixer_rtt,
    glm::vec2 bb_min,
    glm::vec2 bb_sz,
    Sampler& linear_sampler,
    Texture2D& background_texture,
    Texture2D& stroke_texture,
    Texture2D& dual_texture,
    std::function<void()> draw_mix);

[[nodiscard]] bool execute_legacy_node_stroke_preview_live_render_passes(
    const LegacyNodeStrokePreviewLiveRenderRequest& request);

} // namespace pp::panopainter
