using System.Collections;
using Godot;

public partial class Audio
{
	public partial class AudioBlock
	{
		public AudioStream stream;

		public float volume = 1f;

		public float pitch = 1f;
	}

	public static readonly StringName[] commonSounds = new StringName[4] { "snd_menumove.wav", "snd_cantselect.wav", "snd_select.wav", "snd_save.wav" };

	public static AudioStreamPlayer music;

	public static AudioStreamPlayer bleep;

	public static Coroutine routine;

	public static void ChangeMusic(AudioBlock block, float fadeTime)
	{
		if (block == null)
		{
			ChangeMusic(null, fadeTime, 1f, 1f);
		}
		else
		{
			ChangeMusic(block.stream, fadeTime, block.volume, block.pitch);
		}
	}

	public static void ChangeMusic(AudioStream music, float fadeTime = 0.5f, float volume = 1f, float pitch = 1f)
	{
		if (music != Audio.music.Stream)
		{
			Coroutine coroutine = routine;
			if (coroutine != null && !coroutine.done)
			{
				Coroutine.Stop(routine, now: true);
			}
			routine = Coroutine.Start(MusChange(music, fadeTime, volume, pitch));
		}
	}

	private static IEnumerator MusChange(AudioStream clip, float time, float volume, float pitch)
	{
		if (music.Playing)
		{
			Tween tween = music.CreateTween();
			tween.TweenProperty(music, "volume_db", -80, time);
			SignalAwaiter s = tween.ToSignal(tween, Tween.SignalName.Finished);
			while (s.GetResult() == null)
			{
				yield return null;
			}
		}
		music.Stream = clip;
		if (clip != null)
		{
			music.VolumeDb = Mathf.LinearToDb(volume);
			music.PitchScale = pitch;
			music.Play();
		}
		else
		{
			music.Stop();
		}
	}

	public static AudioStreamPlayer PlaySound(AudioBlock block)
	{
		return PlaySound(block.stream, block.volume, block.pitch);
	}

	public static AudioStreamPlayer PlaySound(AudioStream clip, float volume = 1f, float pitch = 1f, bool loop = false)
	{
		AudioStreamPlayer audioStreamPlayer = new AudioStreamPlayer
		{
			Stream = clip,
			VolumeDb = Mathf.LinearToDb(volume),
			PitchScale = pitch,
			Bus = "Sound"
		};
		if (!loop)
		{
			audioStreamPlayer.Finished += audioStreamPlayer.QueueFree;
		}
		Main.instance.CallDeferred("add_child", audioStreamPlayer);
		audioStreamPlayer.CallDeferred("play");
		return audioStreamPlayer;
	}

	public static AudioStreamPlayer PlaySound(StringName name, float volume = 1f, float pitch = 1f, bool loop = false)
	{
		return PlaySound(LoadSound(name), volume, pitch, loop);
	}

	public static AudioStream LoadSound(StringName name)
	{
		if (name == (StringName)"null")
		{
			return null;
		}
		return GD.Load<AudioStream>("res://Audio/Sounds/" + name);
	}

	public static void FadeSound(AudioStreamPlayer sound, float time)
	{
		sound.CreateTween().TweenProperty(sound, "volume_db", -80, time);
	}
}