UI/SpawnMenu/ToolsTab.razor
@using Sandbox;
@using Sandbox.UI;
@inherits Panel
@namespace Sandbox
@implements IUtilityTab
@attribute [Icon( "🔧" )]
@attribute [Title( "#spawnmenu.tab.tools" )]
@attribute [Order( -100 )]

<root class="tab">
	<div class="left">
        <VerticalMenu Value="@(CurrentMode?.GetType())"  class="menuinner">
            <Options>
                @foreach (var group in Game.TypeLibrary.GetTypes<ToolMode>().GroupBy(x => x.Group).OrderBy( x => x.Key ) )
                {
                    @if ( !string.IsNullOrWhiteSpace( group.Key ) )
                    {
                        <h2>@group.Key</h2>
                    }

                    @foreach (var type in group.OrderBy(x => x.Title))
                    {
                        if (type.IsAbstract) continue;

                        <MenuOption Text="@type.Title" Icon="@type.Icon" @onclick="@(() => SwitchMode(type))" Value="@type.TargetType"></MenuOption>
                    }
                }
            </Options>
        </VerticalMenu>
	</div>

    <div class="body menuinner">
        @if ( PostProcessManager?.GetSelectedComponents().Count > 0 )
        {
            @foreach ( var component in PostProcessManager.GetSelectedComponents() )
            {
                <h2>@(Game.TypeLibrary.GetType( component.GetType() )?.Title ?? component.GetType().Name)</h2>
                <ControlSheet Target="@component" PropertyFilter="@FilterProperties"></ControlSheet>
            }
        }
        else
        {
            <ControlSheet PropertyFilter="@FilterProperties" Target="@GetCurrentMode()"></ControlSheet>
        }
	</div>

</root>

@code
{
    ToolMode CurrentMode => Player.FindLocalPlayer()?.GetWeapon<Toolgun>()?.GetCurrentMode();
    PostProcessManager PostProcessManager => Game.ActiveScene.GetSystem<PostProcessManager>();

    protected override int BuildHash() => HashCode.Combine(CurrentMode, PostProcessManager?.SelectedPath, PostProcessManager?.GetSelectedComponents().Count);

	bool IsActiveMode( TypeDescription t )
	{
		var localPlayer = Player.FindLocalPlayer();
		var toolgun = localPlayer?.GetWeapon<Toolgun>();
		if (!toolgun.IsValid()) return false;

		return toolgun.GetCurrentMode()?.GetType() == t.TargetType;
	}

	void SwitchMode(TypeDescription t)
	{
		var localPlayer = Player.FindLocalPlayer();
		if ( localPlayer == null ) return;

		PostProcessManager?.Deselect();

		var inventory = localPlayer.GetComponent<PlayerInventory>();
		if ( !inventory.IsValid() ) return;

		inventory.SetToolMode( t.ClassName );
	}

	protected override void OnVisibilityChanged()
	{
		if ( !IsVisible )
		{
			GetCurrentMode()?.SaveCookies();
		}
	}

	ToolMode GetCurrentMode()
	{
		var localPlayer = Player.FindLocalPlayer();
		var toolgun = localPlayer?.GetWeapon<Toolgun>();
		return toolgun?.GetCurrentMode();
	}

	static bool FilterProperties(SerializedProperty o)
	{
		if (o.PropertyType is null) return false;
		if (o.PropertyType.IsAssignableTo(typeof(Delegate))) return false;

		if (o.IsMethod) return true;
		if (!o.HasAttribute<PropertyAttribute>()) return false;

		return true;
	}
}