using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace COM
{
    [Guid("ED5DCE10-F40B-4655-9E7B-903779C77AF2")]
    public partial class SpVoice : Object
    {
        public enum Flags
        {
            SVSFDefault = 0,
            SVSFlagsAsync = 1,
            SVSFPurgeBeforeSpeak = 2,
            SVSFIsFilename = 4,
            SVSFIsXML = 8,
            SVSFIsNotXML = 16,
            SVSFPersistXML = 32,
            SVSFNLPSpeakPunc = 64,
            SVSFParseSapi = 128,
            SVSFParseSsml = 256,
            SVSFParseAutodetect = 0,
            SVSFNLPMask = 64,
            SVSFParseMask = 384,
            SVSFVoiceMask = 511,
            SVSFUnusedFlags = -512
        }

        public enum Priority
        {
            SVPNormal = 0,
            SVPAlert = 1,
            SVPOver = 2
        }
    }
    public partial class SpVoice : Object
    {
        private Type _ComType = null;
        private object _ComObject = null;

        public SpVoice()
        {
            this.Init();
        }

        public bool Init()
        {
            this._ComType = Type.GetTypeFromProgID("SAPI.SpVoice", true); // CLSID {269316D8-57BD-11D2-9EEE-00C04F797396}  
            if (this._ComType == null)
            {
                throw new Exception("COM调用失败");
            }
            this._ComObject = Activator.CreateInstance(this._ComType, true);
            return this._ComObject != null;
        }

        public int Release()
        {
            return Marshal.ReleaseComObject(this._ComObject);
        }

        public int Rate
        {
            get
            {
                return (int)this._ComType.InvokeMember("Rate", BindingFlags.GetProperty, null, this._ComObject, null);
            }
            set
            {
                this._ComType.InvokeMember("Rate", BindingFlags.SetProperty, null, this._ComObject, new object[] { value });
            }
        }

        public void Pause()
        {
            this._ComType.InvokeMember("Pause", BindingFlags.InvokeMethod, null, this._ComObject, null);
        }

        public void Resume()
        {
            this._ComType.InvokeMember("Resume", BindingFlags.InvokeMethod, null, this._ComObject, null);
        }

        public int Volume
        {
            get
            {
                return (int)this._ComType.InvokeMember("Volume", BindingFlags.GetProperty, null, this._ComObject, null);
            }
            set
            {
                this._ComType.InvokeMember("Volume", BindingFlags.SetProperty, null, this._ComObject, new object[] { value });
            }
        }

        public int Skip(int Type, int NumItems)
        {
            return (int)this._ComType.InvokeMember("Skip", BindingFlags.InvokeMethod, null, this._ComObject, new object[] { Type, NumItems });
        }

        public bool IsUISupported(string TypeOfUI, object ExtraData)
        {
            return (bool)this._ComType.InvokeMember("IsUISupported", BindingFlags.InvokeMethod, null, this._ComObject, new object[] { TypeOfUI, ExtraData });
        }

        public bool WaitUntilDone(int msTimeout)
        {
            return (bool)this._ComType.InvokeMember("WaitUntilDone", BindingFlags.InvokeMethod, null, this._ComObject, new object[] { msTimeout });
        }

        public void DisplayUI(int hWndParent, string Title, string TypeOfUI, object ExtraData)
        {
            this._ComType.InvokeMember("DisplayUI", BindingFlags.InvokeMethod, null, this._ComObject, new object[] { hWndParent, Title, TypeOfUI, ExtraData });
        }

        public void Speak(string Text, Flags Flags)
        {
            this._ComType.InvokeMember("Speak", BindingFlags.InvokeMethod, null, this._ComObject, new object[] { Text, Flags });
        }

        public Priority Property
        {
            get
            {
                return (Priority)this._ComType.InvokeMember("Priority", BindingFlags.GetProperty, null, this._ComObject, null);
            }
            set
            {
                this._ComType.InvokeMember("Priority", BindingFlags.SetProperty, null, this._ComType, new object[] { value });
            }
        }

        public List<string> GetVoices()
        {
            List<string> _ret = new List<string>();
            object Item = null, _Voices = this._ComType.InvokeMember("GetVoices", BindingFlags.InvokeMethod, null, this._ComObject, null);
            int Count = (int)_Voices.GetType().InvokeMember("Count", BindingFlags.GetProperty, null, _Voices, null);
            for (int i = 0; i < Count; i++)
            {
                Item = _Voices.GetType().InvokeMember("Item", BindingFlags.InvokeMethod, null, _Voices, new object[] { i });
                if (Item != null)
                {
                    _ret.Add(Item.GetType().InvokeMember("GetDescription", BindingFlags.InvokeMethod, null, Item, null).ToString());
                }
            }
            return _ret;
        }

        public bool SetVoices(string Name)
        {
            bool _ret = false;
            object Item = null, _Voices = this._ComType.InvokeMember("GetVoices", BindingFlags.InvokeMethod, null, this._ComObject, null);
            int Count = (int)_Voices.GetType().InvokeMember("Count", BindingFlags.GetProperty, null, _Voices, null);
            for (int i = 0; i < Count; i++)
            {
                Item = _Voices.GetType().InvokeMember("Item", BindingFlags.InvokeMethod, null, _Voices, new object[] { i });
                if (Item != null)
                {
                    var _str = Item.GetType().InvokeMember("GetDescription", BindingFlags.InvokeMethod, null, Item, null).ToString();
                    if (_str == Name)
                    {
                        this._ComType.InvokeMember("Voice", BindingFlags.SetProperty, null, this._ComObject, new object[] { Item });
                    }
                }
            }
            return _ret;
        }
    }
}
