Editor/Walkway/ArchWalkwayManifest.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Sandbox;

namespace Sunless.Architecture;

public sealed class ArchWalkwayManifest : ArchKindManifest {
	public override ArchKind Kind => ArchKind.Walkway;

	// A walkway is an ArchRoom that Spans, and the room manifest already claims that type, so this one claims none.
	public override Type Payload => null;

	public override string Slot => "Rooms";

	public override IEnumerable<Type> Hosts => new[] { typeof( ArchBuilding ) };

	public override string Label => "Walkway";

	public override string Glyph => ArchIcons.Get( "subtool_walkway", "link" );

	public override string Subtool => ArchSubtools.Walkway;

	public override string HostOutput => "Walkway deck and endpoints";

	public override IEnumerable<ArchKind> Children => new[]
	{
		ArchKind.Stair, ArchKind.Roof, ArchKind.Trim, ArchKind.Pillar
	};

	public override int DirectRank => 0;

	public override string NameOf( object payload, int id ) {
		return payload is ArchRoom room ? room.Name : base.NameOf( payload, id );
	}

	public override bool TryRename( object payload, string name ) {
		if ( string.IsNullOrWhiteSpace( name ) || payload is not ArchRoom room ) {
			return false;
		}

		room.Name = name;

		return true;
	}

	public override IEnumerable<object> Filed( ArchPlan plan, object host ) {
		if ( host is not ArchBuilding building ) {
			return Array.Empty<object>();
		}

		return building.Rooms.Where( room => room.Spans );
	}

	public override bool File( object host, object payload ) {
		if ( host is not ArchBuilding building || payload is not ArchRoom room ) {
			return false;
		}

		building.Rooms.Add( room );

		return true;
	}

	public override bool Unfile( ArchPlan plan, object payload ) {
		if ( plan is null || payload is not ArchRoom room ) {
			return false;
		}

		return plan.OwnerOf( room ) is { } holder && holder.Rooms.Remove( room );
	}

	public override IReadOnlyList<List<Vector2>> Loops( object payload ) {
		if ( payload is not ArchRoom room ) {
			return Array.Empty<List<Vector2>>();
		}

		var footprint = ArchFloorGen.Footprint( room );

		if ( footprint.Count < 3 ) {
			return Array.Empty<List<Vector2>>();
		}

		return new List<List<Vector2>> { footprint };
	}

	public override float Height( object payload, float fallback ) {
		return payload is ArchRoom room ? room.BaseHeight : fallback;
	}
}