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
    }
}