using System;
using System.Collections.Generic;
using System.Linq;
using System.Speech.Synthesis;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace NEIntelligentControl2.Service.Voice
{
    /// <summary>
    /// 声音播放管理
    /// </summary>
    internal class VoiceManager
    {
        private static readonly object _Locker = new object();
        private bool _IsPlayVoice;
        private Queue<string> _Tasks;

        public VoiceManager()
        {
            try
            {
                string pav = System.Configuration.ConfigurationManager.AppSettings["PlayAlarmVoice"];
                _IsPlayVoice = pav.ToLower() == "y" || pav.ToLower() == "true";
            }
            catch { }
            _Tasks = new Queue<string>();
            Task.Factory.StartNew(PlayVoice, TaskCreationOptions.LongRunning);
        }

        private void PlayVoice()
        {
            while (_IsPlayVoice)
            {
                try
                {
                    lock (_Locker)
                    {
                        if (_Tasks.Count <= 0)
                        {
                            Monitor.Wait(_Locker);
                        }
                    }
                    using (SpeechSynthesizer ss = new SpeechSynthesizer() { Rate = 1 })
                    {
                        ss.SetOutputToDefaultAudioDevice();

                        var vc = ss.GetInstalledVoices()?.Where(c => c.VoiceInfo?.Culture?.Name == "zh-CN").FirstOrDefault();
                        if (vc != null)
                        {
                            ss.SelectVoice(vc.VoiceInfo.Name);
                        }

                        ss.Speak(_Tasks.Dequeue());
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
                Thread.Sleep(1000);
            }
        }

        public void Add(string message)
        {
            if (string.IsNullOrWhiteSpace(message)) return;
            lock (_Locker)
            {
                _Tasks.Enqueue(message);
                Monitor.Pulse(_Locker);
            }
        }
    }
}
