using NAudio.Wave;
using System;

namespace RhythmBullet.Audio
{
    internal class MusicController : IDisposable
    {
        public readonly MusicList musicList;
        WaveOutEvent outputDevice;
        TransparentSampleProvider transparentSampleProvider;
        AudioFileReader audioInput;
        Random random;
        float volume;
        private float Volume
        {
            get
            {
                return volume;
            }

            set
            {
                if (outputDevice != null)
                {
                    outputDevice.Volume = value;
                }

                volume = value;
            }
        }
        private int PlayingIndex
        {
            get
            {
                return musicList.List.IndexOf(audioInput.FileName);
            }

            set
            {
                if (value < 0) value = musicList.List.Count -1;
                if (value >= musicList.List.Count) value = 0;

                LoadMusic(musicList.List[value]);
            }
        }

        public MusicController()
        {
            musicList = new MusicList();
            musicList.SearchCompleteEvent += MusicListRefreshListener;
            random = new Random();
        }

        public MusicController(MusicList musicList)
        {
            random = new Random();
            this.musicList = musicList;
            this.musicList.SearchCompleteEvent += MusicListRefreshListener;
        }

        private void LoadMusic(string path)
        {
            outputDevice?.Dispose();
            audioInput?.Dispose();
            
            audioInput = new AudioFileReader(path);

            transparentSampleProvider = new TransparentSampleProvider(audioInput);

            outputDevice = new WaveOutEvent();
            outputDevice.Volume = Volume;
            outputDevice.Init(transparentSampleProvider);
        }

        public void Skip()
        {
            PlayingIndex++;
        }

        public void Previous()
        {
            PlayingIndex--;
        }

        public void Shuffle()
        {
            PlayingIndex = random.Next(0, musicList.List.Count);
        }

        public void Play()
        {
            outputDevice.Play();
        }

        public void Pause()
        {
            outputDevice.Pause();
        }

        public void Stop()
        {
            outputDevice.Stop();
        }

        public TimeSpan Position()
        {
            return audioInput.CurrentTime;
        }

        public void Dispose()
        {
            audioInput?.Dispose();
            outputDevice?.Dispose();
            musicList.SearchCompleteEvent -= MusicListRefreshListener;
        }

        public void MusicListRefreshListener(MusicList musicList)
        {
        }
    }
}
