using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Theriapolis.Game.CodexUI.Core;

/// <summary>
/// Renders a 9-slice texture into an arbitrary destination rectangle: the
/// four corners stay at their authored size, the four edges stretch along
/// one axis, and the centre stretches both axes. Used for parchment cards,
/// gilded borders, button backgrounds, and slot frames.
///
/// Per-side inset values describe how many source-texture pixels the
/// fixed-size corner+edge bands take. They must add up to less than the
/// source texture's width/height in each axis or the centre band collapses.
/// </summary>
public readonly struct NineSliceInsets
{
    public readonly int Left, Top, Right, Bottom;

    public NineSliceInsets(int uniform) : this(uniform, uniform, uniform, uniform) { }
    public NineSliceInsets(int l, int t, int r, int b) { Left = l; Top = t; Right = r; Bottom = b; }
}

public static class NineSlice
{
    /// <summary>
    /// Draw a 9-slice <paramref name="texture"/> tinted with <paramref name="tint"/>
    /// into <paramref name="dest"/> using <paramref name="insets"/> as the corner sizes.
    /// </summary>
    public static void Draw(SpriteBatch sb, Texture2D texture, Rectangle dest,
                            NineSliceInsets insets, Color tint)
    {
        int sw = texture.Width;
        int sh = texture.Height;
        int l = insets.Left, t = insets.Top, r = insets.Right, b = insets.Bottom;
        int cw = sw - l - r;  // source center width
        int ch = sh - t - b;  // source center height
        if (cw < 1) cw = 1;
        if (ch < 1) ch = 1;

        int dl = dest.X;
        int dt = dest.Y;
        int dcw = System.Math.Max(0, dest.Width  - l - r);
        int dch = System.Math.Max(0, dest.Height - t - b);
        int dr = dest.X + dest.Width  - r;
        int db = dest.Y + dest.Height - b;

        // Corners (1× scale)
        sb.Draw(texture, new Rectangle(dl, dt, l, t),                    new Rectangle(0,         0,        l, t),  tint);
        sb.Draw(texture, new Rectangle(dr, dt, r, t),                    new Rectangle(sw - r,    0,        r, t),  tint);
        sb.Draw(texture, new Rectangle(dl, db, l, b),                    new Rectangle(0,         sh - b,   l, b),  tint);
        sb.Draw(texture, new Rectangle(dr, db, r, b),                    new Rectangle(sw - r,    sh - b,   r, b),  tint);

        // Edges (stretched along their long axis)
        sb.Draw(texture, new Rectangle(dl + l, dt,     dcw, t),          new Rectangle(l,         0,        cw, t),  tint);
        sb.Draw(texture, new Rectangle(dl + l, db,     dcw, b),          new Rectangle(l,         sh - b,   cw, b),  tint);
        sb.Draw(texture, new Rectangle(dl,     dt + t, l,   dch),        new Rectangle(0,         t,        l,  ch), tint);
        sb.Draw(texture, new Rectangle(dr,     dt + t, r,   dch),        new Rectangle(sw - r,    t,        r,  ch), tint);

        // Centre (stretched both axes)
        sb.Draw(texture, new Rectangle(dl + l, dt + t, dcw, dch),        new Rectangle(l,         t,        cw, ch), tint);
    }
}
