using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SerialDebug;
using 常用工具集.Base;
using MES.Utility.Core;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;

namespace 常用工具集.ViewModel._01PLC通信调试
{
    public class 串口调试工具ViewModel : ViewModelBase
    {
        private System.IO.Ports.SerialPort serialPort;
        public bool Enabled1 { get; set; } = true;
        public bool Enabled2 { get; set; } = false;
        public string ButtonText { get; set; } = "打开";
        //串口号下拉列表数据
        public List<string> SerialList { get; set; }
        public int SerialIndex { get; set; } = 0;

        /// <summary>
        /// 波特率
        /// </summary>
        public List<int> BaudRateList { get; set; }
        public int BaudRateIndex { get; set; } = 0;
        //校验
        public List<string> ParityList { get; set; }
        public int ParityIndex { get; set; } = 0;

        //数据为
        public List<int> DataBitList { get; set; }
        public int DataBitIndex { get; set; } = 0;

        //数据为
        public List<string> FlowControlList { get; set; } = new List<string>() { "None", "XOnXOff", "RequestToSend", "RequestToSendXOnXOff" };

        public int FlowControlIndex { get; set; } = 0;
        //停止位
        public List<string> StopBitList { get; set; }
        public int StopBitIndex { get; set; } = 0;

        public int Timeout { get; set; } = 100;


        public bool RTSChecked { get; set; } = true;


        public bool DTRChecked { get; set; } = false;

        public bool ReciveASCChecked { get; set; } = true;
        public bool ReciveHexChecked { get; set; } = false;


        public bool SendASCChecked { get; set; } = true;
        public bool SendHexChecked { get; set; } = false;
        public bool ConvertChecked { get; set; } = true;
        public bool CycleChecked { get; set; } = false;
        public int CycleTime { get; set; } = 1000;


        public string SendContent { get; set; } = "";

        private object _lock = new object();
        private List<string> msgList = new List<string>();
        public string Message
        {
            get
            {
                lock (_lock)
                {
                    return msgList.GetStrArray("\r\n");
                }
            }
            set
            {
                NotifyPropertyChanged();
            }
        }

        public DelegateCommand OpenSerialCmd { get; set; }
        public DelegateCommand ClearReciveCmd { get; set; }
        public DelegateCommand ClearSendCmd { get; set; }
        public DelegateCommand SendCmd { get; set; }


        private CSerialDebug sp;
        public 串口调试工具ViewModel()
        {
            serialPort = new SerialPort();
            sp = new CSerialDebug(serialPort);
            //串口号
            string[] portNames = SerialPort.GetPortNames();
            if (portNames != null && portNames.Length > 0)
            {
                SerialList = portNames.ToList();
            }
            //波特率
            BaudRateList = new List<int>() { 110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 56000, 57600, 115200, 128000 };
            BaudRateIndex = 6;
            //校验
            ParityList = new List<string> { "None", "Odd", "Even", "Mark", "Space" };
            ParityIndex = 0;
            //数据位
            DataBitList = new List<int> { 5, 6, 7, 8 };
            DataBitIndex = 3;
            //停止位
            StopBitList = new List<string> { "None", "One", "Two", "OnePointFive" };
            StopBitIndex = 1;

            //打开关闭串口
            OpenSerialCmd = new DelegateCommand(OpenSerialCmdFunc);
            ClearReciveCmd = new DelegateCommand(ClearReciveCmdFunc);
            ClearSendCmd = new DelegateCommand(ClearSendCmdFunc);
            SendCmd = new DelegateCommand(SendCmdFunc);
        }

        private void OpenSerialCmdFunc(object obj)
        {
            try
            {
                if (ButtonText == "打开")
                {
                    serialPort.PortName = SerialList[SerialIndex];
                    serialPort.BaudRate = BaudRateList[BaudRateIndex];
                    serialPort.Parity = (Parity)ParityIndex;
                    serialPort.DataBits = DataBitList[DataBitIndex];
                    serialPort.StopBits = (StopBits)StopBitIndex;
                    serialPort.Handshake = (Handshake)FlowControlIndex;
                    serialPort.DtrEnable = DTRChecked;
                    serialPort.RtsEnable = RTSChecked;
                    serialPort.ReadBufferSize = 2 * 1024 * 1024;// 2M

                    sp.ReceiveTimeOut = Timeout;
                    sp.Start();
                    sp.ReceivedEvent += new CSerialDebug.ReceivedEventHandler(sp_ReceivedEvent);
                    sp.SendCompletedEvent += new CSerialDebug.SendCompletedEventHandler(sp_SendCompletedEvent);
                    sp.SendOverEvent += new EventHandler(sp_SendOverEvent);
                    ButtonText = "关闭";
                    Enabled1 = false;
                    Enabled2 = true;
                }
                else
                {
                    sp.StopSend();
                    sp.ReceivedEvent -= new CSerialDebug.ReceivedEventHandler(sp_ReceivedEvent);
                    sp.SendCompletedEvent -= new CSerialDebug.SendCompletedEventHandler(sp_SendCompletedEvent);
                    sp.SendOverEvent -= new EventHandler(sp_SendOverEvent);
                    sp.Stop();
                    ButtonText = "打开";
                    Enabled1 = true;
                    Enabled2 = false;
                }
            }
            catch (Exception ex)
            {
                GlobalValues.Error(ex.Message);
            }
        }


        private void ClearReciveCmdFunc(object obj)
        {
            lock (_lock)
            {
                msgList.Clear();
            }
            Message = Guid.NewGuid().ToString();
        }

        private void ClearSendCmdFunc(object obj)
        {
            SendContent = string.Empty;
        }

        private void SendCmdFunc(object obj)
        {
            try
            {

                if (SendContent.IsNullOrEmpty())
                {
                    GlobalValues.Error("没有任何可发送的数据");
                    return;
                }
                //要发送的数据
                List<CSendParam> list = new List<CSendParam>();
                SendParamFormat format = SendParamFormat.ASCII;
                if (SendHexChecked)
                {
                    format = SendParamFormat.Hex;
                }
                int sendInterval = Convert.ToInt32(CycleTime);
                CSendParam param = new CSendParam(format, SendParamMode.SendAfterLastSend, sendInterval, SendContent, ConvertChecked);
                list.Add(param);
                if (CycleChecked)
                {
                    sp.Send(list, 0);
                }
                else
                {
                    sp.Send(list, 1);
                }

            }
            catch (Exception ex)
            {
                GlobalValues.Error(ex.Message);
            }
        }



        private void sp_SendCompletedEvent(object sender, SendCompletedEventArgs e)
        {
            if (e.SendParam == null)
            {
                GlobalValues.Error("发送失败");
                OpenSerialCmdFunc(null);
                return;
            }
            lock (_lock)
            {
                msgList.Add($"{e.TimeString}[-->]");
                if (SendASCChecked)
                {
                    msgList.Add(e.SendParam.ASCIIString);
                }
                else
                {
                    msgList.Add(e.SendParam.HexString);
                }
                if (msgList.Count > 300)
                {
                    int cha = msgList.Count - 300;
                    //lines.Reverse();
                    //差多少，删多少
                    for (int i = 0; i < cha; i++)
                    {
                        msgList.RemoveAt(0);
                    }
                }
            }
            Message = Guid.NewGuid().ToString();
        }

        /// <summary>
        /// 接收事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void sp_ReceivedEvent(object sender, SerialDebugReceiveData e)
        {
            if (e != null)
            {
                lock (_lock)
                {
                    msgList.Add($"{e.TimeString}[<--]");
                    if (ReciveASCChecked)
                    {
                        msgList.Add(e.ASCIIString);
                    }
                    else
                    {
                        msgList.Add(e.HexString);
                    }
                    if (msgList.Count > 300)
                    {
                        int cha = msgList.Count - 300;
                        //lines.Reverse();
                        //差多少，删多少
                        for (int i = 0; i < cha; i++)
                        {
                            msgList.RemoveAt(0);
                        }
                    }
                }
                Message = Guid.NewGuid().ToString();
            }
        }


        void sp_SendOverEvent(object sender, EventArgs e)
        {
        }
    }
}
