using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Advantech.Motion;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using ProductionControl.UI.PropExtend;
using static ProductionControl.UI.UIAxisDev;

namespace ProductionControl.UI
{
    //[TypeConverter(typeof(PropertySorter))] //此属性使类无法序列化和反序列化
    public class IOCardDevProp
    {
        private byte[] _in, _out; 
        public IOCardDevProp(string deviceNum) {
            DeviceNum = deviceNum;
        }

        [PropertyOrder(1), Browsable(true), Category("1 设备"), DisplayName("设备号"), Description("设备号"), ReadOnly(true), JsonIgnore]
        public string DeviceNum { get;private set; } 

        //
        [PropertyOrder(11), Browsable(false), Category("2 时时数据"), DisplayName("输入"), Description("输入"), ReadOnly(true), JsonIgnore]
        public byte[] IN
        {
            get
            {
                return _in;
            }
            set
            {
                _in = value;
                if (value == null)
                    IN_SHOW = null;
                else
                {
                    IN_SHOW = new string[value.Length]; 
                    IN_OP_SHOW= new string[value.Length];
                    for (int i = 0; i < IN_OP_SHOW.Length; i++)
                    {
                        if (string.IsNullOrWhiteSpace(IN_OP_SHOW[i]))
                            IN_OP_SHOW[i] = "XXXX XXXX";
                    }

                    string s;
                    for (int i = 0; i < value.Length; i++)
                    { 
                        s = Convert.ToString(value[i], 2).PadLeft(8, '0').Replace('0', 'L').Replace('1', 'H');
                        //IN_SHOW[i] = String.Join(" ", s.Reverse());
                        IN_SHOW[i] = s.Substring(0, 4) + " " + s.Substring(4);
                    }
                }
            }
        }
        [PropertyOrder(12), Browsable(false), Category("2 时时数据"), DisplayName("输出"), Description("输出"), ReadOnly(true), JsonIgnore]
        public byte[] OUT 
        {
            get
            {
                return _out;
            }
            set
            {
                _out = value;
                if (value == null)
                    OUT_SHOW = null;
                else
                {
                    OUT_SHOW = new string[value.Length];
                    OUT_OP_SHOW = new string[value.Length];
                    string s;
                    for (int i = 0; i < value.Length; i++)
                    {
                        s = Convert.ToString(value[i], 2).PadLeft(8, '0').Replace('0', 'L').Replace('1', 'H');
                        OUT_SHOW[i] = s.Substring(0, 4) + " " + s.Substring(4); //String.Join(" ", s.Reverse());
                        OUT_OP_SHOW[i] = "XXXX XXXX";
                    }
                }
            }
        }
        [PropertyOrder(11), Browsable(true), Category("2 时时数据"), DisplayName("2.1 输入"), Description("输入 (H-高/1；L-低/0)"), ReadOnly(true), JsonIgnore]
        public string[] IN_SHOW { get; set; }
        [PropertyOrder(12), Browsable(true), Category("2 时时数据"), DisplayName("2.2 输出"), Description("输出 (H-高/1；L-低/0)"), ReadOnly(true), JsonIgnore]
        public string[] OUT_SHOW { get; set; }

        //IN_OP OUT_OP_INDEX OUT_OP_BIT_INDEX OUT_OP_VALUE
        [PropertyOrder(1), Browsable(true), Category("3 指令"), DisplayName("3.1 作业方向"), Description("作业方向")]
        public IODirectionEnum Direction { get; set; }
        /// <summary>
        /// 输入值， XXXX XXHL
        /// </summary>
        [PropertyOrder(11), Browsable(true), Category("3 指令"), DisplayName("3.2 输入指令值"), Description("输入指令值 (H-高/1；L-低/0；X-忽略)")]
        public string[] IN_OP_SHOW { get; set; }//单改数组属性不触发SET 
        [PropertyOrder(11), Browsable(true), Category("3 指令"), DisplayName("3.3 输入超时告警(ms)"), Description("自动流程中等待输入指令超时则告警,0则无限期等待")]
        public uint IN_Waiting_Timeout { get; set; } = 0;

        /// <summary>
        /// 输出值， XXXX XXHL
        /// </summary>
        [PropertyOrder(11), Browsable(true), Category("3 指令"), DisplayName("3.4 输出指令值"), Description("输出指令值 (H-高/1；L-低/0；X-忽略)")]
        public string[] OUT_OP_SHOW { get; set; }

        //
        [PropertyOrder(25), Browsable(true), Category("4 控制"), DisplayName("4.1 运行前Sleep(ms)"), Description("休息时间")]
        public uint SleepPre { get; set; }
        [PropertyOrder(26), Browsable(true), Category("4 控制"), DisplayName("4.2 运行后Sleep(ms)"), Description("休息时间")]
        public uint SleepLater { get; set; } 
        [PropertyOrder(27), Browsable(true), Category("4 控制"), DisplayName("4.4 禁用工序"), Description("禁用本工序(True-是；False-否)")]
        public bool Disable { get; set; }
        /// <summary>
        /// 序列化
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public string serialize()
        {  
            return JsonConvert.SerializeObject(this);
        }
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="json"></param>
        /// <returns></returns>
        public void deserialize(string json)
        { 
            var o=  JsonConvert.DeserializeObject<IOCardDevProp>(json);
            Type type = o.GetType();
            System.Reflection.PropertyInfo[] properties = type.GetProperties(); 
            foreach (System.Reflection.PropertyInfo property in properties)
            {
                string name = property.Name;
                if (!type.GetProperty(name).IsDefined(typeof(JsonIgnoreAttribute), true))
                {
                    var value = property.GetValue(o);
                    this.GetType().GetProperty(name).SetValue(this, value);
                }
            }

        }

        private byte[] inputValue2byte(string[] strList)
        {
            byte[] result=new byte[strList.Length];

            string[] strArr = Utils.Util.IODataFormatBinaryStr(strList,false, 'L'); 
            for (int i=0; i< strArr.Length; i++)
            {
                strArr[i] = strArr[i].Replace("L", "0").Replace("H", "1").Replace("X", "0");
                result[i] = Convert.ToByte(strArr[i], 2);
            }

            return result;
        }  
    }
     

}
