using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using 常用工具集.Base;
using MES.Utility.Network.S7netplus;
using S7.Net;

namespace 常用工具集.ViewModel._01PLC通信调试
{
    public class 西门子PLC调试ViewModel : ViewModelBase
    {
        public bool Enabled1 { get; set; } = true;
        public bool Enabled2 { get; set; } = false;
        public string IpAddress { get; set; } = "192.168.1.11";
        public string Address { get; set; } = "DB44.DBD80";

        public List<string> PlcTypeList { get; set; }
        public List<CpuType> PlcTypeEnumList { get; set; }
        public int PlcTypeIndex { get; set; } = 0;
        public short R { get; set; } = 0;
        public short S { get; set; } = 1;

        public int DBAddress2 { get; set; } = 40;
        public int Address2 { get; set; } = 80;
        public int StringLength { get; set; } = 50;
        public string BoolValue { get; set; } = "true";
        public string Int16Value { get; set; } = "";
        public string Int32Value { get; set; } = "";
        public string RealValue { get; set; } = "";
        public string StringValue { get; set; } = "";
        public string StringValue1 { get; set; } = "";
        public int BytesCount { get; set; } = 50;
        public string ReadedValue { get; set; } = "";
        public string Message { get; set; } = "";

        public DelegateCommand ConnectCmd { get; set; }
        public DelegateCommand DisconnectCmd { get; set; }

        public DelegateCommand ReadCmd { get; set; }
        public DelegateCommand WriteCmd { get; set; }
        private S7Helper plc;
        public 西门子PLC调试ViewModel()
        {
            PlcTypeList = new List<string> { "S7-1200", "S7-1500", "S7-200", "S7-300", "S7-400" };
            PlcTypeEnumList = new List<CpuType> { CpuType.S71200, CpuType.S71500, CpuType.S7200, CpuType.S7300, CpuType.S7400 };
            ConnectCmd = new DelegateCommand(ConnectCmdFunc);
            DisconnectCmd = new DelegateCommand(DisconnectCmdFunc);
            ReadCmd = new DelegateCommand(ReadCmdFunc);
            WriteCmd = new DelegateCommand(WriteCmdFunc);
        }


        /// <summary>
        /// 连接
        /// </summary>
        /// <param name="obj"></param> 
        private void ConnectCmdFunc(object obj)
        {
            try
            {
                this.plc = new S7Helper(PlcTypeEnumList[PlcTypeIndex], IpAddress, R, S);
                Enabled2 = true;
                Enabled1 = false;
            }
            catch
            {
                GlobalValues.Error("PLC连接失败");
            }
        }
        /// <summary>
        /// 断开连接
        /// </summary>
        /// <param name="obj"></param> 
        private void DisconnectCmdFunc(object obj)
        {
            try { plc.Dispose(); } catch { }
            plc = null;
            Enabled1 = true;
            Enabled2 = false;
        }

        /// <summary>
        /// 读取操作
        /// </summary>
        /// <param name="obj"></param>
        private void ReadCmdFunc(object obj)
        {
            ReadedValue = string.Empty;
            Message = string.Empty;
            string cmd = obj.ToString();
            if (cmd == "BOOL")
            {
                bool value;
                bool flag = plc.ReadBool(Address, out value);
                if (!flag)
                {
                    ReadedValue = string.Empty;
                    Message = "读取失败";
                    return;
                }
                ReadedValue = value.ToString();
                Message = "读取成功";
            }
            else if (cmd == "INT16")
            {
                ushort value;
                bool flag = plc.ReadInt16(Address, out value);
                if (!flag)
                {
                    ReadedValue = string.Empty;
                    Message = "读取失败";
                    return;
                }
                ReadedValue = value.ToString();
                Message = "读取成功";
            }
            else if (cmd == "INT32")
            {
                int value;
                bool flag = plc.ReadInt32(Address, out value);
                if (!flag)
                {
                    ReadedValue = string.Empty;
                    Message = "读取失败";
                    return;
                }
                ReadedValue = value.ToString();
                Message = "读取成功";
            }
            else if (cmd == "REAL")
            {
                float value;
                bool flag = plc.ReadSingle(Address, out value);
                if (!flag)
                {
                    ReadedValue = string.Empty;
                    Message = "读取失败";
                    return;
                }
                ReadedValue = value.ToString();
                Message = "读取成功";
            }
            else if (cmd == "STRING1")
            {
                string value;
                bool flag = plc.ReadString(Address, StringLength, out value);
                if (!flag)
                {
                    ReadedValue = string.Empty;
                    Message = "读取失败";
                    return;
                }
                ReadedValue = value.ToString();
                Message = "读取成功";
            }
            else if (cmd == "STRING")
            {
                string value;
                bool flag = plc.ReadBytesString(Address, StringLength, out value);
                if (!flag)
                {
                    ReadedValue = string.Empty;
                    Message = "读取失败";
                    return;
                }
                ReadedValue = value.ToString();
                Message = "读取成功";
            }
            else if (cmd == "Bytes")
            {
                byte[] value;
                bool flag = plc.ReadBytes(DBAddress2, Address2, BytesCount, out value);
                if (!flag)
                {
                    Message = "读取失败";
                    return;
                }
                ReadedValue = ToHexStrFromByte(value);
                Message = "读取成功";
            }
        }

        private void WriteCmdFunc(object obj)
        {
            ReadedValue = string.Empty;
            Message = string.Empty;
            string cmd = obj.ToString();
            if (cmd == "BOOL")
            {
                bool value;
                bool flag = bool.TryParse(BoolValue, out value);
                if (!flag)
                {
                    Message = "请输入true或者false";
                    return;
                }
                flag = plc.WriteBool(Address, value);
                Message = flag ? "写入成功" : "写入失败";
            }
            else if (cmd == "INT16")
            {
                ushort value;
                bool flag = ushort.TryParse(Int16Value, out value);
                if (!flag)
                {
                    Message = "请输入正确的数据";
                    return;
                }
                flag = plc.WriteInt16(Address, value);
                Message = flag ? "写入成功" : "写入失败";
            }
            else if (cmd == "INT32")
            {
                int value;
                bool flag = int.TryParse(Int32Value, out value);
                if (!flag)
                {
                    Message = "请输入正确的数据";
                    return;
                }
                flag = plc.WriteInt32(Address, value);
                Message = flag ? "写入成功" : "写入失败";
            }
            else if (cmd == "REAL")
            {
                float value;
                bool flag = float.TryParse(RealValue, out value);
                if (!flag)
                {
                    Message = "请输入正确的数据";
                    return;
                }
                Message = flag ? "写入成功" : "写入失败";
            }
            else if (cmd == "STRING1")
            {
                bool flag = plc.WriteString(Address, StringValue1, StringLength);
                Message = flag ? "写入成功" : "写入失败";
            }
            else if (cmd == "STRING")
            {
                bool flag = plc.WriteBytesString(Address, StringValue, StringLength);
                Message = flag ? "写入成功" : "写入失败";
            }
        }

        /// <summary>
        /// 字节数组转16进制字符串：空格分隔
        /// </summary>
        /// <param name="byteDatas"></param>
        /// <returns></returns>
        private string ToHexStrFromByte(byte[] byteDatas)
        {
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < byteDatas.Length; i++)
            {
                builder.Append(string.Format("{0:X2} ", byteDatas[i]));
            }
            return builder.ToString().Trim();
        }
    }
}
