using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(LineRenderer))]
public class TestWaver : MonoBehaviour
{
    public AudioSource sourceBuffer;
    public AudioSource song;

    public float amplitudeFactor;
    public float resampleTime;
    public int lineLength = 300;
    public float distanceBetweenSamples = 1;

    private List<Vector3> _line_positions = new List<Vector3>();

    private LineRenderer _rend;

    private float time;

    private void Awake()
    {
        _rend = GetComponent<LineRenderer>();

        _rend.numPositions = 0;

        sourceBuffer.Play();
        song.PlayDelayed(5);
    }

    private void Update()
    {
        time += Time.deltaTime;

        if (time >= resampleTime)
        {
            time = 0f;

            if (sourceBuffer.isPlaying)
            {
                float entire_spectrum = _GetEntireSpectrum();
                _AddNewStep(entire_spectrum, _line_positions.Count >= lineLength);
            }
        }
        else
        {
            _AddEmptyStep(_line_positions.Count > lineLength);
        }

        if (!song.isPlaying)
        {
            if (_line_positions.Count >= lineLength * 0.75)
            {
                song.Play();
            }
        }

        //Set the positions
        _UpdateLine();
    }

    private void _UpdateLine()
    {
        if (_line_positions.Count <= lineLength)
        {
            _rend.numPositions++;
        }

        for (int i = 0; i < _line_positions.Count; i++)
        {
            _line_positions[i] = new Vector3(_line_positions[i].x - distanceBetweenSamples, _line_positions[i].y);
        }

        _rend.SetPositions(_line_positions.ToArray());
    }

    private void _AddEmptyStep(bool remove_first_)
    {
        if (remove_first_)
        {
            _line_positions.RemoveAt(0);
        }

        Vector2 previous = Vector2.zero;
        Vector2 current = Vector2.zero;
        if (_line_positions.Count != 0)
        {
            previous = _line_positions[_line_positions.Count - 1];
            current = new Vector2(previous.x + distanceBetweenSamples, previous.y);
        }

        _line_positions.Add(current);
    }

    private void _AddNewStep(float entire_spectrum_, bool remove_first_)
    {
        if (remove_first_)
        {
            _line_positions.RemoveAt(0);
        }

        Vector2 previous = Vector2.zero;
        Vector2 current = Vector2.zero;
        if (_line_positions.Count != 0)
        {
            previous = _line_positions[_line_positions.Count - 1];
            current = new Vector2(previous.x + distanceBetweenSamples, entire_spectrum_);
        }

        _line_positions.Add(current);
    }

    private float _GetEntireSpectrum()
    {
        float[] spectrum = new float[256];

        sourceBuffer.GetSpectrumData(spectrum, 0, FFTWindow.BlackmanHarris);

        float entire_spectrum = 0;

        for (int i = 1; i < spectrum.Length; i++)
        {
            entire_spectrum += spectrum[i] * amplitudeFactor;
        }

        return entire_spectrum;
    }
}