using ryCommon;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SysFuns
{
    /// <summary>
    /// 热键转换类
    /// </summary>
   public class HotkeyValue
    {
        /// <summary>
        /// 功能键。
        /// </summary>
        public Keys Modifiers { get; private set; } = Keys.None;
        /// <summary>
        /// 修改键。
        /// </summary>
        public int Modifiers_Int { get; private set; } = 0;
        /// <summary>
        /// 转换功能键到谷歌浏览器专用
        /// </summary>
        public int Chrome_Modifiers
        {
            get
            {
                int Pb_Modifiers = 0;
                try
                {
                    if ((Modifiers_Int & 4) == 4) { Pb_Modifiers += 2; }
                    if ((Modifiers_Int & 2) == 2) { Pb_Modifiers += 4; }
                    if ((Modifiers_Int & 1) == 1) { Pb_Modifiers += 8; }
                }
                catch { }
                return Pb_Modifiers;
            }
        }
        /// <summary>
        /// 将chrome功能键转换为普通功能键
        /// </summary>
        /// <param name="_Modifiers"></param>
        /// <returns></returns>
        public int Modifiers_FromChrome(int _Modifiers)
        {
            int Pb_Modifiers = 0;
            try
            {
                if ((_Modifiers & 2) == 2) { Pb_Modifiers += 4; }
                if ((_Modifiers & 4) == 4) { Pb_Modifiers += 2; }
                if ((_Modifiers & 8) == 8) { Pb_Modifiers += 1; }
            }
            catch { }
            return Pb_Modifiers;
        }
        /// <summary>
        /// 按键值。
        /// </summary>
        public Keys KeyCode { get; private set; } = Keys.None;
        /// <summary>
        /// 初始化类 <see cref="HotkeyValue"/> 的新实例。
        /// </summary>
        /// <param name="modifiers">The modifiers.</param>
        /// <param name="keyCode">The key code.</param>
        public HotkeyValue(Keys modifiers, Keys keyCode)
        {
            LoadHotKey(modifiers, keyCode);
        }
       /// <summary>
       /// 
       /// </summary>
       /// <param name="Modifiers"></param>
       /// <param name="T_Key"></param>
        public HotkeyValue(int Modifiers, int T_Key)
        {
            this.Modifiers = ConvertModifier(Modifiers);
            this.Modifiers_Int = Modifiers;
            this.KeyCode = (Keys)T_Key;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="hotkey"></param>
        public HotkeyValue(string hotkey)
        {
            LoadHotKey(hotkey);
        }
        /// <summary>
        /// 初始化类 <see cref="HotkeyValue"/> 的新实例。
        /// </summary>
        public HotkeyValue()
        {
            LoadHotKey(Keys.None, Keys.None);
        }
        /// <summary>
        /// 加载热键
        /// </summary>
        /// <param name="modifiers"></param>
        /// <param name="keyCode"></param>
        public void LoadHotKey(Keys modifiers, Keys keyCode)
        {
            this.Modifiers = modifiers;
            this.KeyCode = keyCode;
            int m_key = 0;
            Keys m_Modifiers = Modifiers;
            if ((m_Modifiers & Keys.Alt) != 0)
            { m_key |= 1; }
            else if ((m_Modifiers & Keys.Control) != 0)
            { m_key |= 2; }
            else if ((m_Modifiers & Keys.Shift) != 0)
            { m_key |= 4; }
            else if ((m_Modifiers & Keys.LWin) != 0)
            { m_key |= 8; }
            this.Modifiers_Int = m_key;
        }
        /// <summary>
        /// 加载热键
        /// </summary>
        /// <param name="hotkey"></param>
        public void LoadHotKey(string hotkey)
        {
            int T_Modifiers = 0;
            Keys T_Key = Keys.None;
            try
            {
                string[] item = hotkey.Split('+');
                if (item.Length == 1 && item[0].IsInt())
                {
                    T_Modifiers = 0;
                    T_Key = (Keys)item[0].ToInt(0);
                }
                else if (item.Length == 2 && item[0].IsInt() && item[1].IsInt())
                {
                    T_Modifiers = item[0].ToInt(0);
                    T_Key = (Keys)item[1].ToInt(0);
                }
            }
            catch
            {

            }
            this.Modifiers_Int = T_Modifiers;
            this.Modifiers = ConvertModifier(T_Modifiers);
            this.KeyCode = T_Key;
        }
        /// <summary>
        /// 加载热键
        /// </summary>
        /// <param name="hotkey"></param>
        public void LoadHotKeyStr(string hotkey)
        {
            int T_Modifiers = 0;
            Keys T_Key = Keys.None;
            try
            {
                string[] item = hotkey.Split('+');
                if (item.Length == 1)
                {
                    T_Modifiers = 0;
                    var key = item[0];
                    if(key.Length==1)
                    {
                        T_Key = Keys.None;
                    }
                    else
                    {
                        GetKey(key);
                    }
                }
                else if (item.Length == 2)
                {
                    if (!IsModifiersKey(item[0]))
                    { T_Modifiers = 0; T_Key = Keys.None; }
                    else
                    {
                        var mkeys = Enum.Parse(typeof(SysFuns.KeyModifiers), item[0]);
                        T_Modifiers = (int)mkeys;
                        GetKey(item[1]);
                    }
                }
                else if (item.Length == 3)
                {
                    if (!IsModifiersKey(item[0]) || !IsModifiersKey(item[1]) || item[0] == item[1])
                    { T_Modifiers = 0; T_Key = Keys.None; }
                    else
                    {
                        var mkeys1 = Enum.Parse(typeof(SysFuns.KeyModifiers), item[0]);
                        var mkeys2 = Enum.Parse(typeof(SysFuns.KeyModifiers), item[1]);
                        T_Modifiers = (int)mkeys1 + (int)mkeys2;
                        GetKey(item[2]);
                    }
                }
                else if (item.Length ==4)
                {
                    if (!IsModifiersKey(item[0]) || !IsModifiersKey(item[1]) || !IsModifiersKey(item[2])
                        || item[0] == item[1] || item[1] == item[2] || item[2] == item[3])
                    { T_Modifiers = 0; T_Key = Keys.None; }
                    else
                    {
                        var mkeys1 = Enum.Parse(typeof(SysFuns.KeyModifiers), item[0]);
                        var mkeys2 = Enum.Parse(typeof(SysFuns.KeyModifiers), item[1]);
                        var mkeys3 = Enum.Parse(typeof(SysFuns.KeyModifiers), item[1]);                       
                        T_Modifiers = (int)mkeys1 + (int)mkeys2 + (int)mkeys3;
                        GetKey(item[3]);
                    }
                }
            }
            catch
            {

            }
            bool IsModifiersKey(string _key)
            {
                return Enum.TryParse(_key, out KeyModifiers mkey);
            }
            void GetKey(string _key)
            {
                if (_key == "Enter") { T_Key = Keys.Enter; }
                else if (_key == "Esc") { T_Key = Keys.Escape; }
                else if (_key == "PgDn") { T_Key = Keys.PageDown; }
                else
                {
                    try
                    {

                        if (!Enum.TryParse(_key, out T_Key))
                        { T_Modifiers = 0; T_Key = Keys.None; }
                        else
                        {
                            var keys = Enum.Parse(typeof(Keys), _key);
                            T_Key = (Keys)keys;
                        }
                    }
                    catch {
                    }
                }
            }
            this.Modifiers_Int = T_Modifiers;
            this.Modifiers = ConvertModifier(T_Modifiers);
            this.KeyCode = T_Key;
        }
        private Keys ConvertModifier(int Modifiers)
        {
            Keys m_Modifiers = Keys.None;
            if ((Modifiers & 1) != 0)
            { m_Modifiers |= Keys.Alt; }
            if ((Modifiers & 2) != 0)
            { m_Modifiers |= Keys.Control; }
            if ((Modifiers & 4) != 0)
            { m_Modifiers |= Keys.Shift; }
            if ((Modifiers & 8) != 0)
            { m_Modifiers |= Keys.LWin; }
            return m_Modifiers;
        }
        /// <summary>
        /// 判断是否是热键
        /// </summary>
        public bool IsHotKey => KeyCode != Keys.None || (Modifiers == Keys.None && KeyCode > Keys.A && KeyCode < Keys.Z);
        /// <summary>
        /// 获取当前热键
        /// </summary>
        public string HotKey
        {
            get
            {
                if (KeyCode == Keys.None)
                { return "0"; }
                return Modifiers_Int.ToString() + "+" + ((int)KeyCode).ToString();
            }
        }
        /// <summary>
        /// 已重载，返回“Ctrl+Alt+A”格式的字符串。
        /// </summary>
        /// <returns>类似“Ctrl+Alt+A”格式的字符串</returns>
        public override string ToString()
        {
            string sbt = "";
            if ((this.Modifiers & Keys.Control) != 0)
            { sbt += "Ctrl+"; }
            if ((this.Modifiers & Keys.Shift) != 0)
            { sbt += "Shift+"; }
            if ((this.Modifiers & Keys.Alt) != 0)
            { sbt += "Alt+"; }
            if ((this.Modifiers & Keys.LWin) != 0 || (this.Modifiers & Keys.RWin) != 0)
            { sbt += "Win+"; }
            if (this.KeyCode != Keys.None)
                sbt += this.KeyCode.ToString();
            if (sbt.Length != 0)
            {
                return sbt;
            }
            else
            {
                return "无热键";
            }
        }
        /// <summary>
        /// 返回“Ctrl+Alt+A”格式的字符串。
        /// </summary>
        /// <returns>类似“Ctrl+Alt+A”格式的字符串</returns>
        public string ToStr()
        {
            return ToString();
        }
    }
}
