#include "pch.h"

#include "legacy_node_stroke_preview_sample_services.h"
#include "legacy_node_stroke_preview_runtime_services.h"

namespace pp::panopainter {

namespace {

std::array<pp::paint_renderer::CanvasStrokePoint, 4> make_stroke_preview_sample_points(
    const std::array<vertex_t, 4>& vertices)
{
    return {
        pp::paint_renderer::CanvasStrokePoint { .x = vertices[0].pos.x, .y = vertices[0].pos.y },
        pp::paint_renderer::CanvasStrokePoint { .x = vertices[1].pos.x, .y = vertices[1].pos.y },
        pp::paint_renderer::CanvasStrokePoint { .x = vertices[2].pos.x, .y = vertices[2].pos.y },
        pp::paint_renderer::CanvasStrokePoint { .x = vertices[3].pos.x, .y = vertices[3].pos.y },
    };
}

void upload_stroke_preview_brush_vertices(DynamicShape& brush_shape, std::span<const vertex_t> vertices)
{
    brush_shape.update_vertices(
        const_cast<vertex_t*>(vertices.data()),
        static_cast<int>(vertices.size()));
}

LegacyStrokeSampleExecutionRequest make_stroke_preview_sample_request(
    const LegacyNodeStrokePreviewSamplePassRequest& request,
    const std::array<pp::paint_renderer::CanvasStrokePoint, 4>& sample_points)
{
    return LegacyStrokeSampleExecutionRequest {
        .context = "NodeStrokePreview::stroke_draw_samples",
        .target_size = request.target_size,
        .vertices = request.vertices,
        .sample_points = sample_points,
        .copy_stroke_destination = request.copy_stroke_destination,
        .bind_destination_texture = request.bind_destination_texture,
        .copy_framebuffer_to_destination_texture = request.copy_framebuffer_to_destination_texture,
        .unbind_destination_texture = request.unbind_destination_texture,
        .upload_brush_vertices = [&](std::span<const vertex_t> brush_vertices) {
            upload_stroke_preview_brush_vertices(request.brush_shape, brush_vertices);
        },
        .draw_brush_shape = [&] {
            request.brush_shape.draw_fill();
        },
    };
}

} // namespace

glm::vec4 execute_legacy_node_stroke_preview_sample_pass(
    const LegacyNodeStrokePreviewSamplePassRequest& request)
{
    const auto sample_points = make_stroke_preview_sample_points(request.vertices);
    const auto result = execute_legacy_canvas_stroke_sample(
        make_stroke_preview_sample_request(request, sample_points));
    return result.dirty_bounds;
}

glm::vec4 execute_legacy_node_stroke_preview_sample_pass(
    RTT& preview_rtt,
    std::array<vertex_t, 4>& vertices,
    DynamicShape& brush_shape,
    Texture2D& blend_tex,
    bool copy_stroke_destination)
{
    return execute_legacy_node_stroke_preview_sample_pass(
        LegacyNodeStrokePreviewSamplePassRequest {
            .target_size = { static_cast<float>(preview_rtt.getWidth()), static_cast<float>(preview_rtt.getHeight()) },
            .vertices = vertices,
            .brush_shape = brush_shape,
            .copy_stroke_destination = copy_stroke_destination,
            .bind_destination_texture = [&] {
                bind_legacy_node_stroke_preview_destination_texture(blend_tex);
            },
            .copy_framebuffer_to_destination_texture = [](
                int src_x,
                int src_y,
                int dst_x,
                int dst_y,
                int width,
                int height) {
                copy_legacy_node_stroke_preview_destination_texture_region(
                    src_x,
                    src_y,
                    dst_x,
                    dst_y,
                    width,
                    height);
            },
            .unbind_destination_texture = [&] {
                unbind_legacy_node_stroke_preview_destination_texture(blend_tex);
            },
        });
}

} // namespace pp::panopainter
