WorldMood.cs
namespace NiuLai;

/// <summary>Day, night, and the film's pure-black dream. Janky on purpose.</summary>
public sealed class WorldMood : Component
{
	public static WorldMood Instance { get; private set; }

	DirectionalLight _sun;
	SkyBox2D _sky;
	Color _daySun = new( 1f, 0.92f, 0.72f );
	Color _daySky = new( 0.42f, 0.55f, 0.62f );
	Color _nightSun = new( 0.25f, 0.18f, 0.35f );
	Color _nightSky = new( 0.08f, 0.07f, 0.14f );

	protected override void OnAwake()
	{
		Instance = this;
		GameState.MoodChanged += Apply;
		GameState.Teleport += DoTeleport;
	}

	protected override void OnDestroy()
	{
		if ( Instance == this )
			Instance = null;
		GameState.MoodChanged -= Apply;
		GameState.Teleport -= DoTeleport;
	}

	protected override void OnStart()
	{
		_sun = Scene.GetAllComponents<DirectionalLight>().FirstOrDefault();
		_sky = Scene.GetAllComponents<SkyBox2D>().FirstOrDefault();
		Apply();
	}

	public void Apply()
	{
		if ( !_sun.IsValid() )
			_sun = Scene.GetAllComponents<DirectionalLight>().FirstOrDefault();
		if ( !_sky.IsValid() )
			_sky = Scene.GetAllComponents<SkyBox2D>().FirstOrDefault();

		if ( GameState.InVoid )
		{
			if ( _sun.IsValid() )
			{
				_sun.LightColor = Color.Black;
				_sun.SkyColor = Color.Black;
			}

			if ( Scene.Camera.IsValid() )
				Scene.Camera.BackgroundColor = Color.Black;
			return;
		}

		if ( GameState.IsNight )
		{
			if ( _sun.IsValid() )
			{
				_sun.LightColor = _nightSun;
				_sun.SkyColor = _nightSky;
			}

			if ( Scene.Camera.IsValid() )
				Scene.Camera.BackgroundColor = new Color( 0.08f, 0.07f, 0.12f );
			return;
		}

		if ( GameState.SongWalk )
		{
			if ( _sun.IsValid() )
			{
				_sun.LightColor = new Color( 1f, 0.86f, 0.62f );
				_sun.SkyColor = new Color( 0.55f, 0.48f, 0.42f );
			}

			if ( Scene.Camera.IsValid() )
				Scene.Camera.BackgroundColor = new Color( 0.72f, 0.62f, 0.48f );
			return;
		}

		if ( _sun.IsValid() )
		{
			_sun.LightColor = _daySun;
			_sun.SkyColor = _daySky;
		}

		if ( Scene.Camera.IsValid() )
			Scene.Camera.BackgroundColor = new Color( 0.45f, 0.62f, 0.72f );
	}

	static void DoTeleport()
	{
		var p = CalfPlayer.Instance;
		if ( !p.IsValid() )
			return;

		p.WorldPosition = GameState.Beat switch
		{
			Beat.Dream or Beat.Farewell => GameState.DreamPos,
			Beat.Snake => GameState.SnakePos,
			Beat.Wake => GameState.WakePos,
			_ => GameState.CampPos
		};
	}
}