using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Ports;
using System.Text;
using System.Threading;
using ChuPiao.AutoPrint.Machine.Models;
using ChuPiao.Common.Utils;
using MSCommLib;
using ChuPiao.Common.Enums;
using ChuPiao.Common.Models;
using ChuPiao.AutoPrint.Machine.TjJingCaiV1.MacLotPlayMode;
using ChuPiao.Common.Communication.GtdJson.Packs;
using ChuPiao.Common.Communication.GtdJson;
using ChuPiao.Common.Communication.GtdJson.Items;

namespace ChuPiao.AutoPrint.Machine.TjJingCaiV1
{
    /// <summary>
    /// 打印模块
    /// </summary>
    public class VirtualPrinter : BaseVirtualPrinter
    {
        //private MSCommClass MSPrinterComm;
        //private EventWaitHandle MSCommMutex;
        ////public event HandleCommEvDSRDelegate OnCommEventDSR;
        public VirtualPrinter(string port, int portBps)
        {
            this.Status = VirtualPrinterStatus.Stopped;
            this.Port = port;
            this.PortBps = portBps;

            //this.ComSettings = string.Format("{0},N,8,1", portBps);
        }
        #region Overrides of BaseVirtualPrinter
        //虚拟键盘控制线程
        private Thread _workThread;

        /// <summary>
        /// 初始化
        /// </summary>
        public override void Initialize()
        {
            //this.MSPrinterComm = new MSCommClass();
            //this.MSCommMutex = new ManualResetEvent(true);
            //MSPrinterComm.OnComm += new DMSCommEvents_OnCommEventHandler(MSPrinterComm_OnComm);

            PrinterPort = new SerialPort(Port, PortBps, Parity.None);
            PrinterPort.RtsEnable = true;
            PrinterPort.DtrEnable = true;

            Log.Info("虚拟打印机初始化完成！");
        }

        //void MSPrinterComm_OnComm()
        //{
        //    switch (MSPrinterComm.CommEvent)
        //    {
        //        case 2:
        //            ReceiveDataFromComm();
        //            break;
        //        case 4:
        //            break;
        //        case 1001:
        //            break;
        //    }
        //}
        //private void ReceiveDataFromComm()
        //{
        //    MSCommMutex.WaitOne();
        //    MSCommMutex.Reset();
        //    byte[] readBytes = (byte[])MSPrinterComm.Input;
        //    while (readBytes.Length > 0)
        //    {
        //        if (AlldataStream != null)
        //        {
        //            AlldataStream.Write(readBytes, 0, readBytes.Length);
        //            AlldataStream.Flush();
        //        }
        //        _receivedBuffer.AddRange(readBytes);
        //        string tmpStr = HexString.ByteToString(readBytes) + " ";
        //        _receivedStringBuffer.Append(tmpStr);
        //        Log.Debug(string.Concat("从彩票机接收数据字节数：", readBytes.Length));
        //        //Log.Debug(string.Concat("从彩票机接收到数据：", tmpStr, "，字节数：", readBytes.Length, " 字符总长度：", _receivedStringBuffer.Length));
        //        readBytes = (byte[])MSPrinterComm.Input;
        //        //Thread.Sleep(5);
        //    }
        //    bool isreply = false;
        //    string strReceived = _receivedStringBuffer.ToString();
        //    if (strReceived.EndsWith("10 04 01 10 04 02 10 04 03 10 04 04 "))
        //    {
        //        isreply = true;
        //        strReceived = "";
        //        _receivedBuffer.Clear();
        //        _receivedStringBuffer.Remove(0, _receivedStringBuffer.Length);
        //    }
        //    //if(strReceived.StartsWith("10 04 01 10 04 02 10 04 03 10 04 04"))
        //    //{
        //    //    isreply = true;
        //    //    _receivedBuffer.RemoveRange(0, 12);
        //    //    _receivedStringBuffer.Remove(0, 36);
        //    //}
        //    //if (strReceived.StartsWith("00 1B 40 1D 50 CB CB 1B 23 2A 0A 00 10 04 01 10 04 02 10 04 03 10 04 04"))
        //    //{
        //    //    isreply = true;
        //    //    _receivedBuffer.RemoveRange(0, 24);
        //    //    _receivedStringBuffer.Remove(0, 72);
        //    //}
        //    //if (strReceived.StartsWith("00 1B 40 1D 50 CB CB 10 04 01 10 04 02 10 04 03 10 04 04"))
        //    //{
        //    //    isreply = true;
        //    //    _receivedBuffer.RemoveRange(0, 19);
        //    //    _receivedStringBuffer.Remove(0, 57);
        //    //}
        //    //if (strReceived.StartsWith("1B 40 1D 50 CB CB 10 04 01 10 04 02 10 04 03 10 04 04"))
        //    //{
        //    //    isreply = true;
        //    //    _receivedBuffer.RemoveRange(0, 18);
        //    //    _receivedStringBuffer.Remove(0, 54);
        //    //}
        //    //if (strReceived.StartsWith("1D 50 CB CB 10 04 01 10 04 02 10 04 03 10 04 04"))
        //    //{
        //    //    isreply = true;
        //    //    _receivedBuffer.RemoveRange(0, 16);
        //    //    _receivedStringBuffer.Remove(0, 48);
        //    //}
        //    if (strReceived.StartsWith("1D 4C 40 00 1D 57 00 03"))
        //    {
        //        isreply = true;
        //        _receivedBuffer.RemoveRange(0, 8);
        //        _receivedStringBuffer.Remove(0, 24);
        //    }

        //    if (isreply)
        //    {
        //        Reply("16 12 12 12");
        //    }
        //    else
        //    {
        //        //获取到票数据，判断是否收到一张完整票
        //        strReceived = _receivedStringBuffer.ToString();
        //        //if (!_oneTicketReceived && strReceived.IndexOf(EndString) != -1)
        //        if (!_oneTicketReceived && strReceived.Length > 900 && strReceived.IndexOf(EndString, 200) != -1)
        //        {
        //            Log.Info(string.Concat("从彩票机接收到一张完整票，字节数：", _receivedBuffer.Count, "，字符总长度：", strReceived.Length));
        //            _oneTicketReceived = true;
        //            SaveLastFile(_receivedBuffer.ToArray());
        //            try
        //            {
        //                if (MachineInfo.M_AllowPaperout)
        //                {
        //                    //this.PrinterClient.AddBytes(_receivedBuffer.ToArray());
        //                }
        //            }
        //            catch (Exception exception)
        //            {
        //                Log.Info(string.Concat("打印错误：", exception.ToString()));
        //            }

        //            oneTicketData = new byte[_receivedBuffer.Count];
        //            _receivedBuffer.CopyTo(oneTicketData);
        //            ClearBufferAfterOneTicket();
        //        }
        //    }
        //    MSCommMutex.Set();

        //}
        //private void Reply(string sendhex)
        //{
        //    MSPrinterComm.Output = HexString.StringToByte(sendhex);
        //    Log.Info(string.Concat("回复：", sendhex));
        //}

        /// <summary>
        /// 启动
        /// </summary>
        public override void Start()
        {
            try
            {
                if (Status != VirtualPrinterStatus.Stopped)
                {
                    return;
                }
                if (PrinterPort == null)
                {
                    PrinterPort = new SerialPort(Port, PortBps, Parity.None);
                }
                if (!PrinterPort.IsOpen)
                {
                    PrinterPort.Open();

                    int writeByteInt = PrinterPort.BytesToWrite;
                    if (writeByteInt > 0)
                    {
                        //清空发送数据的缓存
                        PrinterPort.DiscardOutBuffer();
                        Log.Info("PrinterPort.Open后，写缓冲区的Size：" + PrinterPort.WriteBufferSize.ToString() + "；字节数：" + writeByteInt.ToString() + "；DiscardOutBuffer后：" + PrinterPort.BytesToWrite.ToString());
                    }
                    else
                    {
                        Log.Info("PrinterPort.Open后，写缓冲区的Size：" + PrinterPort.WriteBufferSize.ToString() + "；字节数：0");
                    }
                }
                //if (AlldataStream == null)
                //{
                //    string filePath = AlldataFilePath;
                //    AlldataStream = new FileStream(filePath, FileMode.Append, FileAccess.Write);
                //}
                //OpenPrinterComm();
                _workThread = new Thread(new ThreadStart(DoTask));
                Status = VirtualPrinterStatus.Running;
                _workThread.Start();

                Log.Info(string.Concat("虚拟打印机启动成功。端口号：", Port, " ", PortBps));
            }
            catch (Exception exception)
            {
                Log.Warn(string.Concat("虚拟打印机启动异常。错误信息：", exception));
                Log.Warn("操作提示：请重启软件，启动时没有报错才开始出票！");
            }
        }

        /// <summary>
        /// 停止
        /// </summary>
        public override void Stop()
        {
            Status = VirtualPrinterStatus.Stopped;
            //ClosePrinterComm();

            PrinterPort.Close();
            //PrinterPort = null;

            //if (AlldataStream != null)
            //{
            //    AlldataStream.Close();
            //    AlldataStream.Dispose();
            //}
            
            Log.Info("虚拟打印机停止");
        }

        //private string _ComSettings = "19200,N,8,1";
        ///// <summary>
        ///// Com口的设置
        ///// </summary>
        //public string ComSettings
        //{
        //    get { return _ComSettings; }
        //    set { _ComSettings = value; }
        //}
        ///// <summary>
        ///// 打开端口
        ///// </summary>
        //private void OpenPrinterComm()
        //{


        //    try
        //    {
        //        if (MSPrinterComm == null)
        //            throw new Exception("打开终端机打印端口时出错");

        //        ClosePrinterComm();

        //        MSPrinterComm.CommPort = Convert.ToInt16(Port.Replace("COM", ""));

        //        //Base.WriterLog("@MSComm.CommPort=Com" + MSPrinterComm.CommPort.ToString());

        //        /*
        //        @MSComm.Settings = "19200,N,8,1";//设置通信口参数
        //        @MSComm.InBufferSize = short.MaxValue / 2;//设置MSComm2接收缓冲区为32字节
        //        @MSComm.OutBufferSize = 800;//设置MSComm2发送缓冲区为2字节
        //        @MSComm.InputMode = MSCommLib.InputModeConstants.comInputModeBinary;//设置接收数据模式为二进制形式
        //        @MSComm.EOFEnable = true;
        //        @MSComm.SThreshold = 0;//设置Output 一次从发送缓冲读取字节数为1
        //        @MSComm.InBufferCount = 0;//清除接收缓冲区
        //        @MSComm.OutBufferCount = 0;//清除发送缓冲区
        //        @MSComm.RThreshold = 1;//设置接收1个字节产生OnComm事件
        //        @MSComm.DTREnable = true;//??
        //        @MSComm.Handshaking = MSCommLib.HandshakeConstants.comNone;
        //        @MSComm.InputLen = 0;//决定每次Input读入的字符个数，缺省为0，表示读取接收缓冲区的全部内容
        //        @MSComm.NullDiscard = false;
        //        @MSComm.PortOpen = true;//打开串口14
        //        */

        //        //@MSComm.CDHolding = false;   //注意当 Carrier Detect 线为高电平 (CDHolding = True) 且超时时，
        //        //MSComm 控件设置CommEvent 属性为 comEventCDTO（Carrier Detect 超时错误），并产生 OnComm 事件。
        //        //注意 在主机应用程序中捕获一个丢失的传输是特别重要的，例如一个公告板，因为呼叫者可以随时挂起（放弃传输）。
        //        //Carrier Detect 也被称为 Receive Line Signal Detect (RLSD)。

        //        //@MSComm.DSRHolding = false;  //当 Data Set Ready 线为高电平(On，+3～+15V，有效，DSRHolding = True) 且超时时，
        //        //MSComm 控件设置 CommEvent 属性为 comEventDSRTO（数据准备超时）并产生 OnComm 事件。
        //        //当为 Data Terminal Equipment (DTE) 机器写 Data Set Ready/Data Terminal Ready 握手例程时该属性是十分有用的。
        //        //数据类型:Boolean

        //        MSPrinterComm.Settings = ComSettings;// "19200,N,8,1";//设置通信口参数,“BBBB,P,D,S”
        //        //其中BBBB 为波特率，P为奇偶校验，D 为数据位数，S为停止位数，value 的缺省值是：“9600,N,8,1”

        //        MSPrinterComm.Handshaking = HandshakeConstants.comNone;//Handshaking 是指内部通信协议，通过该协议，
        //        //数据从硬件端口传输到接收缓冲
        //        //区。当一个数据字符到达串行端口，通信设备就把它移到接收缓冲区以使程序可以读它。如
        //        //果没有接收缓冲区，程序需要直接从硬件读取每一个字符，这很可能会造成数据丢失，因为
        //        //字符到达的速度可以非常快。
        //        //握手协议保证在缓冲区过载时数据不会丢失。缓冲区过载为数据到达端口太快而使通
        //        //信设备来不及将它移到接收缓冲区。

        //        MSPrinterComm.InBufferSize = short.MaxValue / 16;//设置MSComm接收缓冲区为4KB

        //        MSPrinterComm.OutBufferSize = 1024 * 5;//设置MSComm2发送缓冲区为5KB

        //        MSPrinterComm.InputLen = 0;//决定每次Input读入的字符个数，缺省为0，表示读取接收缓冲区的全部内容

        //        MSPrinterComm.InputMode = InputModeConstants.comInputModeBinary;//设置接收数据模式为二进制形式

        //        MSPrinterComm.EOFEnable = false;

        //        MSPrinterComm.SThreshold = 1; //若设置 Sthreshold 属性为 0（缺省值），
        //        //数据传输事件不会产生 OnComm 事件。若设置 Sthreshold 属性为 1，当传输缓冲区完全空时，
        //        //MSComm 控件产生 OnComm 事件。如果在传输缓冲区中的字符数小于 value，
        //        //CommEvent 属性设置为 comEvSend，并产生 OnComm 事件。comEvSend 事件仅当字符数与 Sthreshold 交叉时被激活一次。
        //        //例如，如果 Sthreshold 等于 5，仅当在输出队列中字符数从 5 降到 4 时，comEvSend 才发生。
        //        //如果在输出队列中从没有比 Sthreshold 多的字符，comEvSend 事件将绝不会发生。

        //        MSPrinterComm.InBufferCount = 0;//清除接收缓冲区

        //        MSPrinterComm.OutBufferCount = 0;//清除发送缓冲区

        //        MSPrinterComm.RThreshold = 1;//说明在产生 OnComm 事件之前要接收的字符数,设置接收1个字节产生OnComm事件,
        //        //当接收字符后，若 Rthreshold 属性设置为 0（缺省值）则不产生 OnComm 事件。例如，
        //        //设置 Rthreshold 为 1，接收缓冲区收到每一个字符都会使 MSComm 控件产生 OnComm 事件。 

        //        MSPrinterComm.DTREnable = false;//Data Terminal Ready 是计算机发送到调制解调器的信号，指示计算机在等待接收传输。

        //        MSPrinterComm.RTSEnable = true;//，由计算机发送Request To Send 信号到联接的调制解调器，以请示允许发送数据。
        //        //请求发送(Request to send-RTS)——用来表示DTE请求DCE发送数据，即当终端要发送数据时，使该信号有效（ON状态），
        //        //向MODEM请求发送。它用来控制MODEM是否要进入发送状态。
        //        //允许发送（Clear to send-CTS）——用来表示DCE准备好接收DTE发来的数据，是对请求发送信号RTS的响应信号。
        //        //当MODEM已准备好接收终端传来的数据，并向前发送时，使该信号有效，通知终端开始沿发送数据线TxD发送数据。

        //        MSPrinterComm.NullDiscard = false;//(*) 这个不能设置为true.这样会把1D564200001B6400(截断一张票)，收到为：1D5642

        //        MSPrinterComm.ParityReplace = "?";//用问号(?)替换非法字符。若设置ParityReplace 为一
        //        //个空字符串(“ ”)，则当奇偶校验错误出现时，字符替换无效。

        //        //计算机:     DTE
        //        //调制解调器: DCE

        //        MSPrinterComm.PortOpen = true;//打开串口14
        //        Log.Info(string.Concat("打开串口：", MSPrinterComm.CommPort));
        //        //Base.WriterLog("[" + MachineObj.Name + "]" + "打开端口：" + MSPrinterComm.CommPort);
        //    }
        //    catch (Exception ex)
        //    {
        //        Log.Warn(string.Concat("串口设置错误。错误信息：",ex));
        //    }
        //}

        ///// <summary>
        ///// 关闭端口
        ///// </summary>
        //private void ClosePrinterComm()
        //{
        //    try
        //    {
        //        if (MSPrinterComm != null && MSPrinterComm.PortOpen)
        //            MSPrinterComm.PortOpen = false;//关闭端口
        //    }
        //    catch(Exception exception)
        //    {
        //        Log.Info(string.Concat("关闭端口异常。错误信息：",exception));
        //    }
        //}

        /// <summary>
        /// 输出电子票数据
        /// </summary>
        /// <returns></returns>
        public override CaptureDataInfo Output()
        {
            int maxWaitTime = MachineInfo.MachineConfigEntity.C_PrintWaitTime;
            //大额票，等10分钟，湖北有大额票等了6、7分钟才返回票数据
            //if (LotMachine.CurrentTicket != null && LotMachine.CurrentTicket.L_Money >= 500)
            //{
            //    maxWaitTime = 10 * 60 * 1000;
            //}
            int waitTime = 0;
            while (Status == VirtualPrinterStatus.Running && waitTime < maxWaitTime && oneTicketData == null)
            {
                Thread.Sleep(30);
                waitTime += 30;
                if (waitTime % 900 == 0)
                {
                    Log.Info(string.Concat("获取彩票机数据等待", waitTime, "毫秒"));
                }
                if (_forceStop)
                {
                    break;
                }
            }
            Log.Info(string.Concat("获取彩票机数据等待", waitTime, "毫秒"));
            CaptureDataInfo captureDataInfo;
            if (oneTicketData != null)
            {
                captureDataInfo = new CaptureDataInfo(oneTicketData);
            }
            else
            {
                byte[] data = new byte[_receivedBuffer.Count];
                _receivedBuffer.CopyTo(data);
                captureDataInfo = new CaptureDataInfo(data);
                if (data.Length > 0)
                {
                    SaveLastFile(captureDataInfo);
                }
            }
            return captureDataInfo;
        }
        private byte[] oneTicketData = new byte[] { };

        /// <summary>
        /// 输出电子票数据
        /// </summary>
        /// <returns></returns>
        public override CaptureDataInfo ReOutput()
        {
            CaptureDataInfo captureDataInfo;
            if (oneTicketData != null)
            {
                captureDataInfo = new CaptureDataInfo(oneTicketData);
            }
            else
            {
                byte[] data = new byte[_receivedBuffer.Count];
                _receivedBuffer.CopyTo(data);
                captureDataInfo = new CaptureDataInfo(data);
                if (data.Length > 0)
                {
                    SaveLastFile(captureDataInfo);
                }
            }
            return captureDataInfo;
        }

        /// <summary>
        /// 强行停止当前票
        /// </summary>
        public override void ForceStop()
        {
            Log.Info("强行停止等待彩票机数据");
            //_oneTicketReceived = true;
            _forceStop = true;
        }

        /// <summary>
        /// 清空接收缓存
        /// </summary>
        public override void ClearBuffer()
        {
            _oneTicketReceived = false;
            oneTicketData = null;
            _forceStop = false;

            _receivedBuffer.Clear();
            _receivedStringBuffer.Length = 0;
        }

        private void ClearBufferAfterOneTicket()
        {
            _oneTicketReceived = false;
            _receivedBuffer.Clear();
            _receivedStringBuffer.Length = 0;
            Log.Debug("收到一张完整票后，清空接收数据缓存");
        }

        #endregion

        #region 方法
        //public FileStream AlldataStream = null;
        private bool _oneTicketReceived = false;
        private bool _forceStop = false;
        //接收缓冲区
        private List<byte> _receivedBuffer = new List<byte>();
        private StringBuilder _receivedStringBuffer = new StringBuilder();

        private DateTime _lastTicketTime = DateTime.Now;
        private const string EndString = "1D 56 42";//天津01 1D 56 42 00
        private string[] EndStringArr = new string[] { "1D 56 42", "01 1D 56 42 00", "1D 56 42 00", "55 AA 01 02 1D 1F", "55 AA 01 07 1D 99 42 45 92 9A 41 55 AA 01 07 1D 99 42 45 92 9A 41", "66 66 66 06 18 E6 60 E0 66 66 66 06 18 E6 60 E0" };
        /// <summary>
        /// 执行数据接收任务
        /// </summary>
        private void DoTask()
        {
            try
            {
                int toalwait = 0;
                while (Status == VirtualPrinterStatus.Running)
                {
                    toalwait += 100;
                    Thread.Sleep(100);
                    int bytesToRead=0;
                    if (PrinterPort.IsOpen)
                    {
                        bytesToRead = PrinterPort.BytesToRead;
                    }
                    if (bytesToRead > 0)
                    {
                        byte[] readBytes = new byte[bytesToRead];
                        PrinterPort.Read(readBytes, 0, readBytes.Length);
                        _receivedBuffer.AddRange(readBytes);
                        //if (AlldataStream != null)
                        //{
                        //    AlldataStream.Write(readBytes, 0, readBytes.Length);
                        //    AlldataStream.Flush();
                        //}
                        string tmpStr = HexString.ByteToString(readBytes) + " ";
                        _receivedStringBuffer.Append(tmpStr);
                        //Log.Debug(string.Concat("从彩票机接收到数据：", tmpStr, "，字节数：", readBytes.Length));
                        string strReceived = _receivedStringBuffer.ToString();
                        Log.Debug(string.Concat("从彩票机接收数据字节数：", readBytes.Length, " 接收的总字符：", strReceived));

                        bool isreply = false;
                        if (strReceived.EndsWith("10 04 01 10 04 02 10 04 03 10 04 04 "))
                        {
                            isreply = true;
                            strReceived = "";
                            _receivedBuffer.Clear();
                            _receivedStringBuffer.Remove(0, _receivedStringBuffer.Length);
                        }
                        if (strReceived.StartsWith("1D 4C 40 00 1D 57 00 03"))
                        {
                            isreply = true;
                            _receivedBuffer.RemoveRange(0, 8);
                            _receivedStringBuffer.Remove(0, 24);
                        }
                        

                        if (isreply)
                        {
                            Write("16 12 12 12");    //回复开始
                        }
                        else
                        {
                            //获取到票数据，判断是否收到一张完整票
                            strReceived = _receivedStringBuffer.ToString();
                            //if (!_oneTicketReceived && strReceived.Length > 900 && strReceived.IndexOf(EndString, 200) != -1)

                            bool isend = false;
                            string strReceived_temp = strReceived.TrimEnd();
                            foreach (string endstring in EndStringArr)
                            {
                                if (strReceived_temp.EndsWith(endstring))
                                {
                                    isend = true;
                                    break;
                                }
                            }

                            if (!_oneTicketReceived && isend)                            
                            {
                                Log.Info(string.Concat("从彩票机接收到一张完整票，字节数：", _receivedBuffer.Count, "，字符总长度：", strReceived.Length));
                                _oneTicketReceived = true;

                                _lastTicketTime = DateTime.Now;
                                oneTicketData = new byte[_receivedBuffer.Count];
                                _receivedBuffer.CopyTo(oneTicketData);
                                ClearBufferAfterOneTicket();

                                SaveLastFile(oneTicketData);

                                try
                                {
                                    if (MachineInfo.M_AllowPaperout)
                                    {
                                        PrinterPort.Write(oneTicketData, 0, oneTicketData.Length);
                                    }
                                }
                                catch (Exception exception)
                                {
                                    Log.Info(string.Concat("打印错误：", exception.ToString()));
                                }

                                //解析票
                                CaptureDataInfo captureDataInfo = new CaptureDataInfo(oneTicketData);
                                string input = captureDataInfo.CaptureDataString;

                                int tmpEnd = input.IndexOf("-------------------");
                                if (tmpEnd < 0)
                                    continue;
                                string strPlayCodetype = input.Substring(0, tmpEnd);

                                L_LotTicketEntity ticketEntity = new L_LotTicketEntity();
                                if (strPlayCodetype.IndexOf("竞彩足球") > 0)
                                {
                                    ticketEntity.LotId = (int)Lottype.Jz ;
                                    if (strPlayCodetype.IndexOf("竞彩足球混合过关") > 0)
                                    {
                                        ticketEntity.L_PlayId = (int)Playtype.JzHHGG;
                                        ticketEntity.MacModeId = (int)TjJingCaiV1ModeType.JzHhgg;
                                    }
                                    else if (strPlayCodetype.IndexOf("竞彩足球胜平负") > 0)
                                    {
                                        ticketEntity.L_PlayId = (int)Playtype.JzSPF;
                                        ticketEntity.MacModeId = (int)TjJingCaiV1ModeType.JzSpf;
                                    }
                                    else if (strPlayCodetype.IndexOf("竞彩足球让球胜平负") > 0)
                                    {
                                        ticketEntity.L_PlayId = (int)Playtype.JzRQSPF;
                                        ticketEntity.MacModeId = (int)TjJingCaiV1ModeType.JzSpfn;
                                    }
                                    else if (strPlayCodetype.IndexOf("竞彩足球比分") > 0)
                                    {
                                        ticketEntity.L_PlayId = (int)Playtype.JzBF;
                                        ticketEntity.MacModeId = (int)TjJingCaiV1ModeType.JzBf;
                                    }
                                    else if (strPlayCodetype.IndexOf("竞彩足球半全场胜平负") > 0)
                                    {
                                        ticketEntity.L_PlayId = (int)Playtype.JzBQC;
                                        ticketEntity.MacModeId = (int)TjJingCaiV1ModeType.JzBqc;
                                    }
                                    else if (strPlayCodetype.IndexOf("竞彩足球总进球数") > 0)
                                    {
                                        ticketEntity.L_PlayId = (int)Playtype.JzJQS;
                                        ticketEntity.MacModeId = (int)TjJingCaiV1ModeType.JzZjq;
                                    }
                                }
                                else if (strPlayCodetype.IndexOf("竞彩篮球") > 0)
                                {
                                    ticketEntity.LotId = (int)Lottype.Jl;
                                    if (strPlayCodetype.IndexOf("竞彩篮球混合过关") > 0)
                                    {
                                        ticketEntity.L_PlayId = (int)Playtype.JlHHGG;
                                        ticketEntity.MacModeId = (int)TjJingCaiV1ModeType.JlHhgg;
                                    }
                                    else if (strPlayCodetype.IndexOf("竞彩篮球大小分") > 0)
                                    {
                                        ticketEntity.L_PlayId = (int)Playtype.JlDXF;
                                        ticketEntity.MacModeId = (int)TjJingCaiV1ModeType.JlDxf;
                                    }
                                    else if (strPlayCodetype.IndexOf("竞彩篮球让分胜负") > 0)
                                    {
                                        ticketEntity.L_PlayId = (int)Playtype.JlRFSF;
                                        ticketEntity.MacModeId = (int)TjJingCaiV1ModeType.JlRfsf;
                                    }
                                    else if (strPlayCodetype.IndexOf("竞彩篮球胜分差") > 0)
                                    {
                                        ticketEntity.L_PlayId = (int)Playtype.JlSFC;
                                        ticketEntity.MacModeId = (int)TjJingCaiV1ModeType.JlSfc;
                                    }
                                    else if (strPlayCodetype.IndexOf("竞彩篮球胜负") > 0)
                                    {
                                        ticketEntity.L_PlayId = (int)Playtype.JlSF;
                                        ticketEntity.MacModeId = (int)TjJingCaiV1ModeType.JlSf;
                                    }
                                }
                                //else if (strPlayCodetype.IndexOf("竞彩名次") > 0)
                                //{
                                //    ticketEntity.LotId = (int)Lottype.Jm;
                                //    if (strPlayCodetype.IndexOf("竞彩名次-冠军") > 0)
                                //    {
                                //        ticketEntity.L_PlayId = (int)Playtype.JmGj;
                                //        ticketEntity.MacModeId = (int)TjJingCaiV1ModeType.JmGj;
                                //    }
                                //    else if (strPlayCodetype.IndexOf("竞彩名次-冠亚军") > 0)
                                //    {
                                //        ticketEntity.L_PlayId = (int)Playtype.JmGyj;
                                //        ticketEntity.MacModeId = (int)TjJingCaiV1ModeType.JmGyj;
                                //    }
                                //}
                                //else  //非竞彩电子票
                                //{
                                   
                                //}
                                else if (strPlayCodetype.Contains("时段报表二"))  //时段报表
                                { 
                                    ChuPiao.AutoPrint.Machine.TjJingCaiV1.MacReport.MacReportService service = new ChuPiao.AutoPrint.Machine.TjJingCaiV1.MacReport.MacReportService();
                                    DecodeMachineReport decodeMachineReport = new DecodeMachineReport();
                                    decodeMachineReport.InputData = captureDataInfo;
                                    service.DecodeMachineReportReport(null, decodeMachineReport);

                                    if (decodeMachineReport.DecodeSuccess)
                                    {
                                        A10005UploadMachineSale pack = new A10005UploadMachineSale();
                                        pack.AgentId = MachineInfo.M_Number;
                                        pack.Salt = LotMachine.MachineInfo.M_Salt;
                                        pack.SaleMoney = decodeMachineReport.MachineReportEntity.R_SaleMoney;
                                        pack.EncashMoney = decodeMachineReport.MachineReportEntity.R_EncashMoney;
                                        pack.ReturnMoney = decodeMachineReport.MachineReportEntity.R_ReturnMoney;
                                        pack.QueryTime = decodeMachineReport.MachineReportEntity.R_QueryTime.ToString("yyyyMMddHHmmss");
                                        pack.From = decodeMachineReport.MachineReportEntity.R_StartTime.ToString("yyyyMMdd");
                                        pack.To = decodeMachineReport.MachineReportEntity.R_EndTime.ToString("yyyyMMdd");
                                        if (pack.From != pack.To)
                                        {
                                            continue;
                                        }
                                        pack.Type = 1;
                                        pack.TypeName = pack.From;
                                        pack.Prntext = decodeMachineReport.MachineReportEntity.R_PrnText;

                                        A10005UploadMachineSaleRet packRet = PackManager.Instance.Send(pack) as A10005UploadMachineSaleRet;
                                        if (packRet.Code <= 0)
                                        {
                                            LotMachine.Log.Warn("上传天报表失败，" + packRet.Message);
                                        }
                                        else
                                        {
                                            LotMachine.Log.Info("上传天报表成功！" + packRet.AgentId);
                                        }

                                    }
                                    else
                                    {
                                        LotMachine.Log.Warn(string.Concat("解析天报表失败。错误信息：", decodeMachineReport.ErrorMessage));
                                    }
                                }
                                else if (strPlayCodetype.Contains("缴款报表"))  //缴款报表
                                {
                                    //缴款
                                    ChuPiao.AutoPrint.Machine.TjJingCaiV1.MacReport.MacReportService service = new ChuPiao.AutoPrint.Machine.TjJingCaiV1.MacReport.MacReportService();
                                    DecodeMachinePayMoneyReport decodePrintData = new DecodeMachinePayMoneyReport();
                                    decodePrintData.InputData = captureDataInfo;
                                    service.DecodeMachinePayMoneyReport(null, decodePrintData);

                                    if (decodePrintData.DecodeSuccess)
                                    {
                                        A10006UploadMachineBalance pack = new A10006UploadMachineBalance();
                                        pack.AgentId = MachineInfo.M_Number;
                                        pack.Salt = LotMachine.MachineInfo.M_Salt;

                                        pack.Balance = decodePrintData.MachinePayMoneyReportEntity.R_Balance;
                                        pack.QueryTime = decodePrintData.MachinePayMoneyReportEntity.R_QueryTime.ToString("yyyyMMddHHmmss");
                                        pack.From = decodePrintData.MachinePayMoneyReportEntity.R_QueryTime.ToString("yyyyMMdd");
                                        pack.To = decodePrintData.MachinePayMoneyReportEntity.R_QueryTime.ToString("yyyyMMdd");
                                        pack.Type = 1;
                                        pack.TypeName = pack.From;   //暂时只打天报表，以后有周月报表再说
                                        pack.Prntext = decodePrintData.MachinePayMoneyReportEntity.R_PrnText;

                                        A10006UploadMachineBalanceRet packRet = PackManager.Instance.Send(pack) as A10006UploadMachineBalanceRet;
                                        if (packRet.Code <= 0)
                                        {
                                            LotMachine.Log.Warn("上传缴款报表中的余额失败，" + packRet.Code.ToString() + " " + packRet.Message);
                                        }
                                        else 
                                        {
                                            LotMachine.Log.Info("上传缴款报表中的余额成功！" + packRet.AgentId);
                                        }


                                        A10007UploadMachinePay pack1 = new A10007UploadMachinePay();
                                        pack1.AgentId = MachineInfo.M_Number;
                                        pack1.Salt = LotMachine.MachineInfo.M_Salt;

                                        pack1.QueryTime = decodePrintData.MachinePayMoneyReportEntity.R_QueryTime;
                                        foreach (PayMoneyDataItem item in decodePrintData.MachinePayMoneyReportEntity.R_DataList)
                                        {
                                            pack1.PaymentList.Add(new UploadMachinePayItem(item.PayType, item.PayMoney, item.PayTime));
                                        }

                                        A10007UploadMachinePayRet packRet1 = PackManager.Instance.Send(pack1) as A10007UploadMachinePayRet;
                                        if (packRet1.Code <= 0)
                                        {
                                            LotMachine.Log.Warn("上传缴款报表中的缴款记录失败，" + packRet1.Code.ToString() + " " + packRet1.Message);
                                        }
                                        else
                                        {
                                            LotMachine.Log.Info("上传缴款报表中的缴款记录成功！" + packRet.AgentId);
                                        }
                                    }
                                    else
                                    {
                                        LotMachine.Log.Warn(string.Concat("解析缴款报表失败。错误信息：", decodePrintData.ErrorMessage));
                                    }
                                }


                                //竞彩上传电子票
                                if (ticketEntity.LotId == (int)Lottype.Jz || ticketEntity.LotId == (int)Lottype.Jl)
                                {

                                    DecodePrintData decodePrintData = new DecodePrintData();
                                    decodePrintData.InputData = captureDataInfo;
                                    MacLotPlayModeServiceFactory modeServiceFactory = new MacLotPlayModeServiceFactory();
                                    IMacLotPlayModeService modeService = modeServiceFactory.GetLotPlayService(ticketEntity.MacModeId);
                                    modeService.DecodeData(ticketEntity, MachineInfo, decodePrintData);

                                    if (decodePrintData.DecodeSuccess)
                                    {
                                        try
                                        {

                                            //通知票号
                                            A10002NotifyTicket pack = new A10002NotifyTicket();
                                            pack.AgentId = MachineInfo.M_Number;
                                            pack.Salt = LotMachine.MachineInfo.M_Salt;
                                            ticketEntity.L_TicketCode = decodePrintData.L_PrintTicketEntity.P_TicketCode;
                                            ticketEntity.L_Password = decodePrintData.L_PrintTicketEntity.P_Password;
                                            ticketEntity.L_CodeRate = decodePrintData.L_PrintTicketEntity.L_CodeRate;
                                            ticketEntity.L_CodeReference = decodePrintData.L_PrintTicketEntity.L_CodeReference;   //篮球
                                            ticketEntity.L_SucTime = decodePrintData.L_PrintTicketEntity.P_SucTime;
                                            ticketEntity.L_PrnText = decodePrintData.L_PrintTicketEntity.P_PrnText;
                                            ticketEntity.L_Status = (int)TicketStatus.Suc;
                                            ticketEntity.L_LimitType = 0;
                                            //解析出来的内容
                                            ticketEntity.L_Code = decodePrintData.L_PrintTicketEntity.P_Code;
                                            ticketEntity.L_Money = decodePrintData.L_PrintTicketEntity.P_Money;
                                            ticketEntity.L_Mutiple = decodePrintData.L_PrintTicketEntity.P_Mutiple;
                                            ticketEntity.L_CodeType = decodePrintData.L_PrintTicketEntity.L_CodeType;
                                            pack.Ticket = ticketEntity;

                                            int retry = 0;
                                            int retCode = 0;
                                            while (retry < 3)
                                            {
                                                A10002NotifyTicketRet packRet = PackManager.Instance.Send(pack) as A10002NotifyTicketRet;
                                                if (packRet.Code > 0)
                                                {
                                                    retCode = packRet.Code;
                                                    break;
                                                }

                                                retry++;
                                                if (retry == 3)
                                                {
                                                    LotMachine.Log.Warn("【操作提示】：请尝试点击“重新通知”！");
                                                    throw new Exception("票号通知失败（已自动尝试3次），" + packRet.Code.ToString() + " " + packRet.Message);
                                                }

                                                Thread.Sleep(retry * 1000);
                                            }

                                            if (retCode == 300)
                                            {
                                                //删除last目录下最后一个文件
                                                LotMachine.VirtualPrinter.DeleteLastFile();

                                                LotMachine.Log.Info(string.Concat("票号通知成功：", ticketEntity.L_TicketSn, " 彩种：", ticketEntity.L_LotName, ticketEntity.LotId, "玩法：", ticketEntity.L_PlayName, ticketEntity.L_PlayId, "倍数：", ticketEntity.L_Mutiple, "金额：", ticketEntity.L_Money));
                                            }
                                            else if (retCode == 304)
                                            {
                                                LotMachine.Log.Info("回写了一张错票!");
                                            }
                                        }
                                        catch (Exception exception)
                                        {
                                            LotMachine.Log.Warn(string.Concat("票号通知失败。生产流水号：", ticketEntity.L_TicketSn, " 票号：", ticketEntity.L_TicketCode, " 密码：", ticketEntity.L_Password));

                                        }
                                    }
                                    else
                                    {
                                        LotMachine.Log.Warn(string.Concat("解析电子票失败。生产流水号：", ticketEntity.L_TicketSn, " 错误信息：", decodePrintData.ErrorMessage));
                                    }
                                }
                                
                            }
                            
                        }
                    }
                    if (toalwait == 30000)
                    {
                        toalwait = 0;
                        Log.Info("虚拟打印机心跳正常");
                    }

                }
                try
                {
                    PrinterPort.Close();
                    PrinterPort.Dispose();
                }
                finally
                {
                    PrinterPort = null;
                }
                Status = VirtualPrinterStatus.Stopped;
                Log.Info(string.Concat("虚拟打印机停止"));

            }
            catch (Exception ex)
            {
                Log.Warn(string.Concat("彩票机 ", this.MachineInfo.M_Number, " 打印机接收数据异常，请停止出票，重启软件，否则会白出！！！"));

                //Log.Warn(string.Concat("彩票机 ", this.MachineInfo.M_Number, " 接收数据异常：", ex.ToString()));
                //if (ex.Message.Contains("口被关闭"))
                //{
                //    Log.Warn("操作提示：软件已经抓取不到票数据，将导致错票（彩票机出了但没有票），请停止出票，重启软件！");
                //}
            }
            //finally
            //{
            //    if (AlldataStream != null)
            //    {
            //        AlldataStream.Close();
            //        AlldataStream.Dispose();
            //    }
            //}

        }

        private void Write(string strWrite)
        {

            byte[] data = StringToBytes(strWrite);
            PrinterPort.Write(data, 0, data.Length);
            Log.Info("Write:" + strWrite);
            /*
            for (int j = 0; j < blist.Length; j++)
            {
                if (1 > 1)
                    Thread.Sleep(1);
                com1.Write(blist, j, 1);
            }
            */
        }

        public static byte[] StringToBytes(string str)
        {
            string[] ByteStrings;
            byte[] result;
            try
            {
                ByteStrings = str.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                result = new byte[ByteStrings.Length];
                for (int i = 0; i < ByteStrings.Length; i++)
                {
                    result[i] = Convert.ToByte(ByteStrings[i], 16);
                }
            }
            catch
            {
                result = new byte[1] { 0 };
            }
            return result;
        }

        public static string BytesToString(byte[] data)
        {
            string result = "";
            if (data != null)
            {
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < data.Length; i++)
                {
                    sb.Append(data[i].ToString("X2")).Append(" ");
                }
                result = sb.ToString();
            }
            return result;
        }
        #endregion
    }
}
