Code/Demos/TarkovInventory/StashTileBlob.cs
using System;
using Goo;
using Sandbox;
using Sandbox.UI;
using static Sandbox.TarkovInventory.StashTheme;

namespace Sandbox.TarkovInventory;

// Pure presenters for a stash item: the three-row grid tile and the drag ghost. No state lives
// here - the item, its footprint rect, the drag/rotation flags and the split click all arrive as
// arguments (the PadBlob idiom). Sizes/colors/fonts/geometry come from StashTheme (using static).
internal static class StashTileBlob
{
    // Three stacked rows: item name on top, the SVG glyph in the middle, the amount on the bottom. The
    // labels own their rows (no overlay) so the stack count stays legible and never occludes the glyph.
    public static Container Tile( StashItem item, GridRect rect, bool dragging, bool rotated, Action<MousePanelEvent> onClick ) => new Container
    {
        Position = PositionMode.Relative,
        Width = rect.W * SlotSize, Height = rect.H * SlotSize,
        BackgroundColor = KindTint( item.Kind ),
        BorderRadius = 5f,
        BorderWidth = 1f,
        BorderColor = ItemBdr,
        Opacity = dragging ? 0.35f : 1f,
        FlexDirection = FlexDirection.Column,
        JustifyContent = Justify.SpaceBetween,
        AlignItems = Align.Center,
        PointerEvents = PointerEvents.All,
        OnClick = onClick,
        Children =
        {
            NameRow( item, rect ),
            IconCell( item, rect, rotated ),
            CountRow( item ),
        },
    };

    // Top row: the item name (full on wide tiles, the Short abbreviation on 1-wide tiles so it fits).
    static Container NameRow( StashItem item, GridRect rect ) => new Container
    {
        Key = "name",
        Width = Length.Percent( 100 ),
        JustifyContent = Justify.Center,
        AlignItems = Align.Center,
        PaddingTop = 2f, PaddingLeft = 3f, PaddingRight = 3f,
        Overflow = OverflowMode.Hidden,
        PointerEvents = PointerEvents.None,
        Children = { new Text( rect.W >= 2 ? item.Name : item.Short ) { Key = "t", FontColor = Title, FontFamily = LabelFont, FontSize = 16f } },
    };

    // Middle row: the SVG glyph, centered, sized to the space left between the name and amount rows.
    static Container IconCell( StashItem item, GridRect rect, bool rotated ) => new Container
    {
        Key = "icon-cell",
        JustifyContent = Justify.Center,
        AlignItems = Align.Center,
        PointerEvents = PointerEvents.None,
        Children =
        {
            new Goo.SvgPanel { Key = "icon", Path = item.Icon, Color = IconTint,
                Width = IconRowSide( rect ), Height = IconRowSide( rect ),
                Transform = rotated ? Goo.PanelTransform.Rotate( 90f ) : (Goo.PanelTransform?)null },
        },
    };

    // Bottom row: the stack amount, always shown so every tile keeps the same three-row shape.
    static Container CountRow( StashItem item ) => new Container
    {
        Key = "count",
        Width = Length.Percent( 100 ),
        JustifyContent = Justify.Center,
        AlignItems = Align.Center,
        PaddingBottom = 2f,
        PointerEvents = PointerEvents.None,
        Children = { new Text( $"x{item.Count}" ) { Key = "t", FontColor = Title, FontFamily = LabelFont, FontSize = 18f, FontWeight = 700 } },
    };

    // The translucent drag ghost: just the glyph on a faint blue plate, sized to the rotated footprint.
    public static Container Ghost( StashItem item, bool rotated )
    {
        var (w, h) = Eff( item, rotated );
        var rect = new GridRect( 0, 0, w, h );
        return new Container
        {
            Width = w * SlotSize, Height = h * SlotSize,
            BackgroundColor = new Color( 0.4f, 0.7f, 1f, 0.25f ),
            BorderRadius = 5f,
            Opacity = 0.85f,
            JustifyContent = Justify.Center,
            AlignItems = Align.Center,
            Children =
            {
                new Goo.SvgPanel { Key = "icon", Path = item.Icon, Color = IconTint,
                    Width = IconSide( rect ), Height = IconSide( rect ),
                    Transform = rotated ? Goo.PanelTransform.Rotate( 90f ) : (Goo.PanelTransform?)null },
            },
        };
    }
}