using Rozpisky.Rendering;
namespace Rozpisky.Tests;
///
/// Testovací : nic nekreslí, jen zaznamenává volání primitiv,
/// aby testy mohly assertovat, co přesně parser (DxfTemplate.Replay) vyprodukoval.
/// Obrysy () se pro pohodlné assertování bboxů zaznamenávají jak analyticky
/// (, ), tak jemně zploštěné na body
/// (, ) – zpětně kompatibilní s dřívějšími testy.
///
public sealed class RecordingRenderer : IProfileRenderer
{
public sealed record TextCall(double X, double Y, string Text, double HeightMm, HAlign H, VAlign V,
double RotationDeg, TextStyle Style, double WidthFactor, double MaxWidthMm);
/// Každé volání Fill = smyčky jednoho HATCH, zploštěné na body.
public List>> Fills { get; } = new();
/// Analytické obrysy jednotlivých volání Fill (se zachovanými oblouky).
public List> FillContours { get; } = new();
/// Analytické obrysy z volání Stroke (bulge polylinie, samostatné oblouky).
public List StrokeContours { get; } = new();
public List Texts { get; } = new();
/// Zploštěné polylinie i obrysy ze Stroke (kvůli zpětné kompatibilitě testů).
public List> Polylines { get; } = new();
public int LineCount { get; private set; }
public int CircleCount { get; private set; }
/// Stavy kresby v pořadí, jak přišly – testy tak můžou tvrdit i o barvě a hladině.
public List Stavy { get; } = new();
/// Stav platný pro naposledy zaznamenanou entitu.
public KresliciStav PosledniStav => Stavy.Count > 0 ? Stavy[^1] : KresliciStav.Vychozi;
public void Stav(in KresliciStav s) => Stavy.Add(s);
/// Koncové body zaznamenaných úseček – testy tvrdí i o poloze, nejen o počtu.
public List<((double X, double Y) Od, (double X, double Y) Do)> Lines { get; } = new();
public void Line(double x1, double y1, double x2, double y2)
{
LineCount++;
Lines.Add(((x1, y1), (x2, y2)));
}
public void Polyline(IReadOnlyList<(double X, double Y)> pts, bool closed = false) => Polylines.Add(pts);
public void Circle(double cx, double cy, double r) => CircleCount++;
public void Stroke(Contour c)
{
StrokeContours.Add(c);
Polylines.Add(Zplosti(c));
}
public void Text(double x, double y, string text, double heightMm,
HAlign h = HAlign.Left, VAlign v = VAlign.Baseline, double rotationDeg = 0,
TextStyle style = default, double widthFactor = 1, double maxWidthMm = 0)
=> Texts.Add(new TextCall(x, y, text, heightMm, h, v, rotationDeg, style, widthFactor, maxWidthMm));
/// Druh výplně u jednotlivých volání Fill (plná / vzor a jeho čáry).
public List Vyplne { get; } = new();
public void Fill(IReadOnlyList loops, Vypln vypln = default)
{
FillContours.Add(loops);
Vyplne.Add(vypln);
Fills.Add(loops.Select(Zplosti).ToList());
}
/// Zploští obrys na body (jemně, sagitta ≤ 0,02 mm) – pro bbox asserty v testech.
private static IReadOnlyList<(double X, double Y)> Zplosti(Contour c)
{
var pts = new List<(double X, double Y)>();
foreach (var e in c.Edges) e.AppendPoints(pts, maxSagitta: 0.02);
if (c.Edges.Count > 0) pts.Add((c.Edges[^1].EX, c.Edges[^1].EY));
return pts;
}
}