const std = @import("std");
const Document = @import("../../models/Document.zig");
const pipeline = @import("pipeline.zig");
const line = @import("line.zig");
const DrawContext = pipeline.DrawContext;
const Color = @import("dvui").Color;

const Object = Document.Object;
const default_stroke: Color.PMA = .{ .r = 0, .g = 0, .b = 0, .a = 255 };
const default_fill: Color.PMA = .{ .r = 0, .g = 0, .b = 0, .a = 0 };
const default_thickness: f32 = 2.0;

/// Ломаная по точкам, обводка stroke_rgba. При closed — отрезок последняя–первая точка и заливка fill_rgba.
pub fn draw(
    ctx: *DrawContext,
    obj: *const Object,
    allocator: std.mem.Allocator,
) !void {
    const pts = obj.getProperty(.points) orelse return;
    if (pts.len < 2) return;
    const stroke = if (obj.getProperty(.stroke_rgba)) |stroke_rgba| pipeline.rgbaToPma(stroke_rgba) else default_stroke;
    const thickness = obj.getProperty(.thickness) orelse default_thickness;
    const closed = obj.getProperty(.closed) orelse false;
    const filled = obj.getProperty(.filled) orelse true;
    const fill_color = if (obj.getProperty(.fill_rgba)) |fill_rgba| pipeline.rgbaToPma(fill_rgba) else default_fill;

    const buffer = try allocator.alloc(Color.PMA, ctx.buf_width * ctx.buf_height);
    @memset(buffer, .{ .r = 0, .g = 0, .b = 0, .a = 0 });
    defer allocator.free(buffer);

    var copy_ctx = ctx.*;
    copy_ctx.pixels = buffer;
    copy_ctx.replace_mode = true;

    const do_fill = closed and filled;

    if (do_fill) {
        copy_ctx.startFill(allocator) catch return;
    }

    var i: usize = 0;
    while (i + 1 < pts.len) : (i += 1) {
        line.drawLine(&copy_ctx, pts[i].x, pts[i].y, pts[i + 1].x, pts[i + 1].y, stroke, thickness, true);
    }
    if (closed and pts.len >= 2) {
        const last = pts.len - 1;
        line.drawLine(&copy_ctx, pts[last].x, pts[last].y, pts[0].x, pts[0].y, stroke, thickness, true);
    }

    if (do_fill) {
        copy_ctx.stopFill(allocator, fill_color);
    }

    ctx.compositeDrawerContext(&copy_ctx, copy_ctx.transform.opacity);
}
