Editor/InteriorLayoutBuilder/RoomLayoutControls.Floors.cs
using System;
using System.Globalization;
using Editor;

namespace ReusableRoomLayout;

internal sealed partial class RoomLayoutControls
{
	private LineEdit activeFloorEdit;
	private LineEdit floorSpacingEdit;
	private Button moveSelectedFloorButton;

	private void AddFloorSection( Widget parent )
	{
		var floorRow = AddRow( parent );
		activeFloorEdit = AddCompactIntEdit( floorRow, "Active Floor", "0", OnActiveFloorEdited );
		AddButton( floorRow, "Previous", "keyboard_arrow_down", OnPreviousFloorClicked, SmallActionButtonWidth );
		AddButton( floorRow, "Next", "keyboard_arrow_up", OnNextFloorClicked, SmallActionButtonWidth );

		var spacingRow = AddRow( parent );
		floorSpacingEdit = AddCompactFloatEdit( spacingRow, "Floor Spacing", "auto", OnFloorSpacingEdited );
		moveSelectedFloorButton = AddButton( spacingRow, "Move Selected", "drive_file_move", OnMoveSelectedToFloorClicked, DefaultMaterialsButtonWidth );
		moveSelectedFloorButton.ToolTip = "Move the selected room, corridor, or selected opening's parent to the active floor.";
	}

	private void UpdateFloorControls( RoomLayoutTool tool )
	{
		if ( moveSelectedFloorButton is not null )
		{
			moveSelectedFloorButton.Enabled = tool?.CanMoveSelectedToActiveFloor == true;
		}

		UpdateIntEdit( activeFloorEdit, tool, tool?.ActiveFloor );
		UpdateFloatEdit( floorSpacingEdit, tool, tool?.FloorSpacing );
	}

	private LineEdit AddCompactIntEdit( Layout row, string labelText, string placeholder, Action action, int labelWidth = FieldLabelWidth )
	{
		return AddCompactFloatEdit( row, labelText, placeholder, action, labelWidth );
	}

	private static void UpdateIntEdit( LineEdit edit, RoomLayoutTool tool, int? value )
	{
		if ( edit is null )
		{
			return;
		}

		edit.ReadOnly = tool is null;
		if ( tool is not null && value.HasValue && !edit.IsFocused )
		{
			edit.Value = value.Value.ToString( CultureInfo.InvariantCulture );
		}
	}

	private void OnActiveFloorEdited()
	{
		if ( TryReadIntEdit( activeFloorEdit, out var floor ) )
		{
			GetTool()?.SetActiveFloor( floor );
		}
	}

	private void OnPreviousFloorClicked()
	{
		GetTool()?.StepActiveFloor( -1 );
	}

	private void OnNextFloorClicked()
	{
		GetTool()?.StepActiveFloor( 1 );
	}

	private void OnFloorSpacingEdited()
	{
		if ( TryReadFloatEdit( floorSpacingEdit, out var spacing ) )
		{
			GetTool()?.SetFloorSpacing( spacing );
		}
	}

	private void OnMoveSelectedToFloorClicked()
	{
		GetTool()?.MoveSelectedToActiveFloor();
	}

	private static bool TryReadIntEdit( LineEdit edit, out int value )
	{
		value = 0;
		var text = edit?.Value?.Trim();
		return !string.IsNullOrEmpty( text ) &&
			int.TryParse( text, NumberStyles.Integer, CultureInfo.InvariantCulture, out value );
	}
}