using Godot;
using Sfs3.Client.Entities.Audio;
using System;

public partial class AudioMeter : VBoxContainer
{
	[Export]
    public TextureRect muteIcon;

	[Export]
    public Label delayLabel;

	[Export]
    public ProgressBar leftLevelMeter;

	[Export]
    public ProgressBar rightLevelMeter;

	[Export]
    public HSlider leftPeakMeter;

	[Export]
    public HSlider rightPeakMeter;

	[Export]
    public Label leftLevelLabel;

	[Export]
    public Label rightLevelLabel;

	[Export]
    public bool showInfo = true;

	private AudioStreamInfo asi;

    // Called when the node enters the scene tree for the first time.
    public override void _Ready()
	{
		Reset();
	}

	// Called every frame. 'delta' is the elapsed time since the previous frame.
	public override void _Process(double delta)
	{
		if (asi != null)
		{
			// LEFT CHANNEL
			
			leftLevelMeter.Value = (asi.LeftLevel > double.NegativeInfinity) ? asi.LeftLevel : leftLevelMeter.MinValue;

			if (leftLevelMeter.Value >= leftPeakMeter.Value)
			 	leftPeakMeter.Value = leftLevelMeter.Value;
			else
			{
				// Slowly reduce peak
				leftPeakMeter.Value = leftLevelMeter.Value + (leftPeakMeter.Value - leftLevelMeter.Value) * 0.95;
			}

			// RIGHT CHANNEL

			if (!asi.IsMono)
			{
				rightLevelMeter.Value = (asi.RightLevel > double.NegativeInfinity) ? asi.RightLevel : rightLevelMeter.MinValue;

				if (rightLevelMeter.Value >= rightPeakMeter.Value)
					rightPeakMeter.Value = rightLevelMeter.Value;
				else
				{
					// Slowly reduce peak
					rightPeakMeter.Value = rightLevelMeter.Value + (rightPeakMeter.Value - rightLevelMeter.Value) * 0.95;
				}
			}

			// Muted
			muteIcon.Visible = showInfo && asi.IsMuted;

			// Delay
			delayLabel.Text = asi.Delay + " ms";
		}
		else
		{
			leftLevelMeter.Value = rightLevelMeter.Value = leftLevelMeter.MinValue;
			leftPeakMeter.Value = rightPeakMeter.Value = leftPeakMeter.MinValue;
		}

		leftLevelLabel.Text = " " + Math.Round(leftLevelMeter.Value, 1) + " dB";
		rightLevelLabel.Text = " " + Math.Round(rightLevelMeter.Value, 1) + " dB";
	}

	public AudioStreamInfo ASInfo {
		get => asi;
		set {
			asi = value;

			if (this.IsNodeReady())
				Reset();
		}
	}

	private void Reset()
	{
		if (showInfo)
		{
			muteIcon.Visible = asi != null && asi.IsMuted;
			delayLabel.Text = (asi != null ? asi.Delay : "0") + " ms";
		}
		else
		{
			muteIcon.Visible = false;
			delayLabel.Visible = false;
		}

		if (asi != null && asi.IsMono && GetNodeOrNull<Container>("RightChannel") != null)
			GetNode<Container>("RightChannel").Visible = false;
	}
}
