Editor/Output/ArchShadows.cs
namespace Sunless.Architecture;

public static class ArchShadows {
	public static bool Resolve( ArchBuiltPart part, ArchPlan plan, ArchKit kit, ArchLayerTree layers ) {
		return part.AskedShadows ?? Inherited( part.Source, plan, layers ) ?? part.ScopeShadows ?? kit?.Shadows ?? true;
	}

	static bool? Inherited( object source, ArchPlan plan, ArchLayerTree layers ) {
		return source is not null && layers?.Find( source ) is { } node ? Above( plan, node ) : null;
	}

	public static bool? Above( ArchPlan plan, ArchLayerNode node ) {
		for ( var above = node?.Parent; above is not null; above = above.Parent ) {
			if ( above.Ref is { } layer && ArchParts.Find( plan, layer.ItemId, "" )?.Shadows is { } inherited ) {
				return inherited;
			}
		}

		return null;
	}

	public static bool Showing( ArchPlan plan, ArchKit kit, ArchLayerNode node, out bool own ) {
		var mine = node?.Ref is { } layer ? ArchParts.Find( plan, layer.ItemId, "" )?.Shadows : null;

		own = mine.HasValue;

		return mine ?? Above( plan, node ) ?? kit?.Shadows ?? true;
	}

	public static string Following( ArchPlan plan, ArchKit kit, ArchLayerNode node ) {
		return Above( plan, node ) is { } parent
			? $"Follow the layer above — {Describe( parent )}"
			: $"Follow the kit — {Describe( kit?.Shadows ?? true )}";
	}

	// Must be set before mesh assignment — that triggers the scene object rebuild
	public static void Write( MeshComponent renderer, bool casts ) {
		renderer.RenderType = casts ? ModelRenderer.ShadowRenderType.On : ModelRenderer.ShadowRenderType.Off;
	}

	public static string Describe( bool casts ) {
		return casts
			? "Casts shadows"
			: "No shadow — lit and drawn, casts nothing";
	}

	public static string Glyph( bool casts ) => casts ? "wb_sunny" : "wb_twilight";
}