using System.Drawing;
using OpenNest;
namespace OpenNest.Data;
///
/// Per-drawing nesting settings a library record owns. They are structured server fields,
/// not package content: canonical packages leave them at their defaults, and adding a library
/// drawing to a nest applies these values. Editing them adds a revision without new geometry.
/// A record, so two settings are equal when every value is.
///
public sealed record DrawingNestingSettings
{
/// Automatic sequencing cuts this drawing's parts first (for example test squares).
public bool CutFirst { get; init; }
public int Priority { get; init; }
/// Rotation step in radians; zero means the engine's default.
public double StepAngle { get; init; }
/// Rotation start angle in radians.
public double StartAngle { get; init; }
/// Rotation end angle in radians.
public double EndAngle { get; init; }
public bool Allow180Equivalent { get; init; }
///
/// Display color as a 32-bit ARGB value. A fully transparent value (alpha 0, the default)
/// means no stored color: the drawing gets the next part color when it is added.
///
public int ColorArgb { get; init; }
/// The settings currently has.
public static DrawingNestingSettings FromDrawing(Drawing drawing)
{
ArgumentNullException.ThrowIfNull(drawing);
var constraints = drawing.Constraints ?? new NestConstraints();
return new DrawingNestingSettings
{
CutFirst = drawing.CutFirst,
Priority = drawing.Priority,
StepAngle = constraints.StepAngle,
StartAngle = constraints.StartAngle,
EndAngle = constraints.EndAngle,
Allow180Equivalent = constraints.Allow180Equivalent,
// Zero means "use the palette", so only a custom color is carried into the library.
ColorArgb = drawing.HasCustomColor ? drawing.Color.ToArgb() : 0,
};
}
/// Writes these settings onto .
public void ApplyTo(Drawing drawing)
{
ArgumentNullException.ThrowIfNull(drawing);
drawing.CutFirst = CutFirst;
drawing.Priority = Priority;
drawing.Constraints = new NestConstraints
{
StepAngle = StepAngle,
StartAngle = StartAngle,
EndAngle = EndAngle,
Allow180Equivalent = Allow180Equivalent,
};
var color = Color.FromArgb(ColorArgb);
drawing.HasCustomColor = color.A != 0;
drawing.Color = drawing.HasCustomColor ? color : Drawing.GetNextColor();
}
/// The first rule these settings break, or null when they may be saved.
public string? GetValidationError()
{
if (!double.IsFinite(StepAngle) || !double.IsFinite(StartAngle) || !double.IsFinite(EndAngle))
return "settings angles must be finite numbers.";
// Ranges are not checked: nest drawings carry whatever their files hold, and
// saving one to the library must not be refused for it.
return StepAngle < 0 ? "settings.stepAngle must be zero or greater." : null;
}
}