using Newtonsoft.Json;
using NLog;
using System;
using System.ComponentModel;
using System.IO;
using System.Windows.Threading;

namespace GeneralGommunication
{
    public class ModbusAsciiAsyncConnector : INotifyPropertyChanged
    {
        public Logger comm_logger;

        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// AD盒地址, 当为 TCP通讯时，为 192.168.251.200:20020;
        /// 当为 串口通讯时， 为 COM6
        /// </summary>

        public string Addr { get; set; } = "192.168.251.60:1502";

        /// <summary>
        /// 连接成功
        /// </summary>
        public bool IsConnected { get; private set; }

        public ModbusAsciiAsync Modbus => modbus;

        IGeneralComm comm;
        ModbusAsciiAsync modbus;


        public ModbusAsciiAsyncConnector()
        {
            modbus = new ModbusAsciiAsync();
            
        }

        public ModbusAsciiAsyncConnector(string filePath):this()
        {
            this.filePath = filePath;
        }

        public void Init()
        {

            //启动速度测量
            modbus.Csm.StartMeasure();

            //注册modbus发送动作，把数据通过 comm模块发送出去
            modbus.SendMsgEvent += (s, msg) =>
            {
                comm?.Write(msg);
            };

        }



        /// <summary>
        /// 断开连接
        /// </summary>
        public void Disconnect()
        {
            if (comm != null)
            {
                comm.Stop();
                //只要comm.Stop()  IsConnected 就会为 False,  就会触发 modbus.AllDeviceDisconnect();
            }
        }

        /// <summary>
        /// 连接
        /// </summary>
        public void Connect()
        {
            Connect(Addr);
        }


        /// <summary>
        /// 连接 addr
        /// </summary>
        /// <param name="addr"></param>
        public void Connect(string addr)
        {
            Addr = addr;
            if (comm == null)
            {
                createComm();
            }
            else
            {
                comm.Stop();
                //只要comm.Stop()  IsConnected 就会为 False,  就会触发 modbus.AllDeviceDisconnect();

                if ((Addr.ToLower().StartsWith("com") && (comm is GComm_SerialPort)) ||
                    (!Addr.ToLower().StartsWith("com") && (comm is GComm_TcpClient)))
                {
                    //不用重建
                }
                else
                {
                    disposeComm();
                    createComm();
                }
            }

            comm.Addr = addr;
            comm.Start();
        }


        void createComm()
        {
            if (Addr.ToLower().StartsWith("com"))
            {
                var _comm = new GComm_SerialPort();
                _comm.Init(new System.IO.Ports.SerialPort()
                {
                    BaudRate = 19200,
                    DataBits = 8,
                    Parity = System.IO.Ports.Parity.None,
                    StopBits = System.IO.Ports.StopBits.One
                });
                _comm.logger = comm_logger;
                comm = _comm;
            }
            else
            {
                var _comm = new GComm_TcpClient();
                _comm.logger = comm_logger;
                comm = _comm;
            }
            comm.DataReceived += Comm_DataReceived;
            comm.PropertyChanged += Comm_PropertyChanged;
            IsConnected = comm.IsConnected;
        }

        private void Comm_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(comm.IsConnected))
            {
                IsConnected = comm.IsConnected;
                if (!IsConnected) {
                    modbus.ResetMsg();
                }
            }
        }

        void disposeComm()
        {
            comm.DataReceived -= Comm_DataReceived;
            comm.PropertyChanged -= Comm_PropertyChanged;
            IsConnected = false;
        }

        private void Comm_DataReceived(IGeneralComm sender, byte[] buf)
        {
            modbus.RecMsg(buf);
        }

        /// <summary>
        /// 重连
        /// </summary>
        public void ReConnect()
        {
            Connect();
        }

        string filePath = "modbusAscii.json";
        /// <summary>
        /// 参数保存
        /// </summary>
        public void Save()
        {
            ModbusAsciiAsyncConnectorJsonDb.Save(filePath, this);
        }
        public bool Load()
        {
            return ModbusAsciiAsyncConnectorJsonDb.Load(filePath, this);
        }

    }

    class ModbusAsciiAsyncConnectorJsonDb
    {
        public static void Save(string jsonDbPath, ModbusAsciiAsyncConnector src)
        {

            if (string.IsNullOrEmpty(jsonDbPath))
                return;

            ModbusAsciiAsyncConnectorJsonDb jsonDb = new ModbusAsciiAsyncConnectorJsonDb()
            {
                Addr = src.Addr,
            };

            try
            {
                File.WriteAllText(jsonDbPath, JsonConvert.SerializeObject(jsonDb, Formatting.Indented));
            }
            catch
            {
                //异常，没有json 编码失败
            }
        }
        public static bool Load(string jsonDbPath, ModbusAsciiAsyncConnector src)
        {
            if (string.IsNullOrEmpty(jsonDbPath))
                return false;

            try
            {
                if (File.Exists(jsonDbPath))
                {
                    string json = File.ReadAllText(jsonDbPath);
                    var jsonDb = JsonConvert.DeserializeObject<ModbusAsciiAsyncConnectorJsonDb>(json);
                    src.Addr = jsonDb.Addr;
                    return true;
                }
            }
            catch
            {
                //异常，没有json 解码失败
            }
            return false;
        }

        public string Addr { get; set; } = "192.168.251.60:1502";

    }
}
