Editor/Ground/ArchTerrainContributions.cs
namespace Sunless.Architecture;

public readonly record struct ArchTerrainRequest(
	Terrain Terrain,
	ArchPlan Plan,
	ArchKit Kit,
	ushort[] Map,
	int Resolution,
	Vector3 Origin,
	float Step,
	float MaxHeight );

public interface IArchTerrainContribution {
	string Ident { get; }

	int Raise( ArchTerrainRequest request ) => 0;

	int Carve( ArchTerrainRequest request );

	int Cut( ArchTerrainRequest request );
}

public sealed class ArchTerrainContributions : ArchTable<ArchTerrainContributions, string, IArchTerrainContribution> {
	protected override IEnumerable<IArchTerrainContribution> Standing() {
		yield return new ArchRoadTerrainContribution();
		yield return new ArchApproachTerrainContribution();
	}

	protected override string KeyOf( IArchTerrainContribution contribution ) => contribution.Ident;

	protected override bool Accepts( IArchTerrainContribution contribution ) => !string.IsNullOrWhiteSpace( contribution.Ident );

	protected override string Collision( IArchTerrainContribution standing, IArchTerrainContribution contribution ) {
		return $"{contribution.Ident} terrain is claimed by both {standing.GetType().Name} and {contribution.GetType().Name}";
	}

	public IArchTerrainContribution For( string ident ) => Held( ident );

	public int Raise( ArchTerrainRequest request ) => Entries.OrderBy( contribution => contribution.Ident ).Sum( contribution => contribution.Raise( request ) );

	public int Carve( ArchTerrainRequest request ) => Entries.OrderBy( contribution => contribution.Ident ).Sum( contribution => contribution.Carve( request ) );

	public int Cut( ArchTerrainRequest request ) => Entries.OrderBy( contribution => contribution.Ident ).Sum( contribution => contribution.Cut( request ) );
}