Editor/Pipe/ArchPipePreviews.cs
namespace Sunless.Architecture;

public sealed class ArchPipePreview : IArchPreview {
	public ArchKind Kind => ArchKind.Pipe;

	public void Draw( ArchPreviewContext context ) {
		if ( context.Payload is not ArchPipePart run || context.Tool is null ) {
			return;
		}

		var shape = context.Tool.Resolved( run.Id, () => ArchPipeShape.Resolve( context.Tool.Plan, run ) );

		Gizmo.Draw.Color = context.Selected ? Color.Yellow : Color.Cyan.WithAlpha( 0.7f );
		ArchGhost.Path( shape.Path().Select( point => point + Vector3.Up * context.Lift ).ToList(), false );

		if ( !context.Selected ) {
			return;
		}

		foreach ( var node in run.Nodes ) {
			Gizmo.Draw.LineSphere( node.Position + Vector3.Up * context.Lift, MathF.Max( 3f, run.Radius ) );
		}

		foreach ( var block in shape.Blocks ) {
			ArchGhost.Tag( shape.At( (block.From + block.To) * 0.5f ) + Vector3.Up * context.Lift,
				$"over {block.Name}", Color.Orange );
		}
	}
}

public sealed class ArchBracketPreview : IArchPreview {
	public ArchKind Kind => ArchKind.Bracket;

	public void Draw( ArchPreviewContext context ) {
		if ( context.Payload is not ArchPipeBracketPart bracket || context.Tool is null ) {
			return;
		}

		Gizmo.Draw.Color = context.Selected ? Color.Yellow : Color.Green.WithAlpha( 0.35f );
		ArchGhost.Volume( bracket.Min, bracket.Max, bracket.BaseHeight + context.Lift, bracket.TopHeight + context.Lift );

		if ( !context.Selected ) {
			return;
		}

		var shape = context.Tool.Resolved( bracket.Id, () => ArchPipeBracket.Resolve( context.Tool.Plan, bracket ) );

		ArchGhost.Note( new Vector3( bracket.Max.x, bracket.Max.y, bracket.TopHeight + context.Lift ),
			$"{shape.Count} hangers · holds {shape.Held.Count} runs" );
	}
}