namespace RioJoy.Core.Overlay;

/// <summary>Horizontal placement of a label within its region.</summary>
public enum OverlayHJust { Left, Center, Right }

/// <summary>Vertical placement of a label within its region (legacy "Vertical justification").</summary>
public enum OverlayVJust { Top, Center, Bottom }

/// <summary>
/// What to do when a label's text does not fit its region at the base font size.
/// Mirrors the legacy script's "Font sizing (if too large)" option
/// (sg-goobie-MFD.scm): <see cref="Fit"/> shrinks the font to fit (auto-fit),
/// <see cref="Crop"/> keeps the size and clips to the region, <see cref="Overflow"/>
/// keeps the size and lets the text spill outside the region.
/// </summary>
public enum OverlaySizeMode { Fit, Crop, Overflow }

/// <summary>
/// One labelled cell on a cockpit template: the rectangle (and font) a label is
/// laid out within. Equivalent to a named text layer in the legacy GIMP template
/// (layer name = <see cref="Name"/>, e.g. a RIO address tag like <c>b-00</c>); the
/// layer's offsets/size/font gave the cell geometry. Geometry is shared by all
/// profiles for a given cockpit image; only the label <em>text</em> is per-profile.
/// </summary>
public sealed class OverlayRegion
{
    /// <summary>Region key — matches the template layer name and the profile's label key.</summary>
    public string Name { get; set; } = "";

    /// <summary>Cell left edge, in template pixels.</summary>
    public double X { get; set; }

    /// <summary>Cell top edge, in template pixels.</summary>
    public double Y { get; set; }

    /// <summary>Cell width, in template pixels.</summary>
    public double Width { get; set; }

    /// <summary>Cell height, in template pixels.</summary>
    public double Height { get; set; }

    /// <summary>Font family for this cell's text.</summary>
    public string FontFamily { get; set; } = "Sans";

    /// <summary>Base font size (px) from the template; the starting point before any auto-fit.</summary>
    public double FontSizePx { get; set; } = 12;

    /// <summary>Text color as <c>#RRGGBB</c>/<c>#AARRGGBB</c>; null = renderer default.</summary>
    public string? ColorHex { get; set; }

    /// <summary>Per-region horizontal justification override; null = use the engine default.</summary>
    public OverlayHJust? HJust { get; set; }

    /// <summary>Per-region vertical justification override; null = use the engine default.</summary>
    public OverlayVJust? VJust { get; set; }

    /// <summary>
    /// Counter-clockwise rotation of the label in degrees; null/0 = upright. Used
    /// for cockpit cells whose labels read sideways (e.g. the vertically-oriented
    /// button column). Rotated labels are centered in the cell (justification N/A).
    /// </summary>
    public double? RotationDegrees { get; set; }
}

/// <summary>
/// A cockpit overlay template: the base image plus the labelled regions, extracted
/// once from the source artwork (docs/reference/customBackground/riojoy.xcf) into a
/// <c>regions.json</c>. Persisted by <see cref="OverlayTemplateStore"/>.
/// </summary>
public sealed class OverlayTemplate
{
    /// <summary>Path to the base cockpit image the labels are drawn over.</summary>
    public string? BaseImagePath { get; set; }

    /// <summary>Base image width in pixels (the output wallpaper size).</summary>
    public int Width { get; set; }

    /// <summary>Base image height in pixels.</summary>
    public int Height { get; set; }

    /// <summary>The labelled cells.</summary>
    public List<OverlayRegion> Regions { get; set; } = new();

    /// <summary>Find a region by name (case-insensitive), or null.</summary>
    public OverlayRegion? FindRegion(string name) =>
        Regions.FirstOrDefault(r => string.Equals(r.Name, name, StringComparison.OrdinalIgnoreCase));
}

/// <summary>
/// A laid-out label ready to rasterize: the resolved text, top-left position,
/// measured size, and the (possibly auto-fitted) font. The renderer just draws it.
/// </summary>
public readonly record struct PlacedLabel(
    string RegionName,
    string Text,
    double X,
    double Y,
    double Width,
    double Height,
    string FontFamily,
    double FontSizePx,
    double RotationDegrees = 0);

/// <summary>Engine-wide defaults for a layout pass; per-region overrides win.</summary>
public sealed class OverlayLayoutOptions
{
    /// <summary>How to handle text that overflows its region at the base size.</summary>
    public OverlaySizeMode SizeMode { get; set; } = OverlaySizeMode.Fit;

    /// <summary>Default horizontal justification (regions may override).</summary>
    public OverlayHJust HJust { get; set; } = OverlayHJust.Center;

    /// <summary>Default vertical justification (regions may override).</summary>
    public OverlayVJust VJust { get; set; } = OverlayVJust.Center;
}
