using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace TimeClock.API
{
    class SoundPlay
    {
       private readonly WaveOut waveOut = null;
        /// <summary>
        /// 实例化音频播放类
        /// </summary>
        public SoundPlay()
        {
            waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback());           
        }
        /// <summary>
        /// 实例化音频播放类
        /// </summary>
        /// <param name="path"></param>
        public SoundPlay(string path)
        {
            waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback());
            FilePath = path;
        }
        /// <summary>
        /// 音频文件地址
        /// </summary>
        public string FilePath { get; set; }
        public event EventHandler OnPlayEnd;
        /// <summary>
        /// 播放
        /// </summary>
        public void Play()
        {
            Play(FilePath);
        }
        /// <summary>
        /// 播放指定音频
        /// </summary>
        /// <param name="path"></param>
        public void Play(string path)
        {
            if (!System.IO.File.Exists(path)) { return; }
            try
            {
                var ms = System.IO.File.OpenRead(path);
                WaveStream wavStream = null;
                switch (System.IO.Path.GetExtension(path).ToLower())
                {
                    case ".wav":
                        var rdr2 = new WaveFileReader(ms);
                        wavStream = WaveFormatConversionStream.CreatePcmStream(rdr2);
                        break;
                    case ".mp3":
                        var rdr = new Mp3FileReader(ms);
                        wavStream = WaveFormatConversionStream.CreatePcmStream(rdr);
                        break;
                }
                if (wavStream == null) { ms.Close(); return; }
                using (var baStream = new BlockAlignReductionStream(wavStream))
                {
                    waveOut.Init(baStream);
                    waveOut.Play();
                    while (waveOut.PlaybackState == PlaybackState.Playing)
                    {
                        Thread.Sleep(10);
                    }
                }
                ms.Close();
            }
            catch { }
        }
        /// <summary>
        /// 播放状态
        /// </summary>
        public PlaybackState PlaybackState
        {
            get { return waveOut.PlaybackState; }
        }
        /// <summary>
        /// 异步播放指定音频
        /// </summary>
        /// <param name="path"></param>
        public void PlaySync(string path)
        {
            if (!System.IO.File.Exists(path)) { return; }
            Thread th = new Thread(delegate() {
                Play(path);
                OnPlayEnd?.Invoke(this,new EventArgs());
            });
            th.Start();
        }
        /// <summary>
        /// 停止播放
        /// </summary>
        public void Stop()
        {
            try
            {
                waveOut.Stop();
            }
            catch
            {
            }
        }
        /// <summary>
        /// 恢复播放
        /// </summary>
        public void Resume()
        {
            try
            {
                waveOut.Resume();
            }
            catch
            {
            }
        }
        /// <summary>
        /// 暂停播放
        /// </summary>
        public void Pause()
        {
            try
            {
                waveOut.Pause();
            }
            catch
            {
            }
        }
       /// <summary>
       /// 设置/获取音量,范围为0-1
       /// </summary>
        public float Volume
        {
            get { return waveOut.Volume; }
            set
            {
                try
                {
                    waveOut.Volume = value;
                }
                catch
                {
                }
            }
        }
        /// <summary>
        /// 销毁数据
        /// </summary>
        ~SoundPlay()
        {
            try
            {
                waveOut.Dispose();
            }
            catch
            {
            }
        }
    }
}
