using Common;
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MeterPlugInLibrary
{
    public class VoiceMCI
    {
        //定义API函数使用的字符串变量 
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        private string Name = "";
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        private string durLength = "";
        [MarshalAs(UnmanagedType.LPTStr, SizeConst = 128)]
        private string TemStr = "";
        int ilong;
        //定义播放状态枚举变量
        public enum State
        {
            mPlaying = 1,
            mPuase = 2,
            mStop = 3
        };
        //结构变量
        public struct structMCI
        {
            public bool bMut;
            public int iDur;
            public int iPos;
            public int iVol;
            public int iBal;
            public string iName;
            public State status;
        };
        public structMCI mc = new structMCI();
        //取得播放文件属性
        public string FileName
        {
            get
            {
                return mc.iName;
            }
            set
            {
                try
                {
                    TemStr = "";
                    TemStr = TemStr.PadLeft(127, Convert.ToChar(" "));
                    Name = Name.PadLeft(260, Convert.ToChar(" "));
                    mc.iName = value;
                    ilong = APIClass.GetShortPathName(mc.iName, Name, Name.Length);
                    Name = GetCurrPath(Name);
                    Name = "open " + Convert.ToChar(34) + Name + Convert.ToChar(34) + " alias media";
                    ilong = APIClass.mciSendString("close all", TemStr, TemStr.Length, 0);
                    ilong = APIClass.mciSendString(Name, TemStr, TemStr.Length, 0);
                    ilong = APIClass.mciSendString("set media time format milliseconds", TemStr, TemStr.Length, 0);
                    mc.status = State.mStop;
                }
                catch
                {
                }
            }
        }
        //播放
        public void play()
        {
            TemStr = "";
            TemStr = TemStr.PadLeft(127, Convert.ToChar(" "));
            APIClass.mciSendString("play media", TemStr, TemStr.Length, 0);
            mc.status = State.mPlaying;
        }
        //停止
        public void StopT()
        {
            TemStr = "";
            TemStr = TemStr.PadLeft(128, Convert.ToChar(" "));
            ilong = APIClass.mciSendString("close media", TemStr, 128, 0);
            ilong = APIClass.mciSendString("close all", TemStr, 128, 0);
            mc.status = State.mStop;
        }
        public void Puase()
        {
            TemStr = "";
            TemStr = TemStr.PadLeft(128, Convert.ToChar(" "));
            ilong = APIClass.mciSendString("pause media", TemStr, TemStr.Length, 0);
            mc.status = State.mPuase;
        }
        private string GetCurrPath(string name)
        {
            if (name.Length < 1) return "";
            name = name.Trim();
            name = name.Substring(0, name.Length - 1);
            return name;
        }
        //总时间
        public int Duration
        {
            get
            {
                durLength = "";
                durLength = durLength.PadLeft(128, Convert.ToChar(" "));
                APIClass.mciSendString("status media length", durLength, durLength.Length, 0);
                durLength = durLength.Trim();
                if (durLength == "") return 0;
                return (int)(Convert.ToDouble(durLength) / 1000f);
            }
        }
        //当前时间
        public int CurrentPosition
        {
            get
            {
                durLength = "";
                durLength = durLength.PadLeft(128, Convert.ToChar(" "));
                APIClass.mciSendString("status media position", durLength, durLength.Length, 0);
                mc.iPos = (int)(Convert.ToDouble(durLength) / 1000f);
                return mc.iPos;
            }
        }

        /// <summary>
        /// 是否有声卡
        /// </summary>
        /// <returns></returns>
        public bool IsExistWaveOut()
        {
            if (APIClass.waveOutGetNumDevs() != 0)
            {
                return true;//有声卡
            }
            return false;

        }
        /// <summary>
        /// 语音播放 -1语音播放失败 0无音频设备 1语音播放成功 2语音播放结束
        /// </summary>
        public int VoicePlay(string strPath)
        {
            try
            {
                VoiceMCI cm = new VoiceMCI();
                if (!cm.IsExistWaveOut())
                {
                    WriteLog("未找到本机播放音频设备,无法播放");
                    return 0;
                }
                string strvoicePath = strPath;
                string mp3 = strvoicePath;
                if (!string.IsNullOrWhiteSpace(mp3) && File.Exists(mp3))
                {
                    cm.FileName = mp3;
                    int a = cm.Duration + 1;
                    cm.play();
                    Application.DoEvents();
                    DateTime dt = DateTime.Now;
                    Task.Factory.StartNew(() =>
                    {
                        while (true)
                        {
                            //判断是否播放结束
                            Application.DoEvents();
                            int dur = ExecDateDiff(dt, DateTime.Now);
                            Application.DoEvents();
                            if (dur >= a)
                            {
                                PbCache.voiceOver = true; //语音播完
                                WriteLog("语音写入");
                                return 2;//语音播放结束
                            }
                        }
                    });
                }
                return 1;
            }
            catch (Exception exp)
            {
                WriteLog("语音播放异常！" + exp.Message);
                return -1;
            }
        }
        /// <summary>
        /// 计算时间差
        /// </summary>
        /// <param name="dateBegin"></param>
        /// <param name="dateEnd"></param>
        /// <returns>返回秒数</returns>
        public static int ExecDateDiff(DateTime dateBegin, DateTime dateEnd)
        {
            TimeSpan ts1 = new TimeSpan(dateBegin.Ticks);
            TimeSpan ts2 = new TimeSpan(dateEnd.Ticks);
            TimeSpan ts3 = ts1.Subtract(ts2).Duration();
            //你想转的格式
            return ts3.Minutes * 60 + ts3.Seconds;
        }
        public void WriteLog(string str)
        {
            string m_szRunPath;
            m_szRunPath = System.Environment.CurrentDirectory;
            if (System.IO.Directory.Exists(m_szRunPath + "\\log") == false)
            {
                System.IO.Directory.CreateDirectory(m_szRunPath + "\\log");
            }
            string strDate = System.DateTime.Now.ToString("yyyyMMdd");
            string strPathFile = m_szRunPath + "\\log\\" + strDate;
            if (!Directory.Exists(strPathFile))//如果不存在就创建file文件夹
            {
                Directory.CreateDirectory(strPathFile);
            }
            System.IO.TextWriter tw = new System.IO.StreamWriter(strPathFile + "\\语音播放MCI_" + strDate + ".log", true);

            tw.WriteLine(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            tw.WriteLine(str);
            tw.WriteLine("\r\n");

            tw.Close();
        }
    }

    public class APIClass
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern int GetShortPathName(
         string lpszLongPath,
         string shortFile,
         int cchBuffer
      );
        [DllImport("winmm.dll", EntryPoint = "mciSendString", CharSet = CharSet.Auto)]
        public static extern int mciSendString(
           string lpstrCommand,
           string lpstrReturnString,
           int uReturnLength,
           int hwndCallback
          );

        [DllImport("winmm.dll", EntryPoint = "waveOutGetNumDevs")]
        public static extern int waveOutGetNumDevs();

    }
}
