namespace OpenNest.Data; /// /// The customers, materials, grades and thicknesses an edit offers in its drop-downs: those /// already used by library drawings, plus the materials and grades of a material catalog. /// Names match by and keep the first spelling seen, so /// pass the newest records first. Thicknesses come only from records in the edit's units. /// The lists are suggestions; any typed value may still be saved. /// public sealed class DrawingLibraryChoices { private readonly List _records; private readonly List _catalog; private DrawingLibraryChoices(List records, List catalog, Units units) { _records = records; Units = units; _catalog = catalog; Customers = Distinct(records.Select(r => r.Customer)); Materials = Distinct(records.Select(r => r.MaterialName).Concat(catalog.Select(m => m.Name))); } public static DrawingLibraryChoices Empty { get; } = new(new(), new(), Units.Inches); /// Library drawings, newest first; archived ones are skipped. /// The edit's units; thicknesses in other units are not offered. /// Materials and grades on file, for example the machine configurations'. public static DrawingLibraryChoices From(IEnumerable records, Units units, IEnumerable? catalog = null) { ArgumentNullException.ThrowIfNull(records); return new DrawingLibraryChoices(records.Where(r => r != null && !r.Archived).ToList(), catalog?.Where(m => m != null).ToList() ?? new(), units); } public Units Units { get; } /// Customers, sorted. public IReadOnlyList Customers { get; } /// Material names, sorted. public IReadOnlyList Materials { get; } /// The grades used or on file for , sorted. public IReadOnlyList GradesOf(string? material) { var key = SharedListNames.Key(material); if (key.Length == 0) return Array.Empty(); return Distinct(_records.Where(r => SharedListNames.Key(r.MaterialName) == key).Select(r => r.MaterialGrade) .Concat(_catalog.Where(m => SharedListNames.Key(m.Name) == key).Select(m => m.Grade))); } /// /// The thicknesses library drawings of (and of /// , when one is given) use, thinnest first. /// public IReadOnlyList ThicknessesOf(string? material, string? grade) { var materialKey = SharedListNames.Key(material); if (materialKey.Length == 0) return Array.Empty(); var gradeKey = SharedListNames.Key(grade); return _records .Where(r => r.Units == Units && SharedListNames.Key(r.MaterialName) == materialKey && (gradeKey.Length == 0 || SharedListNames.Key(r.MaterialGrade) == gradeKey) && double.IsFinite(r.Thickness) && r.Thickness > 0) .Select(r => DrawingLibraryRules.NormalizeThickness(r.Thickness)) .Distinct() .OrderBy(t => t) .ToList(); } private static IReadOnlyList Distinct(IEnumerable names) => names .Where(name => !string.IsNullOrWhiteSpace(name)) .Select(name => MaterialListRules.Spelling(name)) .GroupBy(SharedListNames.Key) .Select(group => group.First()) .OrderBy(name => name, StringComparer.OrdinalIgnoreCase) .ToList(); }