using System;
using System.Collections.Generic;
using System.Linq;
using OpenNest.Engine;
using OpenNest.Engine.Jobs;
using OpenNest.Engine.Jobs.Adapters;
using OpenNest.Geometry;
namespace OpenNest.Forms
{
///
/// Desktop progress adapter for every whole-job engine. Building, validation and binding
/// belong to the shared NestPipeline.
///
internal static class JobEngineNest
{
///
/// Forwards job progress to a NestProgress sink. An engine's optional LegacyProgress detail
/// (live preview parts) passes through; otherwise the stage and committed counts become a
/// description. Committed counts are authoritative only after PlateCommitted.
///
public static IProgress CreateProgress(
string engineName,
IProgress progress
) => new ProgressAdapter(engineName, progress, null);
///
/// As , and also sends each
/// best-plan-so-far report's sheets to .
///
public static IProgress CreateProgress(
string engineName,
IProgress progress,
IProgress> plans
) => new ProgressAdapter(engineName, progress, plans);
public static string Describe(string engineName, NestJobProgress value) => value.Stage switch
{
NestJobStage.PlateCommitted =>
$"{engineName}: committed plate {value.CommittedPlates} ({value.CommittedParts} parts placed)",
NestJobStage.PlanImproved =>
$"{engineName}: found a better plan ({value.Plan?.Plates.Count ?? 0} sheets)",
_ => $"{engineName}: evaluating plate {WorkingPlate(value)} on stock {value.StockId}",
};
/// One-based plate under evaluation; nesters that do not know it report -1.
private static int WorkingPlate(NestJobProgress value) =>
value.PlateIndex >= 0 ? value.PlateIndex + 1 : value.CommittedPlates + 1;
private sealed class ProgressAdapter(
string engineName,
IProgress progress,
IProgress> plans
) : IProgress
{
public void Report(NestJobProgress value)
{
if (value == null)
return;
// A plan sink shows plans as sheets; the plate row keeps tracking the search.
if (value.Stage == NestJobStage.PlanImproved && plans != null)
{
if (value.PlanSheets != null)
plans.Report(value.PlanSheets);
return;
}
if (value.LegacyProgress != null)
{
progress.Report(value.LegacyProgress);
return;
}
progress.Report(
new NestProgress
{
Phase = NestPhase.Custom,
PlateNumber =
value.Stage == NestJobStage.PlateCommitted
? value.CommittedPlates
: WorkingPlate(value),
Description = Describe(engineName, value),
}
);
}
}
}
}