const value = @import("value.zig");
const Value = value.Value;

/// Canvases are opaque handles passed from the host to the VM.
/// The host creates and manages the canvas, hence no `new` function.
pub const Canvas = opaque {
    fn wrap(status: bool) !void {
        if (!status) return error.Draw;
    }

    pub fn begin(c: *Canvas) !void {
        try wrap(__haku2_canvas_begin(c));
    }

    pub fn line(c: *Canvas, start: value.Vec2, end: value.Vec2) !void {
        const x1, const y1 = start;
        const x2, const y2 = end;
        try wrap(__haku2_canvas_line(c, x1, y1, x2, y2));
    }

    pub fn rect(c: *Canvas, top_left: value.Vec2, size: value.Vec2) !void {
        const x, const y = top_left;
        const width, const height = size;
        try wrap(__haku2_canvas_rectangle(c, x, y, width, height));
    }

    pub fn circle(c: *Canvas, center: value.Vec2, r: f32) !void {
        const x, const y = center;
        try wrap(__haku2_canvas_circle(c, x, y, r));
    }

    pub fn fill(c: *Canvas, color: value.Rgba8) !void {
        const r, const g, const b, const a = color;
        try wrap(__haku2_canvas_fill(c, r, g, b, a));
    }

    pub fn stroke(c: *Canvas, color: value.Rgba8, thickness: f32) !void {
        const r, const g, const b, const a = color;
        try wrap(__haku2_canvas_stroke(c, r, g, b, a, thickness));
    }
};

extern fn __haku2_canvas_begin(c: *Canvas) bool;
extern fn __haku2_canvas_line(c: *Canvas, x1: f32, y1: f32, x2: f32, y2: f32) bool;
extern fn __haku2_canvas_rectangle(c: *Canvas, x: f32, y: f32, width: f32, height: f32) bool;
extern fn __haku2_canvas_circle(c: *Canvas, x: f32, y: f32, r: f32) bool;
extern fn __haku2_canvas_fill(c: *Canvas, r: u8, g: u8, b: u8, a: u8) bool;
extern fn __haku2_canvas_stroke(c: *Canvas, r: u8, g: u8, b: u8, a: u8, thickness: f32) bool;
