Editor/sandmod.libraryplus/Widget/ReferenceDialog.cs
using System;
using Editor;

namespace LibraryPlus;

#nullable enable

public sealed class ReferenceDialog : Dialog
{
	private readonly Action<Reference> OnSubmit;
	private readonly LineEdit Reference;
	private readonly LineEdit VersionMax;
	private readonly LineEdit VersionMin;

	private ReferenceDialog( string title, Action<Reference> onSubmit,
		(string? ident, Version? min, Version? max) data, string action = "Save" )
	{
		OnSubmit = onSubmit;

		Window.Title = title;
		Window.SetWindowIcon( "tune" );
		Window.Size = new Vector2( 400, 150 );

		Layout = Layout.Column();
		Layout.Margin = 16;

		var editLayout = Layout.Grid();
		editLayout.VerticalSpacing = 2;
		editLayout.HorizontalSpacing = 16;
		editLayout.AddCell( 0, 0, new Label( "Reference" ) );
		Reference = editLayout.AddCell( 1, 0,
			new LineEdit
			{
				PlaceholderText = "example.reference", RegexValidator = "^([a-zA-Z0-9_-]+)\\.([a-zA-Z0-9_-]+)$"
			} );
		Reference.Value = data.ident;
		editLayout.AddCell( 0, 1, new Label( "Version Min" ) );
		VersionMin = editLayout.AddCell( 1, 1,
			new LineEdit { PlaceholderText = "1.0.0", RegexValidator = "^(\\d+)\\.(\\d+)\\.(\\d+)$" } );
		VersionMin.Value = data.min?.ToString();
		editLayout.AddCell( 0, 2, new Label( "Version Max (optional)" ) );
		VersionMax = editLayout.AddCell( 1, 2,
			new LineEdit { PlaceholderText = "1.0.0", RegexValidator = "^(\\d+)\\.(\\d+)\\.(\\d+)$" } );
		VersionMax.Value = data.max?.ToString();
		Layout.Add( editLayout );

		Layout.AddStretchCell();

		var actionLayout = Layout.Row();
		actionLayout.Spacing = 8;
		actionLayout.AddStretchCell();
		actionLayout.Add( new Button( action ) { Pressed = Submit } );
		actionLayout.Add( new Button( "Cancel" ) { Pressed = Close } );

		Layout.Add( actionLayout );
	}

	public static void Open( string title, Action<Reference> onSubmit,
		string action = "Save" )
	{
		var dialog = new ReferenceDialog( title, onSubmit, (null, null, null), action );
		dialog.Show();
	}

	public static void Open( string title, Action<Reference> onSubmit,
		(string? ident, Version? min, Version? max) data,
		string action = "Save" )
	{
		var dialog = new ReferenceDialog( title, onSubmit, data, action );
		dialog.Show();
	}

	private void Submit()
	{
		if ( string.IsNullOrWhiteSpace( Reference.Value ) || string.IsNullOrWhiteSpace( VersionMin.Value ) )
		{
			return;
		}

		if ( !Version.TryParse( VersionMin.Value, out var versionMin ) )
		{
			return;
		}

		Version? versionMax = null;
		if ( !string.IsNullOrWhiteSpace( VersionMax.Value ) &&
		     !Version.TryParse( VersionMax.Value, out versionMax ) )
		{
			return;
		}

		OnSubmit( new Reference( Reference.Value, versionMin, versionMax ) );
		Close();
	}
}