Code/UI/Components/NumericEdit.razor
@using Sandbox.UI
@inherits Panel
@implements IEdit
@implements IGraphStyle
@namespace Nodebox.UI

<root>
    @if (IsSupported(Type)) {
        <TextEntry
            Numeric=@true
            Value=@(Value?.ToString() ?? "0")
            Placeholder=@("0")
            CharacterRegex=@(Regex)
            @ref=TextEntryRef/>
    }
</root>

@code
{
    public TextEntry TextEntryRef { get; protected set; }

    public string TooltipOverride { get; set; }

    public string Text => TextEntryRef?.Text;
    
    [Change(nameof(OnValueChanged))]
    public object Value { get; set; }
    public object ValueImmediate => Type switch {
        var x when x == typeof(float) => (object)float.SafeParse(Text),
        var x when x == typeof(double) => (object)double.SafeParse(Text),
        var x when x == typeof(int) => (object)int.SafeParse(Text),
        var x when x == typeof(long) => (object)long.SafeParse(Text),
        var x when x == typeof(uint) => (object)uint.SafeParse(Text),
        var x when x == typeof(ulong) => (object)ulong.SafeParse(Text),
        var x when x == typeof(byte) => (object)byte.SafeParse(Text),
        _ => throw new NotImplementedException(),
    };
    public void OnValueChanged(object oldValue, object newValue) {
        if (newValue == null) { return; }
        Assert.AreEqual(newValue.GetType(), Type, $"{newValue.GetType()} =/= {Type}");
        TextEntryRef?.Text = newValue?.ToString();
    }
    public Type Type { get; set; }

    public string Regex => Type switch {
        var x when x == typeof(float) => "[0-9\\-\\.]",
        var x when x == typeof(double) => "[0-9\\-\\.]",
        var x when x == typeof(int) => "[0-9\\-]",
        var x when x == typeof(long) => "[0-9\\-]",
        var x when x == typeof(uint) => "[0-9]",
        var x when x == typeof(ulong) => "[0-9]",
        var x when x == typeof(byte) => "[0-9]",
        _ => throw new NotImplementedException(),
    };

    public static bool IsSupported(Type type) => type switch {
        var x when x == typeof(float) => true,
        var x when x == typeof(double) => true,
        var x when x == typeof(int) => true,
        var x when x == typeof(long) => true,
        var x when x == typeof(uint) => true,
        var x when x == typeof(ulong) => true,
        var x when x == typeof(byte) => true,
        _ => false,
    };

    protected override void OnAfterTreeRender(bool firstTime) {
        Tooltip = TooltipOverride == null ? this.ConstructTooltip() : TooltipOverride;
        TextEntryRef?.Tooltip = Tooltip;
        TextEntryRef?.Children?.First()?.Tooltip = Tooltip;

        if (firstTime) {
            Value ??= TypeLibrary.GetType(Type).CreateDefault();
        }

        if (!firstTime) { return; }

        
        if (TextEntryRef.IsValid()) {
            OnValueChanged(null, Value);

            TextEntryRef.AddEventListener("onchange", (ev) => {
                ev.StopPropagation();
                var snd = Sound.PlayFile(SoundFile.Load("sounds/kenney/ui/click_002.vsnd_c"), 0.05f, 1.5f);
                snd.TargetMixer = Sandbox.Audio.Mixer.FindMixerByName("UI");
                snd.ListenLocal = true;
                CreateEvent("onchange", ValueImmediate);
                
                Tooltip = TooltipOverride == null ? this.ConstructTooltip() : TooltipOverride;
                TextEntryRef?.Tooltip = Tooltip;
                TextEntryRef?.Children?.First()?.Tooltip = Tooltip;
            });

            TextEntryRef.AddEventListener("onblur", (ev) => {
                ev.StopPropagation();
                Value = ValueImmediate;
                CreateEvent("onsubmit", Value);
            });

            @* TextEntryRef.AddEventListener("oncancel", (ev) => {
                ev.StopPropagation();
                OnValueChanged(null, Value);
                CreateEvent("oncancel", Value);
            }); *@
        }
    }

    protected override int BuildHash() => System.HashCode.Combine( Type );
}