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

namespace Theriapolis.Game.CodexUI.Core;

/// <summary>
/// Base class for every CodexUI widget. Layout is two-pass:
///   1. <see cref="Measure"/> — child reports a desired size given an
///      available size envelope.
///   2. <see cref="Arrange"/> — parent places the child by writing into
///      <see cref="Bounds"/>; the child propagates to its own children.
///
/// Update + Draw run after layout. Hit-testing uses screen-space
/// <see cref="Bounds"/> directly via <see cref="ContainsPoint"/>.
/// </summary>
public abstract class CodexWidget
{
    public Rectangle Bounds { get; protected set; }
    public bool Visible { get; set; } = true;
    public bool Enabled { get; set; } = true;
    public CodexWidget? Parent { get; internal set; }

    public Point DesiredSize { get; protected set; }

    /// <summary>Child reports its preferred size; parent decides whether to honour it.</summary>
    public Point Measure(Point available)
    {
        DesiredSize = MeasureCore(available);
        return DesiredSize;
    }

    /// <summary>Parent commits a final rectangle; child propagates to grandchildren.</summary>
    public void Arrange(Rectangle bounds)
    {
        Bounds = bounds;
        ArrangeCore(bounds);
    }

    protected abstract Point MeasureCore(Point available);
    protected abstract void  ArrangeCore(Rectangle bounds);

    public virtual void Update(GameTime gt, CodexInput input) { }
    public virtual void Draw(SpriteBatch sb, GameTime gt) { }

    /// <summary>True if a screen-space point lies inside our bounds. Hover-/click-test helper.</summary>
    public bool ContainsPoint(Point p) => Bounds.Contains(p);
}
