using System; namespace OpenNest; /// Immutable per-job options; selection never changes the legacy global registry. public sealed class NestJobOptions { public NestJobOptions(string placementStrategy = "Default", int? maxPlates = null, double salvageRate = 0, double minimumSalvageDimension = 0) { ArgumentException.ThrowIfNullOrWhiteSpace(placementStrategy); if (maxPlates <= 0) throw new ArgumentOutOfRangeException(nameof(maxPlates)); if (!double.IsFinite(salvageRate) || salvageRate < 0 || salvageRate > 1) throw new ArgumentOutOfRangeException(nameof(salvageRate)); if (!double.IsFinite(minimumSalvageDimension) || minimumSalvageDimension < 0) throw new ArgumentOutOfRangeException(nameof(minimumSalvageDimension)); PlacementStrategy = placementStrategy; MaxPlates = maxPlates; SalvageRate = salvageRate; MinimumSalvageDimension = minimumSalvageDimension; } /// Fraction of eligible edge-offcut area credited by StockLadder (0..1). public double SalvageRate { get; } /// Both offcut dimensions must meet this caller-supplied minimum in job units. /// Zero disables credit; scraps and holes are never credited. public double MinimumSalvageDimension { get; } public string PlacementStrategy { get; } /// Maximum physical sheets to commit, or null for no explicit cap. public int? MaxPlates { get; } }