using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Threading;
using ChuPiao.AutoPrint.Machine.Models;
using ChuPiao.Common.Enums;
using ChuPiao.Common.Models;
using System.IO;
using System.Windows.Forms;
using System.Xml;

namespace ChuPiao.AutoPrint.Machine.TjJingCaiV1
{
    /// <summary>
    /// 老键盘
    /// </summary>
    public class VirtualKeyboardV1:BaseVirtualKeyboard
    {
        public VirtualKeyboardV1(string port,int portBps)
        {
            this.Status = VirtualKeyboardStatus.Stopped;
            this.KeyboardType = KeyboardType.NewKeyboard;
            this.Port = port;
            this.PortBps = portBps;
            this.KeycodeDictionary=new SortedDictionary<string, M_KeycodeConfigEntity>();
            this.WaitSendKeycodeQueue=new Queue<KeycodeInfo>();
        }

        #region Overrides of BaseVirtualKeyboard

        //虚拟键盘控制线程
        private Thread _workThread;
        private int _waitTime = 0;
        //是否发送中
        //private bool _sending = false;

        /// <summary>
        /// 初始化
        /// </summary>
        public override void Initialize()
        {
            try
            {
                KeyboardPort = new SerialPort(Port, PortBps, Parity.None);
                //_workThread = new Thread(new ThreadStart(DoTask));

                KeycodeDictionary.Clear();
                //M_KeycodeConfigService keycodeConfigService = new M_KeycodeConfigService();
                //List<M_KeycodeConfigEntity> kecodeConfigs = keycodeConfigService.GetKeycodeConfigList((int)KeyboardType);
                //foreach (M_KeycodeConfigEntity entity in kecodeConfigs)
                //{
                //    KeycodeDictionary.Add(entity.K_KeycodeName, entity);
                //}

                string keycodeconfigPath = Path.Combine(Application.StartupPath, "Config/keycode.xml");
                if (File.Exists(keycodeconfigPath))
                {
                    XmlDocument doc = new XmlDocument();
                    doc.Load(keycodeconfigPath);

                    foreach (XmlNode node in doc.SelectSingleNode("/keycode/old").ChildNodes)
                    {
                        KeycodeDictionary.Add(node.Attributes["key"].InnerText, new M_KeycodeConfigEntity(node.Attributes["key"].InnerText, node.Attributes["value"].InnerText));
                    }
                }
                else
                {
                    throw new Exception("keycode.xml不存在");
                }

                ClearScreenSaverKeycode = new KeycodeInfo(MachineInfo.MachineConfigEntity.C_ClearScreensaverKeys, 30);
                ClearScreenSaverKeycode.ValueBytes = KeycodeDictionary[ClearScreenSaverKeycode.Name].K_KeycodeValueBytes;
                ClearScreenSaverKeycode.ValueHex = KeycodeDictionary[ClearScreenSaverKeycode.Name].K_KeycodeValue;
                Log.Info("虚拟键盘初始化完成！");
            }
            catch (Exception exception)
            {
                Log.Warn(string.Concat("虚拟键盘初始化异常。错误信息：", exception.Message));
                Log.Warn("操作提示：请重启软件，启动时没有报错才开始出票！");
                throw new Exception(string.Concat("虚拟键盘初始化异常。错误信息：", exception.Message));
            }
            
        }

        /// <summary>
        /// 启动
        /// </summary>
        public override void Start()
        {
            try
            {
                if (Status != VirtualKeyboardStatus.Stopped)
                {
                    return;
                }
                if (KeyboardPort == null)
                {
                    KeyboardPort = new SerialPort(Port, PortBps, Parity.None);
                }
                if (!KeyboardPort.IsOpen)
                {
                    KeyboardPort.Open();
                }
                _workThread = new Thread(new ThreadStart(DoTask));
                Status = VirtualKeyboardStatus.Running;
                _workThread.Start();
                //Log.Info("虚拟键盘测试，发送清除屏保键码……");
                //List<KeycodeInfo> list = new List<KeycodeInfo>();
                //list.Add(ClearScreenSaverKeycode);
                //this.Input(list);
                Log.Info(string.Concat("虚拟键盘启动成功。端口号：", KeyboardPort.PortName));

                //_isStop = false;
                //if (!KeyboardPort.IsOpen)
                //{
                //    KeyboardPort.Open();
                //}
                //if (_workThread != null && _workThread.ThreadState != ThreadState.Running)
                //{
                //    _workThread.Start();
                //    Log.Info("虚拟键盘测试，发送清除屏保键码……");
                //    List<KeycodeInfo> list=new List<KeycodeInfo>();
                //    list.Add(ClearScreenSaverKeycode);
                //    this.Input(list);
                //}
                //Log.Info(string.Concat("虚拟键盘启动成功。端口号：", KeyboardPort.PortName));
            }
            catch (Exception exception)
            {
                Log.Warn(string.Concat("虚拟键盘启动异常。错误信息：", exception.Message));
            }
        }

        /// <summary>
        /// 停止
        /// </summary>
        public override void Stop()
        {
            if(Status==VirtualKeyboardStatus.Running)
            {
                Status = VirtualKeyboardStatus.Stopping;
            }
        }

        /// <summary>
        /// 输入键码
        /// </summary>
        public override void Input(List<KeycodeInfo> keycodeInfo)
        {
            if (keycodeInfo == null || keycodeInfo.Count < 1)
            {
                return;
            }
            string keyname = "";
            try
            {
                string tmpStr = "";
                foreach (KeycodeInfo info in keycodeInfo)
                {
                    keyname = info.Name;
                    tmpStr += info.Name + ",";
                    if (info.Name.StartsWith("wait"))
                    {
                        keyname = "wait";
                        int keysendinterval = (info.Name == "wait")
                                                  ? info.SendInterval
                                                  : int.Parse(info.Name.Replace("wait", ""));
                        info.Name = keyname;
                        info.SendInterval = keysendinterval;
                    }
                    info.ValueBytes = KeycodeDictionary[info.Name].K_KeycodeValueBytes;
                    info.ValueHex = KeycodeDictionary[info.Name].K_KeycodeValue;
                    lock (WaitSendKeycodeQueue)
                    {
                        WaitSendKeycodeQueue.Enqueue(info);
                    }

                    //keyname = info.Name;
                    //info.ValueBytes = KeycodeDictionary[info.Name].K_KeycodeValueBytes;
                    //info.ValueHex = KeycodeDictionary[info.Name].K_KeycodeValue;
                    //lock (WaitSendKeycodeQueue)
                    //{
                    //    WaitSendKeycodeQueue.Enqueue(info);
                    //}
                    //tmpStr += info.Name + ",";
                }
                Log.Info(string.Concat("输入键码：", tmpStr.TrimEnd(',')));
                _waitTime = 0;
                //_sending = true;
            }
            catch (Exception ex)
            {
                //一个键码在KeycodeDictionary找不到，就清空前面放到队列里面的键码，这样不会影响下次
                WaitSendKeycodeQueue.Clear();
                Log.Warn(string.Concat("键码 ", keyname, " 不在键码表中！"));
                throw ex;
            }
        }

        #endregion
        #region 方法
        /// <summary>
        /// 执行发送任务
        /// </summary>
        private void DoTask()
        {
            try
            {
                while (Status==VirtualKeyboardStatus.Running)
                {

                    //if (_sending)
                    //{
                        while (WaitSendKeycodeQueue.Count > 0)
                        {
                            KeycodeInfo keycodeInfo;
                            lock (WaitSendKeycodeQueue)
                            {
                                keycodeInfo = WaitSendKeycodeQueue.Dequeue();
                            }
                            //if (keycodeInfo.Name == "wait")
                            if (keycodeInfo.Name.StartsWith("wait"))
                            {
                                //特殊键码
                                Thread.Sleep(keycodeInfo.SendInterval);
                                continue;
                            }
                            if (keycodeInfo.SendInterval > 0)
                            {
                                Thread.Sleep(keycodeInfo.SendInterval);
                            }
                            KeyboardPort.Write(keycodeInfo.ValueBytes, KeyboardPort.BytesToWrite, keycodeInfo.ValueBytes.Length);
                            //Log.Debug(string.Concat("发送键码：", keycodeInfo.Name, "，等待间隔：", keycodeInfo.SendInterval));
                        }
                    ////}
                    ////_sending = false;
                    //if (_waitTime >= 115000)
                    //{
                    //    //清除屏保
                    //    Log.Info(string.Concat("清除屏保", ClearScreenSaverKeycode.Name));
                    //    KeyboardPort.Write(ClearScreenSaverKeycode.ValueBytes, KeyboardPort.BytesToWrite, ClearScreenSaverKeycode.ValueBytes.Length);
                    //    _waitTime = 0;
                    //}
                    _waitTime += 100;
                    Thread.Sleep(100);
                }

                try
                {
                    KeyboardPort.Close();
                    KeyboardPort.Dispose();
                }
                finally
                {
                    KeyboardPort = null;
                }

                Status = VirtualKeyboardStatus.Stopped;
                Log.Info(string.Concat("虚拟键盘停止"));
            }
            catch (ThreadAbortException)
            {
                //由Abort()终止线程引发的异常，不作处理
            }
            catch (Exception ex)
            {
                Log.Warn(string.Concat("彩票机 ", MachineInfo.M_Number, " 虚拟键盘发送数据异常：", ex.Message));
                if (ex.Message.Contains("口被关闭"))
                {
                    Log.Warn("操作提示：软件已经不能成功发送键码，请停止出票，重启软件！");
                }
            }
        }

        #endregion
    }
}
