Editor/SuiSampleGenerator.cs
using System.Collections.Generic;
using SboxUiDesigner.Runtime;

namespace SboxUiDesigner.EditorUi;

/// <summary>
/// Generates the canonical sample .sui documents (PRD doc 14 § Sample projects).
/// Used by the Tools menu "Install Samples" action — produces fully-formed
/// <see cref="SuiDocument"/> instances the user can save as assets.
///
/// Each sample exercises a different slice of the schema:
/// - <see cref="BuildSimplePanel"/> — anchor/pivot, panel + text basics
/// - <see cref="BuildInventoryBasic"/> — InventoryGrid + InventorySlot composition
/// - <see cref="BuildHotbarBasic"/> — Hotbar (HorizontalBox flex) + ItemIcon
/// - <see cref="BuildHudSurvival"/> — composite HUD: ProgressBar + Text + Image
/// </summary>
public static class SuiSampleGenerator
{
	public static IReadOnlyList<(string Name, SuiDocument Doc)> All()
	{
		return new List<(string, SuiDocument)>
		{
			("simple_panel", BuildSimplePanel()),
			("inventory_basic", BuildInventoryBasic()),
			("hotbar_basic", BuildHotbarBasic()),
			("hud_survival", BuildHudSurvival()),
		};
	}

	// ─────────────────────────────────────────────────────────────────────
	//  simple_panel — minimal panel + centered text
	// ─────────────────────────────────────────────────────────────────────
	public static SuiDocument BuildSimplePanel()
	{
		var doc = SuiDocument.CreateDefault( "simple_panel" );
		doc.Output.ClassName = "SimplePanel";

		var root = doc.GetRoot();
		var panel = AddChild( doc, root, SuiElementType.Panel, "Panel", absolute: true );
		panel.Layout.Width = 480;
		panel.Layout.Height = 240;
		panel.Layout.Anchor = SuiAnchor.MiddleCenter;
		panel.Layout.PivotX = 0.5f;
		panel.Layout.PivotY = 0.5f;
		panel.Style.BackgroundColor = "#1f2937";
		panel.Style.BorderColor = "#3b82f6";
		panel.Style.BorderWidth = 2;
		panel.Style.BorderRadius = 6;

		var text = AddChild( doc, panel, SuiElementType.Text, "Title", absolute: true );
		text.Layout.Width = 400;
		text.Layout.Height = 32;
		text.Layout.Anchor = SuiAnchor.MiddleCenter;
		text.Layout.PivotX = 0.5f;
		text.Layout.PivotY = 0.5f;
		text.Props.Text = "Hello, s&box UI Designer!";
		text.Props.FontSize = 24;
		text.Props.FontWeight = SuiFontWeight.Bold;
		text.Props.Color = "#e5e7eb";
		text.Props.TextAlign = SuiTextAlign.Center;

		return doc;
	}

	// ─────────────────────────────────────────────────────────────────────
	//  inventory_basic — 5×3 grid of inventory slots
	// ─────────────────────────────────────────────────────────────────────
	public static SuiDocument BuildInventoryBasic()
	{
		var doc = SuiDocument.CreateDefault( "inventory_basic" );
		doc.Output.ClassName = "InventoryBasic";

		var root = doc.GetRoot();
		var window = AddChild( doc, root, SuiElementType.Panel, "InventoryWindow", absolute: true );
		window.Layout.Width = 540;
		window.Layout.Height = 360;
		window.Layout.Anchor = SuiAnchor.MiddleCenter;
		window.Layout.PivotX = 0.5f;
		window.Layout.PivotY = 0.5f;
		window.Style.BackgroundColor = "#0b1220";
		window.Style.BorderColor = "#475569";
		window.Style.BorderWidth = 2;
		window.Style.BorderRadius = 8;

		var title = AddChild( doc, window, SuiElementType.Text, "Title", absolute: true );
		title.Layout.X = 0;
		title.Layout.Y = 8;
		title.Layout.Width = 540;
		title.Layout.Height = 32;
		title.Layout.Anchor = SuiAnchor.TopCenter;
		title.Layout.PivotX = 0.5f;
		title.Props.Text = "Inventory";
		title.Props.FontSize = 20;
		title.Props.FontWeight = SuiFontWeight.SemiBold;
		title.Props.Color = "#e5e7eb";
		title.Props.TextAlign = SuiTextAlign.Center;

		// InventoryGrid is flex+row+wrap by default (ApplyTypeDefaults), so
		// children flow into a grid. Width allows 5 slots @ 80px + 4 gaps @ 12px = 448 px.
		var grid = AddChild( doc, window, SuiElementType.InventoryGrid, "Slots", absolute: false );
		grid.Layout.Width = 448;
		grid.Layout.Height = 280;
		grid.Layout.X = 20;
		grid.Layout.Y = 56;
		grid.Layout.Anchor = SuiAnchor.TopLeft;
		grid.Layout.Gap = 12;
		grid.Props.Columns = 5;
		grid.Props.Rows = 3;
		grid.Props.CellWidth = 80;
		grid.Props.CellHeight = 80;
		grid.Props.GridGap = 12;

		// 15 slots in a 5×3 grid (flex layout — children inherit cell sizes from grid props)
		for ( int i = 0; i < 15; i++ )
		{
			var slot = AddChild( doc, grid, SuiElementType.InventorySlot, $"Slot_{i + 1}", absolute: false );
			slot.Layout.Width = 80;
			slot.Layout.Height = 80;
			slot.Style.BackgroundColor = "#1e293b";
			slot.Style.BorderColor = "#475569";
			slot.Style.BorderWidth = 1;
			slot.Style.BorderRadius = 4;
		}

		return doc;
	}

	// ─────────────────────────────────────────────────────────────────────
	//  hotbar_basic — bottom-anchored row of 9 slots
	// ─────────────────────────────────────────────────────────────────────
	public static SuiDocument BuildHotbarBasic()
	{
		var doc = SuiDocument.CreateDefault( "hotbar_basic" );
		doc.Output.ClassName = "HotbarBasic";

		var root = doc.GetRoot();
		var hotbar = AddChild( doc, root, SuiElementType.Hotbar, "Hotbar", absolute: false );
		hotbar.Layout.Mode = SuiLayoutMode.Flex;
		hotbar.Layout.FlexDirection = SuiFlexDirection.Row;
		hotbar.Layout.JustifyContent = SuiJustifyContent.Center;
		hotbar.Layout.AlignItems = SuiAlignItems.Center;
		hotbar.Layout.Gap = 8;
		hotbar.Layout.Width = 800;
		hotbar.Layout.Height = 80;
		hotbar.Layout.Anchor = SuiAnchor.BottomCenter;
		hotbar.Layout.Y = 24;
		hotbar.Layout.PivotX = 0.5f;
		hotbar.Layout.PivotY = 1f;

		for ( int i = 0; i < 9; i++ )
		{
			var slot = AddChild( doc, hotbar, SuiElementType.InventorySlot, $"Slot_{i + 1}", absolute: false );
			slot.Layout.Width = 64;
			slot.Layout.Height = 64;
			slot.Style.BackgroundColor = "#0f172a";
			slot.Style.BorderColor = i == 0 ? "#3b82f6" : "#475569";
			slot.Style.BorderWidth = i == 0 ? 2 : 1;
			slot.Style.BorderRadius = 4;
		}

		return doc;
	}

	// ─────────────────────────────────────────────────────────────────────
	//  hud_survival — top-left HUD with HP/Stamina/Hunger bars + label
	// ─────────────────────────────────────────────────────────────────────
	public static SuiDocument BuildHudSurvival()
	{
		var doc = SuiDocument.CreateDefault( "hud_survival" );
		doc.Output.ClassName = "HudSurvival";

		var root = doc.GetRoot();

		// Container — top-left, vertical stack of bars
		var hud = AddChild( doc, root, SuiElementType.VerticalBox, "HudContainer", absolute: false );
		hud.Layout.Mode = SuiLayoutMode.Flex;
		hud.Layout.FlexDirection = SuiFlexDirection.Column;
		hud.Layout.AlignItems = SuiAlignItems.Stretch;
		hud.Layout.Gap = 8;
		hud.Layout.Width = 280;
		hud.Layout.Height = 120;
		hud.Layout.Anchor = SuiAnchor.TopLeft;
		hud.Layout.X = 32;
		hud.Layout.Y = 32;

		AddBar( doc, hud, "Health", "#ef4444", 100 );
		AddBar( doc, hud, "Stamina", "#22c55e", 75 );
		AddBar( doc, hud, "Hunger", "#f59e0b", 60 );

		return doc;

		static void AddBar( SuiDocument d, SuiElement parent, string label, string fillColor, float value )
		{
			var row = AddChild( d, parent, SuiElementType.HorizontalBox, label + "_Row", absolute: false );
			row.Layout.Mode = SuiLayoutMode.Flex;
			row.Layout.FlexDirection = SuiFlexDirection.Row;
			row.Layout.AlignItems = SuiAlignItems.Center;
			row.Layout.Gap = 8;
			row.Layout.Width = 280;
			row.Layout.Height = 24;

			var lbl = AddChild( d, row, SuiElementType.Text, label + "_Label", absolute: false );
			lbl.Layout.Width = 80;
			lbl.Layout.Height = 24;
			lbl.Props.Text = label;
			lbl.Props.FontSize = 14;
			lbl.Props.FontWeight = SuiFontWeight.SemiBold;
			lbl.Props.Color = "#e5e7eb";
			lbl.Props.TextAlign = SuiTextAlign.Left;

			var bar = AddChild( d, row, SuiElementType.ProgressBar, label + "_Bar", absolute: false );
			bar.Layout.Width = 192;
			bar.Layout.Height = 16;
			bar.Style.BackgroundColor = "#1f2937";
			bar.Style.BorderColor = "#374151";
			bar.Style.BorderWidth = 1;
			bar.Style.BorderRadius = 4;
			bar.Props.ProgressMin = 0;
			bar.Props.ProgressMax = 100;
			bar.Props.ProgressPreviewValue = value;
			bar.Props.ProgressFillColor = fillColor;
		}
	}

	// ─────────────────────────────────────────────────────────────────────
	//  Helper — add a child element under parent with sensible defaults.
	// ─────────────────────────────────────────────────────────────────────
	private static SuiElement AddChild( SuiDocument doc, SuiElement parent, SuiElementType type, string name, bool absolute )
	{
		var el = new SuiElement
		{
			Id = SuiDocument.NewElementId(),
			Name = name,
			Type = type,
			ParentId = parent.Id,
		};
		el.ApplyTypeDefaults();
		if ( absolute ) el.Layout.Mode = SuiLayoutMode.Absolute;
		el.Style.ClassName = SuiDocumentValidator.SanitizeClassName( name );

		parent.Children.Add( el.Id );
		doc.Elements.Add( el );
		return el;
	}
}