using ProjectManagementSystem.Device.Extenions;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ProjectManagementSystem.Device.Core
{
    public class CommunicationCom : CommunicationBase, ICommunication
    {
        private SerialPort m_comDevice;

        public bool IsStart { get { return m_comDevice != null && m_comDevice.IsOpen; } }
        public string ComPortName { get; set; }
        public int ComBaudRate { get; set; }

        public CommunicationCom(string portName, int baudRate)
        {
            ComPortName = portName;
            ComBaudRate = baudRate;
        }

        public void Start()
        {
            if (Init())
            {
                LogMsg($"串口{ComPortName}已打开");
            }
            else
            {
                LogMsg($"串口{ComPortName}打开失败");
            }
        }

        public void Stop()
        {
            try
            {
                m_comDevice.DataReceived -= M_comDevice_DataReceived;
                m_comDevice.Close();
                m_comDevice.Dispose();
            }
            catch (Exception ex)
            {
                LogMsg("关闭串口异常", ex);
            }
        }

        public bool Init()
        {
            m_comDevice = new SerialPort
            {
                PortName = ComPortName,
                BaudRate = ComBaudRate,
                Parity = Parity.None,
                DataBits = 8,
                StopBits = StopBits.One,
            };

            try
            {
                m_comDevice.Open();
                m_comDevice.DataReceived += M_comDevice_DataReceived;
                return m_comDevice.IsOpen;
            }
            catch (Exception ex)
            {
                LogMsg($"打开串口{ComPortName}异常", ex);
            }

            return false;
        }

        private void M_comDevice_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                //System.Threading.Thread.Sleep(20);
                byte[] buffer = new byte[m_comDevice.BytesToRead];
                m_comDevice.Read(buffer, 0, buffer.Length);

                LogMsg($"{m_comDevice.PortName}: Recv: {buffer.Byte2HexString()}");

                DataReceived?.Invoke(m_comDevice.PortName, buffer);
            }
            catch (Exception ex)
            {
                LogMsg("串口接收数据异常", ex);
            }

        }

        public void SendCommand(byte[] data, string address)
        {
            try
            {
                if (!m_comDevice.IsOpen)
                {
                    LogMsg($"{ComPortName}未打开，尝试重新打开...");
                    Stop();
                    Init();
                }

                if (string.IsNullOrEmpty(address)
                    || m_comDevice.PortName == address)
                {
                    m_comDevice.Write(data, 0, data.Length);
                    LogMsg($"{ComPortName}: Send: {data.Byte2HexString()}");
                }
            }
            catch (Exception ex)
            {
                LogMsg($"{ComPortName}: SendErr: {data.Byte2HexString()}", ex);
            }
        }
    }
}
