using OpenCvSharp;
using System.ComponentModel;
using System.Drawing;
using static OpenCvSharp.AgastFeatureDetector;
using System.Text.RegularExpressions;
using System.Text;
using System.Drawing.Design;
using AntdUI;
using static DH.Commons.Enums.EnumHelper;
using System.Text.Json.Serialization;
using DH.Commons.Enums;

namespace DH.Commons.Base
{

    public class ModelLabel
    {
        public string LabelId { get; set; }


        [Category("模型标签")]
        [DisplayName("模型标签索引")]
        [Description("模型识别的标签索引")]
        public int LabelIndex { get; set; }


        [Category("模型标签")]
        [DisplayName("模型标签")]
        [Description("模型识别的标签名称")]
        public string LabelName { get; set; }




        //[Category("模型配置")]
        //[DisplayName("模型参数配置")]
        //[Description("模型参数配置集合")]

        //public ModelParamSetting ModelParamSetting { get; set; } = new ModelParamSetting();


        public string GetDisplayText()
        {
            return $"{LabelId}-{LabelName}";
        }
    }
    public class MLRequest
    {
        public int ImageChannels = 3;
        public Mat mImage;
        public int ResizeWidth;
        public int ResizeHeight;

        public float confThreshold;

        public float iouThreshold;

        //public int ImageResizeCount;
        public bool IsCLDetection;
        public int ProCount;
        public string in_node_name;

        public string out_node_name;

        public string in_lable_path;

        public int ResizeImageSize;
        public int segmentWidth;
        public int ImageWidth;

        // public List<labelStringBase> OkClassTxtList;


        public List<ModelLabel> LabelNames;




    }
    public enum ResultState
    {

        [Description("检测NG")]
        DetectNG = -3,

        //[Description("检测不足TBD")]
        // ShortageTBD = -2,
        [Description("检测结果TBD")]
        ResultTBD = -1,
        [Description("OK")]
        OK = 1,
        // [Description("NG")]
        // NG = 2,
        //统计结果
        [Description("A类NG")]
        A_NG = 25,
        [Description("B类NG")]
        B_NG = 26,
        [Description("C类NG")]
        C_NG = 27,
    }
    /// <summary>
    /// 深度学习 识别结果明细 面向业务:detect 面向深度学习:Recongnition、Inference
    /// </summary>
    public class DetectionResultDetail
    {
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
        public string LabelBGR { get; set; }//识别到对象的标签BGR



        public int LabelNo { get; set; }   // 识别到对象的标签索引

#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
        public string LabelName { get; set; }//识别到对象的标签名称


        public double Score { get; set; }//识别目标结果的可能性、得分

#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
        public string LabelDisplay { get; set; }//识别到对象的 显示信息


        public double Area { get; set; }//识别目标的区域面积

        public Rectangle Rect { get; set; }//识别目标的外接矩形

        public RotatedRect MinRect { get; set; }//识别目标的最小外接矩形(带角度)

        public ResultState InferenceResult { get; set; }//只是模型推理 label的结果

        public double DistanceToImageCenter { get; set; }  //计算矩形框到图像中心的距离



        public ResultState FinalResult { get; set; }//模型推理+其他视觉、逻辑判断后 label结果
    }
    public class MLResult
    {
        public bool IsSuccess = false;
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
        public string ResultMessage;

#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
        public Bitmap ResultMap;

        public List<DetectionResultDetail> ResultDetails = new List<DetectionResultDetail>();
    }
    public class MLInit
    {
        public string ModelFile;
        public string InferenceDevice;


        public int InferenceWidth;
        public int InferenceHeight;

        public string InputNodeName;


        public int SizeModel;

        public bool bReverse;//尺寸测量正反面
                             //目标检测Gpu
        public bool IsGPU;
        public int GPUId;
        public float Score_thre;
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
        public MLInit(string modelFile, bool isGPU, int gpuId, float score_thre)


        {
            ModelFile = modelFile;
            IsGPU = isGPU;
            GPUId = gpuId;
            Score_thre = score_thre;
        }

        public MLInit(string modelFile, string inputNodeName, string inferenceDevice, int inferenceWidth, int inferenceHeight)
        {
            ModelFile = modelFile;
            InferenceDevice = inferenceDevice;

            InferenceWidth = inferenceWidth;
            InferenceHeight = inferenceHeight;
            InputNodeName = inputNodeName;


        }
    }
    public class DetectStationResult
    {
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
        public string Pid { get; set; }


#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
        public string TempPid { get; set; }


        /// <summary>
        /// 检测工位名称
        /// </summary>
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
        public string DetectName { get; set; }



        /// <summary>
        /// 深度学习 检测结果
        /// </summary>
        public List<DetectionResultDetail> DetectDetails = new List<DetectionResultDetail>();
        public List<IShapeElement> DetectionResultShapes = new List<IShapeElement>();


        /// <summary>
        /// 工位检测结果
        /// </summary>
        public ResultState ResultState { get; set; } = ResultState.ResultTBD;


        public double FinalResultfScore { get; set; } = 0.0;


        public string ResultLabel { get; set; } = "";// 多个ng时,根据label优先级,设定当前检测项的label

        public string ResultLabelCategoryId { get; set; } = "";// 多个ng时,根据label优先级,设定当前检测项的label

        public int PreTreatState { get; set; }
        public bool IsPreTreatDone { get; set; } = true;

        public bool IsAfterTreatDone { get; set; } = true;

        public bool IsMLDetectDone { get; set; } = true;

        /// <summary>
        /// 预处理阶段已经NG
        /// </summary>
        public bool IsPreTreatNG { get; set; } = false;

        /// <summary>
        /// 目标检测NG
        /// </summary>
        public bool IsObjectDetectNG { get; set; } = false;

        public DateTime EndTime { get; set; }

        public int StationDetectElapsed { get; set; }
        public static string NormalizeAndClean(string input)
        {
#pragma warning disable CS8603 // 可能返回 null 引用。
            if (input == null) return null;
#pragma warning restore CS8603 // 可能返回 null 引用。

            // Step 1: 标准化字符编码为 Form C (规范组合)
            string normalizedString = input.Normalize(NormalizationForm.FormC);

            // Step 2: 移除所有空白字符,包括制表符和换行符
            string withoutWhitespace = Regex.Replace(normalizedString, @"\s+", "");

            // Step 3: 移除控制字符 (Unicode 控制字符,范围 \u0000 - \u001F 和 \u007F)
            string withoutControlChars = Regex.Replace(withoutWhitespace, @"[\u0000-\u001F\u007F]+", "");

            // Step 4: 移除特殊的不可见字符(如零宽度空格等)
            string cleanedString = Regex.Replace(withoutControlChars, @"[\u200B\u200C\u200D\uFEFF]+", "");

            return cleanedString;
        }

    }
    public class RelatedCamera : NotifyProperty
    {

        private string _cameraSourceId = "";
        [Category("关联相机")]
        [DisplayName("相机源ID")]
        [Description("关联相机的唯一标识符")]
        //[TypeConverter(typeof(CollectionCountConvert))]
        public string CameraSourceId
        {
            get { return _cameraSourceId; }
            set
            {
                if (_cameraSourceId == value) return;
                _cameraSourceId = value;
                OnPropertyChanged(nameof(CameraSourceId));
            }
        }

        public RelatedCamera()
        {
        }

        // 可选:添加带 Selected 的构造函数
        public RelatedCamera(string cameraSourceId)
        {
            CameraSourceId = cameraSourceId;

        }
    }
    public class CustomizedPoint : INotifyPropertyChanged, IComparable<CustomizedPoint>
    {
        private double x = 0;
        [Category("坐标设置")]
        [Description("X坐标")]
        public double X
        {
            get => x;
            set
            {
                if (value != x)
                {
                    x = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("X"));
                }
            }
        }

        private double y = 0;
        [Category("坐标设置")]
        [Description("Y坐标")]
        public double Y
        {
            get => y;
            set
            {
                if (value != y)
                {
                    y = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Y"));
                }
            }
        }

        public CustomizedPoint() { }

        public CustomizedPoint(double x, double y)
        {
            X = x;
            Y = y;
        }

        //public CustomizedPoint(Point p)
        //{
        //    X = p.X;
        //    Y = p.Y;
        //}

        public CustomizedPoint(PointF p)
        {
            X = p.X;
            Y = p.Y;
        }

        public CustomizedPoint(CustomizedPoint p)
        {
            X = p.X;
            Y = p.Y;
        }

        /// <summary>
        /// 根据PLC的读取数值获取点位坐标
        /// </summary>
        /// <param name="plcValues">0:X低位 1:X高位 2:Y低位 3:Y高位</param>
        //public CustomizedPoint(List<int> plcValues)
        //{
        //    if (plcValues == null || plcValues.Count != 4)
        //        return;

        //    var list = plcValues.ParseUnsignShortListToInt();

        //    X = list[0];
        //    Y = list[1];
        //}

        public event PropertyChangedEventHandler PropertyChanged;

        public static List<CustomizedPoint> GetPoints(List<double> Xs, List<double> Ys)
        {
            List<CustomizedPoint> points = new List<CustomizedPoint>();
            for (int i = 0; i < Xs.Count && i < Ys.Count; i++)
            {
                points.Add(new CustomizedPoint(Xs[i], Ys[i]));
            }

            return points;
        }

        public static double GetDistance(CustomizedPoint p1, CustomizedPoint p2)
        {
            return Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2));
        }

        public override string ToString()
        {
            return GetDisplayText();
        }

        public virtual string GetDisplayText()
        {
            return string.Format("X:{0};Y:{1}", X, Y);
        }

        public virtual string GetCSVHead()
        {
            return "X,Y";
        }

        public virtual string GetCSVData()
        {
            return X.ToString("f3") + ";" + Y.ToString("f3");
        }

        //public static double GetCustomizedPointDistance(CustomizedPoint startPoint, CustomizedPoint endPoint)
        //{
        //    return Math.Sqrt(Math.Pow(endPoint.X - startPoint.X, 2) + Math.Pow(endPoint.Y - startPoint.Y, 2));
        //}

        public CustomizedPoint OffsetClone(CustomizedPoint point)
        {
            return new CustomizedPoint(X + point.X, Y + point.Y);
        }

        public void Offset(CustomizedPoint point)
        {
            X += point.X;
            Y += point.Y;
        }

        public int CompareTo(CustomizedPoint other)
        {
            return X == other.X && Y == other.Y ? 0 : 1;
        }

        public override int GetHashCode()
        {
            //return (int)(X * 10 + Y);
            return new Tuple<double, double>(X, Y).GetHashCode();
        }

        public static CustomizedPoint operator -(CustomizedPoint p1, CustomizedPoint p2)
        {
            return new CustomizedPoint(p1.X - p2.X, p1.Y - p2.Y);
        }

        public static CustomizedPoint operator +(CustomizedPoint p1, CustomizedPoint p2)
        {
            return new CustomizedPoint(p1.X + p2.X, p1.Y + p2.Y);
        }
    }
    //    public class PreTreatParam
    //    {

    //        /// <summary>
    //        /// 参数名称
    //        /// </summary>
    //        ///     
    //        [Category("预处理参数")]
    //        [DisplayName("参数名称")]
    //        [Description("参数名称")]
    //#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
    //        public string Name { get; set; }



    //        /// <summary>
    //        /// 参数值
    //        /// </summary>
    //        ///     
    //        [Category("预处理参数")]
    //        [DisplayName("参数值")]
    //        [Description("参数值")]
    //#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
    //        public string Value { get; set; }



    //    }
    public class DetectionConfig : NotifyProperty
    {
        #region 属性字段
        private string _id = Guid.NewGuid().ToString();
        private string _name;
        private string _cameraSourceId = "";
        private List<RelatedCamera> _cameraCollects = new List<RelatedCamera>();
        private bool _isEnableGPU;
        private bool _isMixModel;
        private bool _isPreEnabled;
        private bool _isEnabled;
        private bool _isAddStation = true;
        private string _halconAlgorithemPath_Pre;
        private AntList<PreTreatParam> _preTreatParams = new AntList<PreTreatParam>();
        private AntList<PreTreatParam> _outPreTreatParams = new AntList<PreTreatParam>();
        private ModelType _modelType = ModelType.目标检测;
        private string _modelPath;
        private int _modelWidth = 640;
        private int _modelHeight = 640;
        private string _modeloutNodeName = "output0";
        private float _modelconfThreshold = 0.5f;
        private string _in_lable_path;
        private AntList<DetectionLable> _detectionLableList = new AntList<DetectionLable>();
        private AntList<SizeTreatParam> _sizeTreatParamList = new AntList<SizeTreatParam>();

        private CustomizedPoint _showLocation = new CustomizedPoint();

        private bool _saveOKOriginal = false;
        private bool _saveNGOriginal = false;
        private bool _saveOKDetect = false;
        private bool _saveNGDetect = false;

        #endregion

        #region 属性声明
        [ReadOnly(true)]
        public string Id
        {
            get => _id;
            set
            {
                if (_id == value) return;
                _id = value;
                OnPropertyChanged(nameof(Id));
            }
        }

        [Category("检测配置")]
        [DisplayName("检测配置名称")]
        [Description("检测配置名称")]
        public string Name
        {
            get => _name;
            set
            {
                if (_name == value) return;
                _name = value;
                OnPropertyChanged(nameof(Name));
            }
        }

        [Category("关联相机集合")]
        [DisplayName("关联相机集合")]
        [Description("关联相机描述")]
        public List<RelatedCamera> CameraCollects
        {
            get => _cameraCollects;
            set
            {
                if (_cameraCollects == value) return;
                _cameraCollects = value;
                OnPropertyChanged(nameof(CameraCollects));
            }
        }

        [Category("启用配置")]
        [DisplayName("是否启用GPU检测")]
        [Description("是否启用GPU检测")]
        public bool IsEnableGPU
        {
            get => _isEnableGPU;
            set
            {
                if (_isEnableGPU == value) return;
                _isEnableGPU = value;
                OnPropertyChanged(nameof(IsEnableGPU));
            }
        }

        [Category("启用配置")]
        [DisplayName("是否混料模型")]
        [Description("是否混料模型")]
        public bool IsMixModel
        {
            get => _isMixModel;
            set
            {
                if (_isMixModel == value) return;
                _isMixModel = value;
                OnPropertyChanged(nameof(IsMixModel));
            }
        }

        [Category("启用配置")]
        [DisplayName("是否启用预处理")]
        [Description("是否启用预处理")]
        public bool IsPreEnabled
        {
            get => _isPreEnabled;
            set
            {
                if (_isPreEnabled == value) return;
                _isPreEnabled = value;
                OnPropertyChanged(nameof(IsPreEnabled));
            }
        }

        [Category("启用配置")]
        [DisplayName("是否启用该检测")]
        [Description("是否启用该检测")]
        public bool IsEnabled
        {
            get => _isEnabled;
            set
            {
                if (_isEnabled == value) return;
                _isEnabled = value;
                OnPropertyChanged(nameof(IsEnabled));
            }
        }

        [Category("启用配置")]
        [DisplayName("是否加入检测工位")]
        [Description("是否加入检测工位")]
        public bool IsAddStation
        {
            get => _isAddStation;
            set
            {
                if (_isAddStation == value) return;
                _isAddStation = value;
                OnPropertyChanged(nameof(IsAddStation));
            }
        }

        [Category("1.预处理(视觉算子)")]
        [DisplayName("预处理-算法文件路径")]
        public string HalconAlgorithemPath_Pre
        {
            get => _halconAlgorithemPath_Pre;
            set
            {
                if (_halconAlgorithemPath_Pre == value) return;
                _halconAlgorithemPath_Pre = value;
                OnPropertyChanged(nameof(HalconAlgorithemPath_Pre));
            }
        }

        [Category("1.预处理(视觉算子)")]
        [DisplayName("预处理-参数列表")]
        [Description("预处理-参数列表")]
        public AntList<PreTreatParam> PreTreatParams
        {
            get => _preTreatParams;
            set
            {
                if (_preTreatParams == value) return;
                _preTreatParams = value;
                OnPropertyChanged(nameof(PreTreatParams));
            }
        }

        [Category("1.预处理(视觉算子)")]
        [DisplayName("预处理-输出参数列表")]
        [Description("预处理-输出参数列表")]
        public AntList<PreTreatParam> OUTPreTreatParams
        {
            get => _outPreTreatParams;
            set
            {
                if (_outPreTreatParams == value) return;
                _outPreTreatParams = value;
                OnPropertyChanged(nameof(OUTPreTreatParams));
            }
        }

        [Category("2.中检测(深度学习)")]
        [DisplayName("中检测-模型类型")]
        [Description("模型类型:ImageClassification-图片分类;ObjectDetection:目标检测;Segmentation-图像分割")]
        public ModelType ModelType
        {
            get => _modelType;
            set
            {
                if (_modelType == value) return;
                _modelType = value;
                OnPropertyChanged(nameof(ModelType));
            }
        }

        [Category("2.中检测(深度学习)")]
        [DisplayName("中检测-模型文件路径")]
        [Description("中处理 深度学习模型文件路径")]
        public string ModelPath
        {
            get => _modelPath;
            set
            {
                if (_modelPath == value) return;
                _modelPath = value;
                OnPropertyChanged(nameof(ModelPath));
            }
        }

        [Category("2.中检测(深度学习)")]
        [DisplayName("中检测-模型宽度")]
        [Description("中处理-模型宽度")]
        public int ModelWidth
        {
            get => _modelWidth;
            set
            {
                if (_modelWidth == value) return;
                _modelWidth = value;
                OnPropertyChanged(nameof(ModelWidth));
            }
        }

        [Category("2.中检测(深度学习)")]
        [DisplayName("中检测-模型高度")]
        [Description("中处理-模型高度")]
        public int ModelHeight
        {
            get => _modelHeight;
            set
            {
                if (_modelHeight == value) return;
                _modelHeight = value;
                OnPropertyChanged(nameof(ModelHeight));
            }
        }

        [Category("2.中检测(深度学习)")]
        [DisplayName("中检测-模型节点名称")]
        [Description("中处理-模型节点名称")]
        public string ModeloutNodeName
        {
            get => _modeloutNodeName;
            set
            {
                if (_modeloutNodeName == value) return;
                _modeloutNodeName = value;
                OnPropertyChanged(nameof(ModeloutNodeName));
            }
        }

        [Category("2.中检测(深度学习)")]
        [DisplayName("中检测-模型置信度")]
        [Description("中处理-模型置信度")]
        public float ModelconfThreshold
        {
            get => _modelconfThreshold;
            set
            {
                if (_modelconfThreshold == value) return;
                _modelconfThreshold = value;
                OnPropertyChanged(nameof(ModelconfThreshold));
            }
        }

        [Category("2.中检测(深度学习)")]
        [DisplayName("中检测-模型标签路径")]
        [Description("中处理-模型标签路径")]
        public string In_lable_path
        {
            get => _in_lable_path;
            set
            {
                if (_in_lable_path == value) return;
                _in_lable_path = value;
                OnPropertyChanged(nameof(In_lable_path));
            }
        }



        [Category("显示配置")]
        [DisplayName("显示位置")]
        [Description("检测信息显示位置")]
        public CustomizedPoint ShowLocation
        {
            get => _showLocation;
            set
            {
                if (_showLocation == value) return;
                _showLocation = value;
                OnPropertyChanged(nameof(ShowLocation));
            }
        }

        /// <summary>
        /// 标签集合(需确保DetectionLable也实现INotifyPropertyChanged)
        /// </summary>
        public AntList<DetectionLable> DetectionLableList
        {
            get => _detectionLableList;
            set
            {
                if (_detectionLableList == value) return;
                _detectionLableList = value;
                OnPropertyChanged(nameof(DetectionLableList));
            }
        }

        public AntList<SizeTreatParam> SizeTreatParamList
        {
            get => _sizeTreatParamList;
            set
            {
                if (_sizeTreatParamList == value) return;
                _sizeTreatParamList = value;
                OnPropertyChanged(nameof(SizeTreatParamList));
            }
        }


        public bool SaveOKOriginal
        {
            get => _saveOKOriginal;
            set
            {
                if (_saveOKOriginal == value) return;
                _saveOKOriginal = value;
                OnPropertyChanged(nameof(SaveOKOriginal));
            }
        }

        public bool SaveNGOriginal
        {
            get => _saveNGOriginal;
            set
            {
                if (_saveNGOriginal == value) return;
                _saveNGOriginal = value;
                OnPropertyChanged(nameof(SaveNGOriginal));
            }
        }
        public bool SaveOKDetect
        {
            get => _saveOKDetect;
            set
            {
                if (_saveOKDetect == value) return;
                _saveOKDetect = value;
                OnPropertyChanged(nameof(SaveOKDetect));
            }
        }
        public bool SaveNGDetect
        {
            get => _saveNGDetect;
            set
            {
                if (_saveNGDetect == value) return;
                _saveNGDetect = value;
                OnPropertyChanged(nameof(SaveNGDetect));
            }
        }
        #endregion

        #region 构造函数
        public DetectionConfig() { }

        public DetectionConfig(
            string name,
            ModelType modelType,
            string modelPath,
            bool isEnableGPU,
            string sCameraSourceId)
        {
            // 通过属性赋值触发通知
            ModelPath = modelPath ?? string.Empty;
            Name = name;
            ModelType = modelType;
            IsEnableGPU = isEnableGPU;

        }
        #endregion
    }

    //大改预处理类
    /// <summary>
    /// 预处理
    /// </summary>
    public class PreTreatParam : NotifyProperty
    {


        private bool _selected = false;
        public bool Selected
        {
            get { return _selected; }
            set
            {
                if (_selected == value) return;
                _selected = value;
                OnPropertyChanged(nameof(Selected));
            }
        }
        private string _name;
        public string Name
        {
            get { return _name; }
            set
            {
                if (_name == value) return;
                _name = value;
                OnPropertyChanged(nameof(Name));
            }
        }


        private string _value;
        public string Value
        {
            get { return _value; }
            set
            {
                if (_value == value) return;
                _value = value;
                OnPropertyChanged(nameof(Value));
            }
        }

        private CellLink[] cellLinks;
        [JsonIgnore]
        public CellLink[] CellLinks
        {
            get { return cellLinks; }
            set
            {
                if (cellLinks == value) return;
                cellLinks = value;
                OnPropertyChanged(nameof(CellLinks));
            }
        }


    }


    public class DetectionLable : NotifyProperty
    {
        private bool _selected = false;

        private string _labelId;
        private string _labelName;
        private double _maxScore;
        private double _minScore;
        private double _maxArea;
        private double _minArea;
        private ResultState _resultState = ResultState.ResultTBD;




        public bool Selected
        {
            get { return _selected; }
            set
            {
                if (_selected == value) return;
                _selected = value;
                OnPropertyChanged(nameof(Selected));
            }
        }



        public string LabelId
        {
            get { return _labelId; }
            set
            {
                if (_labelId == value) return;
                _labelId = value;
                OnPropertyChanged(nameof(LabelId));
            }
        }

        public string LabelName
        {
            get { return _labelName; }
            set
            {
                if (_labelName == value) return;
                _labelName = value;
                OnPropertyChanged(nameof(LabelName));
            }
        }

        public double MaxScore
        {
            get { return _maxScore; }
            set
            {
                if (_maxScore.Equals(value)) return;
                _maxScore = value;
                OnPropertyChanged(nameof(MaxScore));
            }
        }

        public double MinScore
        {
            get { return _minScore; }
            set
            {
                if (_minScore.Equals(value)) return;
                _minScore = value;
                OnPropertyChanged(nameof(MinScore));
            }
        }

        public double MaxArea
        {
            get { return _maxArea; }
            set
            {
                if (_maxArea.Equals(value)) return;
                _maxArea = value;
                OnPropertyChanged(nameof(MaxArea));
            }
        }

        public double MinArea
        {
            get { return _minArea; }
            set
            {
                if (_minArea.Equals(value)) return;
                _minArea = value;
                OnPropertyChanged(nameof(MinArea));
            }
        }

        public ResultState ResultState
        {
            get { return _resultState; }
            set
            {
                if (_resultState == value) return;
                _resultState = value;
                OnPropertyChanged(nameof(ResultState));
            }
        }

        private CellLink[] cellLinks;
        [JsonIgnore]
        public CellLink[] CellLinks
        {
            get { return cellLinks; }
            set
            {
                if (cellLinks == value) return;
                cellLinks = value;
                OnPropertyChanged(nameof(CellLinks));
            }
        }
    }

    public class SizeTreatParam : NotifyProperty
    {
        private bool _selected = false;


        private bool _isEnable;
        private string _preName;
        private int _prePix;

        private SizeEnum _preType;
        private string _resultShow;
        private string _outResultShow;


        private string _prePath;


        public bool Selected
        {
            get { return _selected; }
            set
            {
                if (_selected == value) return;
                _selected = value;
                OnPropertyChanged(nameof(Selected));
            }
        }

        public bool IsEnable
        {
            get { return _isEnable; }
            set
            {
                if (_isEnable == value) return;
                _isEnable = value;
                OnPropertyChanged(nameof(IsEnable));
            }
        }

        public string PreName
        {
            get { return _preName; }
            set
            {
                if (_preName == value) return;
                _preName = value;
                OnPropertyChanged(nameof(PreName));
            }
        }

        public SizeEnum PreType
        {
            get { return _preType; }
            set
            {
                if (_preType == value) return;
                _preType = value;
                OnPropertyChanged(nameof(PreType));
            }
        }

        public int PrePix
        {
            get { return _prePix; }
            set
            {
                if (_prePix.Equals(value)) return;
                _prePix = value;
                OnPropertyChanged(nameof(PrePix));
            }
        }

        public string ResultShow
        {
            get { return _resultShow; }
            set
            {
                if (_resultShow == value) return;
                _resultShow = value;
                OnPropertyChanged(nameof(ResultShow));
            }

        }

        public string OutResultShow
        {
            get { return _outResultShow; }
            set
            {
                if (_outResultShow == value) return;
                _outResultShow = value;
                OnPropertyChanged(nameof(OutResultShow));
            }
        }

        public string PrePath
        {
            get { return _prePath; }
            set
            {
                if (_prePath.Equals(value)) return;
                _prePath = value;
                OnPropertyChanged(nameof(PrePath));
            }
        }


        private CellLink[] cellLinks;
        [JsonIgnore]
        public CellLink[] CellLinks
        {
            get { return cellLinks; }
            set
            {
                if (cellLinks == value) return;
                cellLinks = value;
                OnPropertyChanged(nameof(CellLinks));
            }
        }
    }
    /// <summary>
    /// 识别目标定义 class:分类信息    Detection Segmentation:要识别的对象
    /// </summary>
    public class RecongnitionLabel //: IComplexDisplay
    {
        [Category("检测标签定义")]
        [Description("检测标签编码")]
        [ReadOnly(true)]
        public string Id { get; set; } = Guid.NewGuid().ToString();

        [Category("检测标签定义")]
        [DisplayName("检测标签名称")]
        [Description("检测标签名称")]
        public string LabelName { get; set; } = "";

        [Category("检测标签定义")]
        [DisplayName("检测标签描述")]
        [Description("检测标签描述,中文描述")]
        public string LabelDescription { get; set; } = "";

        [Category("检测标签定义")]
        [DisplayName("检测标签分类")]
        [Description("检测标签分类id")]
        //[TypeConverter(typeof(LabelCategoryConverter))]
        public string LabelCategory { get; set; } = "";




    }

    /// <summary>
    /// 检测项识别对象
    /// </summary>
    public class DetectConfigLabel //: IComplexDisplay
    {
        [Category("检测项标签")]
        [DisplayName("检测项标签")]
        [Description("检测标签Id")]
        //[TypeConverter(typeof(DetectionLabelConverter))]
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
        public string LabelId { get; set; }


        [Browsable(false)]
        //public string LabelName { get => GetLabelName(); }

        [Category("检测项标签")]
        [DisplayName("检测标签优先级")]
        [Description("检测标签优先级,值越小,优先级越高")]
        public int LabelPriority { get; set; } = 0;

        //[Category("检测项标签")]
        //[DisplayName("标签BGR值")]
        //[Description("检测标签BGR值,例如:0,128,0")]
        //public string LabelBGR { get; set; }

        //[Category("模型配置")]
        //[DisplayName("模型参数配置")]
        //[Description("模型参数配置集合")]
        //[TypeConverter(typeof(ComplexObjectConvert))]
        //[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
        //public ModelParamSetting ModelParamSetting { get; set; } = new ModelParamSetting();

        //public string GetDisplayText()
        //{
        //    string dName = "";
        //    if (!string.IsNullOrWhiteSpace(LabelId))
        //    {
        //        using (var scope = GlobalVar.Container.BeginLifetimeScope())
        //        {
        //            IProcessConfig config = scope.Resolve<IProcessConfig>();

        //            var mlBase = config.DeviceConfigs.FirstOrDefault(c => c is VisionEngineInitialConfigBase) as VisionEngineInitialConfigBase;
        //            if (mlBase != null)
        //            {
        //                var targetLabel = mlBase.RecongnitionLabelList.FirstOrDefault(u => u.Id == LabelId);
        //                if (targetLabel != null)
        //                {
        //                    dName = targetLabel.GetDisplayText();
        //                }
        //            }
        //        }
        //    }
        //    return dName;
        //}
        //public string GetLabelName()
        //{
        //    var name = "";


        //        var mlBase = iConfig.DeviceConfigs.FirstOrDefault(c => c is VisionEngineInitialConfigBase) as VisionEngineInitialConfigBase;
        //        if (mlBase != null)
        //        {
        //            var label = mlBase.RecongnitionLabelList.FirstOrDefault(u => u.Id == LabelId);
        //            if (label != null)
        //            {
        //                name = label.LabelName;
        //            }
        //        }


        //    return name;
        //}
    }

    /// <summary>
    /// 识别对象定义分类信息 A类B类 
    /// </summary>
    public class RecongnitionLabelCategory //: IComplexDisplay
    {
        [Category("检测标签分类")]
        [Description("检测标签分类")]
        [ReadOnly(true)]
        public string Id { get; set; } = Guid.NewGuid().ToString();

        [Category("检测标签分类")]
        [DisplayName("检测标签分类名称")]
        [Description("检测标签分类名称")]
        public string CategoryName { get; set; } = "A-NG";

        [Category("检测标签分类")]
        [DisplayName("检测标签分类优先级")]
        [Description("检测标签分类优先级,值越小,优先级越高")]
        public int CategoryPriority { get; set; } = 0;

        public string GetDisplayText()
        {
            return CategoryPriority + ":" + CategoryName;
        }
    }

    /// <summary>
    /// 检测过滤
    /// </summary>
    public class DetectionFilter ///: IComplexDisplay
    {
        [Category("过滤器基础信息")]
        [DisplayName("检测标签")]
        [Description("检测标签信息")]
        //[TypeConverter(typeof(DetectionLabelConverter))]

        public string LabelId { get; set; }


        public string LabelName { get; set; }


        [Category("过滤器基础信息")]
        [DisplayName("是否启用过滤器")]
        [Description("是否启用过滤器")]
        public bool IsEnabled { get; set; }

        [Category("过滤器判定信息")]
        [DisplayName("判定结果")]
        [Description("过滤器默认判定结果")]
        public ResultState ResultState { get; set; } = ResultState.ResultTBD;

        [Category("过滤条件")]
        [DisplayName("过滤条件集合")]
        [Description("过滤条件集合,集合之间为“且”关系")]
        //[TypeConverter(typeof(CollectionCountConvert))]
        //  [Editor(typeof(ComplexCollectionEditor<FilterConditions>), typeof(UITypeEditor))]
        public List<FilterConditions> FilterConditionsCollection { get; set; } = new List<FilterConditions>();



        public bool FilterOperation(DetectionResultDetail recongnitionResult)
        {
            return FilterConditionsCollection.All(u =>
            {
                return u.FilterConditionCollection.Any(c =>
                {
                    double compareValue = 0;

                    switch (c.FilterPropperty)
                    {
                        case DetectionFilterProperty.Width:
                            compareValue = recongnitionResult.Rect.Width;
                            break;
                        case DetectionFilterProperty.Height:
                            compareValue = recongnitionResult.Rect.Height;
                            break;
                        case DetectionFilterProperty.Area:
                            compareValue = recongnitionResult.Area;
                            break;
                        case DetectionFilterProperty.Score:
                            compareValue = recongnitionResult.Score;
                            break;
                            //case RecongnitionTargetFilterProperty.Uncertainty:
                            //    compareValue = 0;
                            //    //defect.Uncertainty;
                            //    break;
                    }

                    return compareValue >= c.MinValue && compareValue <= c.MaxValue;
                });
            });
        }
    }

    public class FilterConditions //: IComplexDisplay
    {
        [Category("过滤条件")]
        [DisplayName("过滤条件集合")]
        [Description("过滤条件集合,集合之间为“或”关系")]
        //[TypeConverter(typeof(CollectionCountConvert))]
        //[Editor(typeof(ComplexCollectionEditor<FilterCondition>), typeof(UITypeEditor))]
        public List<FilterCondition> FilterConditionCollection { get; set; } = new List<FilterCondition>();

        //public string GetDisplayText()
        //{
        //    if (FilterConditionCollection.Count == 0)
        //    {
        //        return "空";
        //    }
        //    else
        //    {
        //        var desc = string.Join(" OR ", FilterConditionCollection.Select(u => u.GetDisplayText()));

        //        if (FilterConditionCollection.Count > 1)
        //        {
        //            desc = $"({desc})";
        //        }

        //        return desc;
        //    }
        //}
    }

    public class FilterCondition //: IComplexDisplay
    {
        [Category("识别目标属性")]
        [DisplayName("过滤属性")]
        [Description("识别目标过滤针对的属性")]
        //[TypeConverter(typeof(EnumDescriptionConverter<DetectionFilterProperty>))]
        public DetectionFilterProperty FilterPropperty { get; set; } = DetectionFilterProperty.Width;

        [Category("过滤值")]
        [DisplayName("最小值")]
        [Description("最小值")]
        public double MinValue { get; set; } = 1;

        [Category("过滤值")]
        [DisplayName("最大值")]
        [Description("最大值")]
        public double MaxValue { get; set; } = 99999999;

        //public string GetDisplayText()
        //{
        //    return $"{FilterPropperty.GetEnumDescription()}:{MinValue}-{MaxValue}";
        //}
    }

    public enum DetectionFilterProperty
    {
        [Description("宽度")]
        Width = 1,
        [Description("高度")]
        Height = 2,
        [Description("面积")]
        Area = 3,
        [Description("得分")]
        Score = 4,
        //[Description("不确定性")]
        //Uncertainty = 5,
    }
}