using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using DH.Commons.Enums;

namespace DH.Devices.Motion
{
    public class MotionBase
    {
        //[Category("板卡配置")]
        //[DisplayName("板卡站号")]
        //[Description("板卡站号")]
        //public virtual ushort StationNumber { get; set; } = 0;

        public TaskFactory _taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.LongRunning);
        protected Dictionary<int, bool> _axisAlarmRaisedFlag = new Dictionary<int, bool>();
        protected Dictionary<int, System.Threading.Timer> _axisLimitTimer = new Dictionary<int, System.Threading.Timer>();

        //[Category("扩展卡设置")]
        //[Description("扩展卡数量")]
        //[DisplayName("扩展卡数量")]
        //public ushort CardExtNum { get; set; } = 0;

        public List<AxisMovingStatus> AxisStatusList { get; set; } = new List<AxisMovingStatus>();



        public virtual void Init() { }

        public virtual void Start() { }

        public virtual void Stop() {  }
        public virtual void ResetImmediatePause(bool isResumeMoving) { }

        public virtual bool AllAxisOn() { return false; }

        public virtual void SetImmediatePause() { }



        public virtual bool AllAxisOff() { return false; }

        public virtual async Task AxisOnAsync(int axisNum){ }

        public virtual async Task AxisOffAsync(int axisNum) { }

        public virtual List<AxisInfo> GetCurrentAxisInfo(params string[] axisName) { return new List<AxisInfo>(); }

        public bool isconnected=false;


        [Category("板卡配置")]
        [DisplayName("板卡型号")]
        [Description("板卡型号")]
        public BoardModelEnum BoardModel { get; set; } = BoardModelEnum.EC3416;




        [Category("板卡配置")]
        [DisplayName("扩展板类型")]
        [Description("扩展板类型")]
        public ExtensionBoardEnum ExtBoard { get; set; } = ExtensionBoardEnum.None;



        [Category("机台配置")]
        [DisplayName("机台类型")]
        [Description("机台类型")]
        public MachineDiskType MachineDiskType { get; set; } = MachineDiskType.SingleDisk;




        [Category("轴配置")]
        [DisplayName("轴数量")]
        [Description("AxisNum:轴数量")]
        public int AxisNum { get; set; } = 4;


        [Category("轴配置")]
        [DisplayName("轴配置信息集合")]
        [Description("AxisSettings:轴配置信息集合")]
        public List<AxisSetting> AxisSettings { get; set; } = new List<AxisSetting>();

        [Category("轴配置")]
        [DisplayName("轴速度比率")]
        [Description("AxisVelocityRatio:轴速度比率")]
        public double AxisVelocityRatio { get; set; } = 1;

        //[Category("警报配置")]
        //[Description("WarningSetCollection:警报配置列表")]
        //[DisplayName("警报配置")]
        //[TypeConverter(typeof(CollectionCountConvert))]
        //[Editor(typeof(WarningSetsEditor<IOWarningSet>), typeof(UITypeEditor))]
        //public List<IWarningSet> WarningSetCollection { get; set; } = new List<IWarningSet>();

        [Category("IO配置")]
        [Description("输入IO总数")]
        [DisplayName("输入IO总数")]
        public int InputNums { get; set; } = 16;

        [Category("IO配置")]
        [Description("输出IO总数")]
        [DisplayName("输出IO总数")]
        public int OutputNums { get; set; } = 16;

        [Category("IO配置")]
        [DisplayName("IO定义集合")]
        [Description("IO定义集合")]
        //[TypeConverter(typeof(CollectionCountConvert))]
       // [Editor(typeof(ComplexCollectionEditor<IODefinition>), typeof(UITypeEditor))]
        public List<IODefinition> IODefinitionCollection { get; set; } = new List<IODefinition>();

        [Category("IO配置")]
        [DisplayName("是否信号模式")]
        [Description("true:信号模式,绿色表示有信号,灰色表示无信号 false:电平模式,绿色高电平,灰色低电平,一般情况下低电平表示有信号,板卡默认是电平模式")]
        public bool IsSignalMode { get; set; } = false;

        #region IMonitorConfig
        //[Category("监听设置")]
        //[Description("MonitorSetCollection:监听操作配置集合")]
        //[DisplayName("监听配置")]
        //[TypeConverter(typeof(CollectionCountConvert))]
        //[Editor(typeof(ComplexCollectionEditor<IOMonitorSet>), typeof(UITypeEditor))]
        //public List<IMonitorSet> MonitorSetCollection { get; set; } = new List<IMonitorSet>();

        [Category("监听设置")]
        [Description("true:启动监听 false:关闭监听")]
        [DisplayName("监听启用")]
        public bool IsEnableMonitor { get; set; } = false;

        [Category("监听设置")]
        [Description("扫描间隔时间,单位:ms")]
        [DisplayName("扫描间隔")]
        public int MonitorInterval { get; set; } = 20;

        [Category("监听设置")]
        [Description("超时设置,单位:ms")]
        [DisplayName("监听超时")]
        public int MonitorTimeout { get; set; } = 500;

        //public List<IMonitorSet> GetAllMonitorSet()
        //{
        //    WarningSetCollection.ForEach(m => m.SourceDevice = this.Name);
        //    MonitorSetCollection.ForEach(m => m.SourceDeviceId = this.Id);
        //    return MonitorSetCollection;
        //}
        #endregion




        #region 转盘卡新增配置


        [Category("筛选配置")]
        [DisplayName("启用转盘卡自动筛选功能")]
        [Description("启用转盘卡自动筛选功能")]
        public bool IsEnableFilter { get; set; } = true;

        [Category("筛选配置")]
        [DisplayName("启用转盘卡盘2触发取反")]
        [Description("启用转盘卡盘2触发取反")]
        public bool DiskSnaptChange { get; set; } = false;



        [Category("筛选配置")]
        [DisplayName("第二路来料检测配置")]
        [Description("第二路来料检测配置")]
        public SortingInputSetting SortingInputSetting { get; set; } = new SortingInputSetting();



        [Category("筛选配置")]
        [DisplayName("相机配置")]
        [Description("相机配置")]
        public List<SnapshotSetting> SnapshotSettings { get; set; } = new List<SnapshotSetting>();





        [Category("筛选配置")]
        [DisplayName("吹气口配置")]
        [Description("吹气口配置")]
        public List<BlowSetting> BlowSettings { get; set; } = new List<BlowSetting>();


        [Category("筛选配置")]
        [DisplayName("转盘运转方向")]
        [Description("转盘运转方向,顺时针或逆时针")]
        //[TypeConverter(typeof(EnumDescriptionConverter<RotationDirectionEnum>))]
        public RotationDirectionEnum MotionDir { get; set; } = RotationDirectionEnum.Clockwise;



        [Category("筛选配置")]
        [DisplayName("物料尺寸最大值")]
        [Description("物料尺寸最大值,单位:脉冲")]
        public uint PieceMaxSize { get; set; } = 20000;


        [Category("筛选配置")]
        [DisplayName("物料尺寸最小值")]
        [Description("物料尺寸最小值,单位:脉冲")]
        public uint PieceMinSize { get; set; } = 10;


        [Category("筛选配置")]
        [DisplayName("物料最小间隔")]
        [Description("物料最小间隔,单位:脉冲")]
        public uint MinDistance { get; set; } = 10;

        [Category("筛选配置")]
        [DisplayName("两个物料之间触发最小间隔时间")]
        [Description("两个物料之间触发最小间隔时间,单位:ms")]
        public uint MinTimeInterval { get; set; } = 1;



        [Category("急停配置")]
        [DisplayName("启用转盘卡硬件急停")]
        [Description("启用转盘卡硬件急停")]
        public bool IsEnableEmgStop { get; set; } = false;


        [Category("急停配置")]
        [DisplayName("急停信号触发索引")]
        [Description("急停信号触发索引")]
        public ushort EmgStopSignalIoIndex { get; set; } = 4;


        [Category("急停配置")]
        [DisplayName("急停触发信号")]
        [Description("急停触发信号")]
        public EMG_Mode EmgMode { get; set; } = EMG_Mode.EMG_Trigger_High_IMD;






        #endregion


        public List<IOItem> CurrentIOs { get; set; } = new List<IOItem>();

    }

    /// <summary>
    /// 吹气口配置
    /// </summary>
    public class BlowSetting
    {

        [Category("板卡配置")]
        [DisplayName("板卡站号")]
        [Description("板卡站号")]
        public virtual ushort StationNumber { get; set; } = 0;




        [Category("吹气口配置")]
        [DisplayName("是否启用")]
        [Description("是否启用")]
        public bool IsEnabled { get; set; } = false;

        [Category("吹气口配置")]
        [DisplayName("转盘运转方向")]
        [Description("转盘运转方向")]
        public RotationDirectionEnum RotationDirection { get; set; } = RotationDirectionEnum.Clockwise;

        //[Category("吹气口配置")]
        //[DisplayName("吹气口名称")]
        //[Description("吹气口名称")]
        //public string Name { get; set; } = "";


        [Category("吹气口配置")]
        [DisplayName("吹气口位置")]
        [Description("吹气口位置,即吹气口到入料检测传感器的相对位置,单位:脉冲")]
        public int BlowPosition { get; set; } = 0;


        [Category("吹气口配置")]
        [DisplayName("输出信号")]
        [Description("输出信号")]
        public ActionMode ActionMode { get; set; } = ActionMode.OutputPulse10ms;

        [Category("吹气口配置")]
        [DisplayName("吹气口IO")]
        [Description("吹气口IO")]
        public IODefinition BlowIO { get; set; } = new IODefinition() { IOType = IOType.OUTPUT };



        [Category("吹气口配置")]
        [DisplayName("吹气口类型")]
        [Description("吹气口类型")]
        public BlowType BlowType { get; set; }


        //public string GetDisplayText()
        //{
        //    //return $"{BlowType.GetEnumDescription()} 距离{BlowPosition} 输出{BlowIO.GetDisplayText()}";
        //}
    }
    public class SnapshotSetting : IComparable
    {

        [Category("板卡配置")]
        [DisplayName("板卡站号")]
        [Description("板卡站号")]
        public virtual ushort StationNumber { get; set; } = 0;


        [Category("取像相机设置")]
        [DisplayName("转盘运转方向")]
        [Description("转盘运转方向")]
        public RotationDirectionEnum RotationDirection { get; set; } = RotationDirectionEnum.Clockwise;


        [Category("取像相机设置")]
        [DisplayName("是否启用")]
        [Description("是否启用")]
        public bool IsEnabled { get; set; } = false;


        [Category("取像相机设置")]
        [Description("取像相机")]
        [DisplayName("取像相机")]
        public string CameraId { get; set; }


        [Category("取像相机设置")]
        [DisplayName("相机触发延时毫秒")]
        [Description("相机触发后延时显示,单位ms")]
        public double CameraDelayCountMS { get; set; } = 0;


        [Category("取像相机设置")]
        [DisplayName("相机位置")]
        [Description("相机位置,即相机到入料检测传感器的相对位置,单位:脉冲")]
        public int CameraPosition { get; set; } = 0;



        [Category("取像相机设置")]
        [DisplayName("相机IO")]
        [Description("相机IO")]
        public IODefinition CameraIO { get; set; } = new IODefinition() { IOType = IOType.OUTPUT };


        [Category("取像相机设置")]
        [DisplayName("输出信号")]
        [Description("输出信号,取决于相机触发模式及转盘速度")]
        public ActionMode ActionMode { get; set; } = ActionMode.OutputPulse10ms;



        //[Category("获取结果")]
        //[Description("调用方法")]
        //[DisplayName("调用方法")]
        //[TypeConverter(typeof(ProcessMethodSelectorConverter))]
        //public string MethodCode { get; set; }


        public int CompareTo(object obj)
        {
            if (obj is SnapshotSetting setting)
            {
                // return Math.Abs(CameraPosition).CompareTo(Math.Abs(setting.CameraPosition));
                return CameraPosition.CompareTo(setting.CameraPosition);
            }
            return 0;
        }

        //public string GetDisplayText()
        //{
        //    //string cameraName = "";
        //    //using (var scope = GlobalVar.Container.BeginLifetimeScope())
        //    //{
        //    //    List<IDevice> devices = scope.Resolve<List<IDevice>>();
        //    //    cameraName = devices.FirstOrDefault(u => u.Id == CameraId)?.Name ?? "";
        //    //}

        //    //// return $"{cameraName} :{IOItem.GetDisplayText()};{cameraName} {DetectType.GetEnumDescription()}";
        //    //return $"{cameraName} 距离{CameraPosition} 输出{CameraIO.GetDisplayText()}";
        //}
    }
    /// <summary>
    /// 轴配置
    /// </summary>
    public class AxisSetting
    {
        [Category("轴配置")]
        [DisplayName("轴号索引")]
        [Description("AxisIndex:轴号索引")]
        public int AxisIndex { get; set; }

        [Category("轴配置")]
        [DisplayName("轴名称")]
        [Description("AxisName:轴名称")]
        public string AxisName { get; set; }

        [Category("轴配置")]
        [DisplayName("轴是否启用")]
        [Description("IsAxisEnabled:轴是否启用")]
        public bool IsAxisEnabled { get; set; } = false;

        [Category("换算配置")]
        [DisplayName("脉冲数换算比例")]
        [Description("脉冲数和其他计量单位的换算比例,例如设置为1000,表示1000个脉冲等于1uint")]
        public int AxisRatio { get; set; } = 1;

        [Category("监听设置")]
        [Description("true:监听位置信息 false:不监听位置信息")]
        [DisplayName("位置监听")]
        public bool IsMonitorPosition { get; set; } = true;

        [Category("监听设置")]
        [Description("true:监听状态信息 false:不监听状态信息")]
        [DisplayName("状态监听")]
        public bool IsMonitorStatus { get; set; } = true;

        [Category("捕获设置")]
        [Description("true:启用捕获监听 false:不启用捕获监听")]
        [DisplayName("捕获监听")]
        public bool IsMonitorCapture { get; set; } = true;

        [Category("速度配置")]
        [DisplayName("默认速度参数")]
        [Description("VelocityPara:默认速度参数")]
        public VelocityPara VelocityPara { get; set; } = new VelocityPara();

        //[Category("回原点设置")]
        //[DisplayName("回原点模式")]
        //[Description("HomeMode:回原点模式。0:一般模式 1:极限限位模式 2:外部触发模式")]
        //public int HomeMode { get; set; } = 0;

        //[Category("回原点设置")]
        //[DisplayName("回原点方向")]
        //[Description("IsHomePositive:回原点方向。 true:正方向开始  false:负方向开始")]
        //public bool IsHomePositive { get; set; } = true;

        //[Category("回原点设置")]
        //[DisplayName("是否自动回原点")]
        //[Description("IsAutoGoHome:是否自动回原点。 true:是  false:否")]
        //public bool IsAutoGoHome { get; set; } = false;

        //[Category("超时设置")]
        //[DisplayName("回原点超时")]
        //[Description("TimeOutHome:回原点超时,单位毫秒")]
        //public int TimeOutHome { get; set; } = 30000;

        //[Category("超时设置")]
        //[DisplayName("运动超时")]
        //[Description("TimeOutMove:运动超时,单位毫秒")]
        //public int TimeOutMove { get; set; } = 10000;

        //[Category("开闭环设置")]
        //[DisplayName("是否使用Cmmd回馈")]
        //[Description("IsUseCmmdPosition:是否使用Cmmd回馈")]
        //public bool IsUseCmmdPosition { get; set; } = false;

        //[Category("开闭环设置")]
        //[DisplayName("是否使用板卡反馈停止信号")]
        //[Description("IsUseMDNStopSignal:是否使用板卡反馈停止信号")]
        //public bool IsUseMDNStopSignal { get; set; } = false;

        //[Category("开闭环设置")]
        //[DisplayName("是否启用报警")]
        //[Description("IsUseWarning:是否启用报警")]
        //public bool IsUseWarning { get; set; } = false;


        [Category("伺服报警")]
        [DisplayName("是否启用报警")]
        [Description("是否启用报警")]
        public bool IsUseAlarm { get; set; } = true;


        [Category("伺服报警")]
        [DisplayName("报警复位电平")]
        [Description("报警复位电平")]
        public LogicLevelEnum AlarmLogic { get; set; } = LogicLevelEnum.LowLevel;



        [Category("原点配置")]
        [DisplayName("回原点参数")]
        [Description("回原点参数")]

        public GoHomePara GoHomePara { get; set; } = new GoHomePara();


        [Category("暂停配置")]
        [DisplayName("是否启用立即暂停")]
        [Description("IsImmediatePause:是否启用立即暂停")]
        public bool IsImmediatePause { get; set; } = false;

        public string GetDisplayText()
        {
            return AxisIndex + "-" + AxisName + "-" + (IsAxisEnabled ? "启用" : "禁用");
        }
    }

    /// <summary>
    /// 速度参数对象
    /// </summary>
    public class VelocityPara 
    {
        [Category("速度配置")]
        [DisplayName("速度")]
        [Description("Velocity:速度,为0时表示不修改当前设置")]
        public double Velocity { get; set; } = 0;

        [Category("速度配置")]
        [DisplayName("加速度")]
        [Description("Acc:加速度,为0时表示不修改当前设置")]
        public double Acc { get; set; } = 0;

        [Category("速度配置")]
        [DisplayName("减速度")]
        [Description("减速度,为0时表示不修改当前设置")]
        public double Dec { get; set; } = 0;



        public string GetDisplayText()
        {
            return $"速度:{Velocity} 加速度:{Acc} 减速度:{Dec}";
        }
    }

    /// <summary>
    /// 回原点参数对象
    /// </summary>
    public class GoHomePara
    {
        [Category("回原点参数")]
        [DisplayName("回原点方式")]
        [Description("HomeMode:回原点方式")]
        public GoHomeMode HomeMode { get; set; } = GoHomeMode.Negative_Ne_Center_H_Positive_N_Index_HPoO_Offset_Po;


        [Category("回原点参数")]
        [DisplayName("正负限位触发电平")]
        [Description("LimitLogic:正负限位触发电平")]
        public LogicLevelEnum LimitLogic { get; set; } = LogicLevelEnum.LowLevel;

        [Category("回原点参数")]
        [DisplayName("原点限位触发电平")]
        [Description("HomeLogic:原点限位触发电平")]

        public LogicLevelEnum HomeLogic { get; set; } = LogicLevelEnum.LowLevel;

        [Category("回原点参数")]
        [DisplayName("Index触发电平")]
        [Description("IndexLogic:Index触发电平")]

        public LogicLevelEnum IndexLogic { get; set; } = LogicLevelEnum.LowLevel;


        [Category("回原点参数")]
        [DisplayName("捕捉位置模式")]
        [Description("TriggerSource:捕捉位置模式")]
       
        public PositionSourceEnum TriggerSource { get; set; } = PositionSourceEnum.CommandPosition;



        [Category("回原点加速时间")]
        [DisplayName("高速段加速时间")]
        [Description("高速段加速时间,单位:ms")]
        public ushort H_dMaxA_Time { get; set; } = 10;


        [Category("回原点加速时间")]
        [DisplayName("低速段加速时间")]
        [Description("低速段加速时间,单位:ms")]
        public ushort L_dMaxA_Time { get; set; } = 10;



        [Category("回原点参数")]
        [DisplayName("偏移位置")]
        [Description("偏移位置,按回零模式中的方向偏移")]
        public int OffsetPosition { get; set; } = 0;



        [Category("回原点参数")]
        [DisplayName("碰撞原点缓停时间")]
        [Description("SearchHomeStopTime:触发缓停时间,范围 0-1000ms,(默认:急停)。注意:设置碰撞原点缓停时间,需要配合回零设置的高速段速度,和低速度速度的搭配。设置大了会出现过冲的现象,设置小了停止的时候会有抖动,需要调节时间,尽量设置找到原点时候在开关中间。")]
        public ushort SearchHomeStopTime { get; set; } = 0;





        [Category("回原点速度")]
        [DisplayName("高速段速度")]
        [Description("高速段速度")]
        public double H_dMaxV { get; set; } = 10000;

        [Category("回原点速度")]
        [DisplayName("低速段速度")]
        [Description("低速段速度")]
        public double L_dMaxV { get; set; } = 3000;





        [Category("回原点超时")]
        [DisplayName("回原点超时")]
        [Description("回原点超时,单位秒")]
        public int GoHomeTimeOut { get; set; } = 60;
    }



    /// <summary>
    /// 回原点的状态
    /// </summary>
    public class GoHomeStatus
    {
        [Category("回原点状态")]
        [DisplayName("回原点状态")]
        [Description("回原点状态,0:回零成功,31:回零错误,32:正在回零")]
        public ushort Status { get; set; }



    }

    /// <summary>
    /// 轴状态对象
    /// </summary>
    public class AxisMovingStatus 
    {
        /// <summary>
        /// 卡号、 核号
        /// </summary>
        public int StationNumber { get; set; } = 0;

        /// <summary>
        /// 轴索引
        /// </summary>
        public int AxisIndex { get; set; }

        /// <summary>
        /// 轴名称
        /// </summary>
        public string AxisName { get; set; }

        /// <summary>
        /// 当前位置
        /// </summary>
        public int CurPosition { get; set; }

        /// <summary>
        /// 目的地
        /// </summary>
        public int PrfPosition { get; set; }

        /// <summary>
        /// 当前速度参数
        /// </summary>
        public double CurVelocity { get; set; }

        /// <summary>
        /// 规划速度参数
        /// </summary>
        public double PrfVelocity { get; set; }

        /// <summary>
        /// 轴状态
        /// </summary>
        public int AxisStatus { get; set; }

        public bool Alarm { get; set; } = false;
        public bool Enable { get; set; } = false;
        public bool PositiveLimit { get; set; } = false;
        public bool NegativeLimit { get; set; } = false;


        public bool IsMonitorPosition { get; set; }

        public bool IsMonitorStatus { get; set; }

        //public string GetDisplayText()
        //{
        //    //return $"轴{AxisIndex}:{AxisName}-当前状态:{AxisStatus}-当前位置:{CurPosition}";
        //}
    }
 



    public class AxisInfo 
    {
        public string AxisName { get; set; }
        public double AxisLocation { get; set; }

        public string GetDisplayText()
        {
            return $"{AxisName}:{AxisLocation}";
        }
    }


    public class IODefinition : IOItem
    {
        [Category("IO配置")]
        [Description("IO预定义")]
        public IOPrestatement IOPreStatement { get; set; } = IOPrestatement.Customized;

        [Category("IO配置")]
        [Description("IO用途描述")]
        public string IODesc { get; set; }

        [Category("IO配置")]
        [Description("备注说明")]
        public string Remark { get; set; }


        //[Category("IO配置")]
        //[Description("IO初始值,Flase为0(低电平),Ture为1(高电平)")]
        //public bool InitialValue { get; set; } = false;




        [Browsable(false)]
        [JsonIgnore]
        public override IOValue IOValue { get; set; }

        //public override string GetDisplayText()
        //{
        //    return $"{(IOPreStatement == IOPrestatement.Customized ? IODesc : IOPreStatement.GetEnumDescription())} {IOType.GetEnumDescription()} {IOIndex}";
        //}
    }


    public class IOItem :  IEqualityComparer
    {
        /// <summary>
        /// IO点编号
        /// </summary>
        [Category("IO配置")]
        [Description("IO点索引")]
        public virtual int IOIndex { get; set; }

        /// <summary>
        /// IO点的值
        /// </summary>
        [Category("IO配置")]
        [Description("IO状态")]
        public virtual IOValue IOValue { get; set; }

        /// <summary>
        /// IO点是in还是out
        /// </summary>   
        [Category("IO配置")]
        [Description("IO类型")]
        public virtual IOType IOType { get; set; }

        public new bool Equals(object x, object y)
        {
            if (x is IOItem a && y is IOItem b)
            {
                return a.IOType == b.IOType && a.IOIndex == b.IOIndex;
            }

            return false;
        }

        //public virtual string GetDisplayText()
        //{
        //    return $"{IOType.GetEnumDescription()}-{IOIndex}-{IOValue.GetEnumDescription()}";
        //}

        public int GetHashCode(object obj)
        {
            return obj.GetHashCode();
        }
    }


    public class SortingInputSetting 
    {

        [Category("入料检测配置")]
        [DisplayName("启用入料检测")]
        [Description("启用入料检测")]
        public bool Enable { get; set; } = false;


        [Category("入料检测配置")]
        [DisplayName("位号")]
        [Description("位号")]
     
        public BitInputNumberEnum BitInputNumber { get; set; } = BitInputNumberEnum.BitInput0;


        [Category("入料检测配置")]
        [DisplayName("物件检测有效电平")]
        [Description("物件检测有效电平")]
        public LogicLevelEnum InputLogic { get; set; } = LogicLevelEnum.LowLevel;


        [Category("入料检测配置")]
        [DisplayName("物件检测有效电平")]
        [Description("物件检测有效电平")]
        public ushort AxisIndex { get; set; } = 0;




        [Category("入料检测配置")]
        [DisplayName("跟随方式")]
        [Description("跟随方式")]
        public PositionSourceEnum PositionSource { get; set; } = PositionSourceEnum.EncoderPosition;



        [Category("入料检测配置")]
        [DisplayName("入料检测捕获位置")]
        [Description("入料检测捕获位置")]
        public SortingInputPositionModeEnum SortingInputPositionMode { get; set; } = SortingInputPositionModeEnum.Front;



        [Category("相机绑定配置")]
        [DisplayName("启用相机绑定")]
        [Description("启用相机绑定")]
        public bool EnableBindCamera { get; set; } = false;


        [Category("相机绑定配置")]
        [DisplayName("起始相机号")]
        [Description("起始相机号")]
        public ushort CameraStartNumber { get; set; } = 0;




        [Category("吹气绑定配置")]
        [DisplayName("启用吹气绑定")]
        [Description("启用吹气绑定")]
        public bool EnableBindBlow { get; set; } = false;


        [Category("吹气绑定配置")]
        [DisplayName("起始气阀号")]
        [Description("起始气阀号")]
        public ushort BlowStartNumber { get; set; } = 0;



        //public string GetDisplayText()
        //{
        //    return $"{BitInputNumber.GetEnumDescription()} 启用相机绑定{EnableBindCamera.ToString()} 启用吹气绑定{EnableBindBlow.ToString()}";
        //}
    }

    #region 源程序运行调用类,未复制完,太复杂注释掉

    public class ResponseMessage
    {
        public ResponseMessage() { }

        public int Code { get; set; }

        public int Result { get; set; } = 1;

        public string Message { get; set; }

        public string DataJson { get; set; }

        [JsonIgnore]
        public object DataObj { get; set; } = null;

        /// <summary>
        /// 执行结果数据集合
        /// </summary>
        public List<int> DataList { get; set; } = new List<int>();

        public void GetMessageFromException(Exception ex, int code = 9999)
        {
            Code = code;
            //Message = ex.GetExceptionMessage();

            Result = -1;
        }

        public ResponseMessage(int result)
        {
            Result = result;
        }

        public ResponseMessage(bool resultFlag, List<int> datas = null)
        {
            Result = resultFlag ? 1 : -1;

            if (datas != null)
            {
                DataList = new List<int>(datas);
            }
        }

        public ResponseMessage(int resultFlag, List<int> datas = null)
        {
            Result = resultFlag;

            if (datas != null)
            {
                DataList = new List<int>(datas);
            }
        }

        public ResponseMessage(bool result, string msg)
        {
            Result = result ? 1 : -1;
            Message = msg;
        }

        public string GetDisplayText()
        {
            return $"{Result} | {(DataList.Count > 0 ? string.Join(" ", DataList) : "NA")}";
        }
    }

    public interface IOperationConfig //: IOperationResult
    {
        /// <summary>
        /// 发生异常时的重新尝试次数
        /// </summary>
        int ReTryTimes { get; set; }

        /// <summary>
        /// 输入参数
        /// </summary>
        List<int> InputPara { get; set; }

        int TriggerValue { get; set; }

        /// <summary>
        /// 当异常发生时的异常反馈值
        /// </summary>
        int ExceptionValue { get; set; }

        /// <summary>
        /// 指示该操作的监视配置来源
        /// </summary>
        string MonitorSetId { get; set; }

        /// <summary>
        /// 调用该操作配置的设备Id
        /// </summary>
        string ExecuteDeviceId { get; set; }

        /// <summary>
        /// 操作执行后部分输出结果,目前拟采用序列化后的字符串方式保存
        /// </summary>
        string OutputData { get; set; }
    }


    public class SolidMotionCardOperationConfigBase : OperationConfigBase
    {
        [Category("板卡操作")]
        [Description("板卡操作配置基类集合,依次执行")]

        public List<SolidMotionCardOperationSet> OperationCollection { get; set; } = new List<SolidMotionCardOperationSet>();

       
    }

    public class OperationConfigBase : IOperationConfig//, ISourceDevice
    {
        /// <summary>
        /// 输入参数
        /// </summary>
        [JsonIgnore]
        [Category("输入配置")]
        [Description("输入参数配置")]
        [DisplayName("输入参数")]
        //[TypeConverter(typeof(SimpleCollectionConvert<int>))]
        public virtual List<int> InputPara { get; set; } = new List<int>();

        /// <summary>
        /// 异常反馈值
        /// </summary>
        [Category("异常反馈设置")]
        [Description("异常反馈值")]
        [DisplayName("异常反馈值")]
        public virtual int ExceptionValue { get; set; } = 0;

        /// <summary>
        /// 发生异常时的重新尝试次数
        /// </summary>
        [Category("异常反馈设置")]
        [Description("发生异常时的重新尝试次数")]
        [DisplayName("重试次数")]
        public virtual int ReTryTimes { get; set; } = 3;

        [Browsable(false)]
        public string MonitorSetId { get; set; } = "";

        [Browsable(false)]
        [JsonIgnore]
        public virtual string ExecuteDeviceId { get; set; } = "";

        //[Browsable(false)]
        //[JsonIgnore]
        //public virtual string SourceDeviceId { get; set; } = "";

        [Browsable(false)]
        [JsonIgnore]
        public virtual string OutputData { get; set; } = "";

        [Browsable(false)]
        [JsonIgnore]
        public virtual int TriggerValue { get; set; }
    }

    public class SolidMotionCardOperationSet : IOOperationConfigBase
    {
        #region Ignore
        [JsonIgnore]
        [Browsable(false)]
        public override List<int> InputPara { get; set; } = new List<int>();

        /// <summary>
        /// 异常反馈值
        /// </summary>
        [JsonIgnore]
        [Browsable(false)]
        public override int ExceptionValue { get; set; } = 0;

        /// <summary>
        /// 发生异常时的重新尝试次数
        /// </summary>
        [JsonIgnore]
        [Browsable(false)]
        public override int ReTryTimes { get; set; } = 1;
        #endregion

        [Category("2.板卡运动配置")]
        [DisplayName("运动配置集合")]
        [Description("MovingOps:多轴并发,运动配置集合")]
        public List<MovingOption> MovingOps { get; set; } = new List<MovingOption>();

        [Category("5.操作延时")]
        [DisplayName("操作前延时")]
        [Description("操作前延时,单位ms")]
        public override int DelayBefore { get; set; } = 0;

        [Category("5.操作延时")]
        [DisplayName("操作后延时")]
        [Description("操作后延时,单位ms")]
        public override int DelayAfter { get; set; } = 0;


    }

    public class IOOperationConfigBase : OperationConfigBase
    {
        [Category("\t\t\tIO操作配置")]
        [DisplayName("1.IO预检查")]
        [Description("IO预检查定义集合")]

        public List<IOOperationItem> PreCheckIOCollection { get; set; } = new List<IOOperationItem>();

        [Category("\t\t\tIO操作配置")]
        [Description("超时设置,单位:ms")]
        [DisplayName("2.IO预检查超时")]
        public int PreCheckIOTimeout { get; set; } = 0;

        [Category("\t\t\tIO操作配置")]
        [DisplayName("3.IO输出")]
        [Description("IO输出定义集合")]
        public List<IOOperationItem> IOOutputCollection { get; set; } = new List<IOOperationItem>();

        [Category("\t\t\tIO操作配置")]
        [DisplayName("4.IO输出确认")]
        [Description("IO确认定义集合")]
        public List<IOOperationItem> IOConfirmCollection { get; set; } = new List<IOOperationItem>();

        [Category("\t\t\tIO操作配置")]
        [Description("超时设置,单位:ms")]
        [DisplayName("5.IO输出确认超时")]
        public int IOConfirmTimeout { get; set; } = 0;

        [Category("\t\t\tIO操作配置")]
        [Description("IO操作前延时,单位ms")]
        public virtual int DelayBefore { get; set; } = 0;

        [Category("\t\t\tIO操作配置")]
        [Description("IO操作后延时,单位ms")]
        public virtual int DelayAfter { get; set; } = 0;

 
    }

    /// <summary>
    /// IO操作对象
    /// </summary>
    public class IOOperationItem
    {
        [Category("IO操作配置")]
        [Description("需要操作的IO")]
        public IODefinition IOItem { get; set; } = new IODefinition();

        [Category("IO操作配置")]
        [Description("需要操作的IO的状态")]
        public IOValue CheckValue
        {
            get => IOItem.IOValue;
            set => IOItem.IOValue = value;
        }

        //[Browsable(false)]
        //[JsonIgnore]
        public List<IODefinition> IOItemSource = new List<IODefinition>();

        //public string GetDisplayText()
        //{
        //    return IOItem.IODesc + "-" + CheckValue.GetEnumDescription();
        //}
    }

    /// <summary>
    /// 运动对象
    /// </summary>
    public class MovingOption
    {
        [Category("运动配置")]
        [DisplayName("运动轴索引")]
        [Description("AxisIndex:运动轴索引")]
        // [TypeConverter(typeof(AxisIndexConvert))]
        public int AxisIndex { get; set; }

        [Category("运动配置")]
        [DisplayName("运动模式")]
        [Description("MoveMode:运动模式")]
        public MotionMode MoveMode { get; set; } = MotionMode.P2P;


        [Category("运动配置")]
        [DisplayName("运动方向")]
        [Description("MoveDir:运动方向")]
        public PulseMode MoveDir { get; set; } = PulseMode.Pulse_Dir_H;


        [Category("运动配置")]
        [DisplayName("点位运动误差带")]
        [Description("点位运动误差带,单位plus")]
        public int ErrorBand { get; set; } = 20;

        [Category("运动配置")]
        [DisplayName("是否绝对运动")]
        [Description("IsAbsolute:是否绝对运动")]
        public bool IsAbsolute { get; set; } = true;

        [Category("运动配置")]
        [DisplayName("目的地")]
        [Description("Destination:目的地")]
        public int Destination { get; set; }

        [Category("运动配置")]
        [DisplayName("备注")]
        [Description("Remark:备注")]
        public string Remark { get; set; }

        [Category("运动配置")]
        [DisplayName("速度参数")]
        [Description("VelocityPara:速度参数")]
        public VelocityPara VelocityPara { get; set; } = new VelocityPara();




        [Category("运动配置")]
        [Description("超时设置,单位:ms")]
        [DisplayName("运动超时")]
        public int MovingTimeout { get; set; } = 0;

        internal List<AxisSetting> _axisSettingList = new List<AxisSetting>();

        public void SetAxisSetting(List<AxisSetting> settings)
        {
            if (settings != null)
                _axisSettingList = settings;
        }

        public string GetDisplayText()
        {
            //string axisName = AxisIndexStr;
            string axisName = AxisIndex.ToString();
            var axisSet = _axisSettingList.FirstOrDefault(a => a.AxisIndex == AxisIndex);
            if (axisSet != null)
            {
                axisName += ("-" + axisSet.AxisName);
            }
            return axisName + "," + MoveMode.ToString() + "," + (IsAbsolute ? "Abs" : "Rel") + "," + Destination;
        }
        //public event PropertyChangedEventHandler PropertyChanged;
    }

    public class SolidMotionOperationCollection : OperationConfigBase
    {
        [Category("运动配置")]
        [DisplayName("运动配置集合")]
        [Description("MovingOps:多轴并发,运动配置集合")]
        public List<MovingOption> MovingOps { get; set; } = new List<MovingOption>();

        [Category("运动配置")]
        [Description("多轴并发运动超时设置,单位:s")]
        [DisplayName("多轴并发运动超时")]
        public int MovingOpsTimeout { get; set; } = 60;

     
    }
    #endregion

}