Code/UI/Components/PinRefButton.razor
@inherits Button
@implements IGraphStyle
@namespace Nodebox.UI

<root class="@(Flow == Flow.Output ? "output" : "input")">
    <div class="pin-container">
        <PinButton
            Tooltip=@(DisplayInfo.ForGenericType(Type).Name)
            Color=@(Color)
            Shape=@(Shape)
            Node=@(Node)
            Flow=@(Flow)
            Index=@(Index)
            @ref=PinButton/>
    </div>
    @if (Name != null && Name != "")
    {
        <div class="pin-name-container">
            @Name
        </div>
    }
    @if (NeedsInput)
    {
        <div class="pin-input-container">
            <Edit Type=@(Type) Value=@(PinRef.Value) @ref=EditRef/>
        </div>
    }
</root>

@code
{
    public PinButton PinButton { get; set; }

    public Edit EditRef { get; set; }

    public Color Color => this.GraphStyle.TypePalette.Get(Type).Color;
    public PinShape Shape => this.GraphStyle.TypePalette.Get(Type).Shape;

    public PinRef PinRef {
        get => new(Node, Flow, Index);
        set {
            Node = value.Node;
            Flow = value.Flow;
            Index = value.Index;
            Type = value.Type;
            Name = value.Name;
            Description = value.Description;
        }
    }

    private WeakReference<Node> WeakNode { get; set; } = new(null);
    public Node Node {
        get {
            WeakNode.TryGetTarget(out var target);
            return target;
        }
        set {
            WeakNode.SetTarget(value);
        }
    }

    public Flow Flow { get; set; } = Flow.Input;
    public PinIndex Index { get; set; } = 0;
    public Type Type { get; set; } = null;
    public string Name { get; set; } = null;
    public string Description { get; set; } = null;

    public Panel Input { get; protected set; }
    protected override void OnAfterTreeRender(bool firstTime) {
        Tooltip = DisplayInfo.ForGenericType(Type).Name;

        if (!firstTime) { return; }

        AddEventListener("onsubmit", () => {
            Assert.AreEqual(EditRef.Value.GetType(), Type);
            Node?[Index] = EditRef.Value;
        });
    }

    public bool IsConnected => PinRef.Wires == null ? false : PinRef.Wires.Count > 0;
    public bool NeedsInput => Flow == Flow.Input && !IsConnected && !PinRef.HideInput;

    protected override int BuildHash() => System.HashCode.Combine(
        Node, Node.Generation
    );
}