const std = @import("std");
const Object = @import("../Object.zig");
const Property = @import("../Property.zig").Property;
const PropertyData = @import("../Property.zig").Data;
const defaultCommonProperties = Object.defaultCommonProperties;
const basic_models = @import("../basic_models.zig");
const Point2_f = basic_models.Point2_f;
const line = @import("line.zig");
const ellipse = @import("ellipse.zig");
const broken = @import("broken.zig");
pub const Rect = basic_models.Rect_f;

/// Добавляет к объекту список свойств фигуры. Для .points дублирует слайс (объект владеет).
fn appendShapeProperties(allocator: std.mem.Allocator, obj: *Object, props: []const Property) !void {
    for (props) |prop| {
        if (prop.data == .points) {
            const pts = prop.data.points;
            const copy = try allocator.dupe(Point2_f, pts);
            try obj.properties.append(allocator, .{ .data = .{ .points = copy } });
        } else {
            try obj.properties.append(allocator, prop);
        }
    }
}

/// Создаёт объект с дефолтными общими и фигурными свойствами.
pub fn createObject(allocator: std.mem.Allocator, shape_kind: Object.ShapeKind) !Object {
    var obj = try createWithCommonProperties(allocator, shape_kind);
    errdefer obj.deinit(allocator);
    switch (shape_kind) {
        .line => try appendShapeProperties(allocator, &obj, &line.default_shape_properties),
        .ellipse => try appendShapeProperties(allocator, &obj, &ellipse.default_shape_properties),
        .broken => {
            try appendShapeProperties(allocator, &obj, &broken.default_shape_properties);
            try obj.setProperty(allocator, .{ .data = .{ .fill_rgba = obj.getProperty(.stroke_rgba).? } });
        },
    }
    return obj;
}

fn createWithCommonProperties(allocator: std.mem.Allocator, shape_kind: Object.ShapeKind) !Object {
    var properties_list = std.ArrayList(Property).empty;
    errdefer properties_list.deinit(allocator);
    for (defaultCommonProperties) |prop| try properties_list.append(allocator, prop);
    return .{
        .id = 0,
        .shape = shape_kind,
        .properties = properties_list,
        .children = std.ArrayList(Object).empty,
    };
}
