using AntdUI;
using AntdUI.Svg;
using DH.Commons.Base;
using DH.Commons.Enums;
using DH.Commons.Helper;
using DH.Commons.Models;
using DH.Devices.Camera;
using DH.Devices.Motion;
using DH.Devices.PLC;
using DH.Devices.Vision;
using DHSoftware.Languages;
using DHSoftware.Models;
using DHSoftware.Utils;
using DHSoftware.Views;
using DVPCameraType;
using HalconDotNet;
using Microsoft.Win32;
using OpenCvSharp;
using System;
using System.CodeDom;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using XKRS.UI.Device.Winform;
using static AntdUI.Math3D;
using static DH.Commons.Enums.EnumHelper;
using Camera = DHSoftware.Models.Camera;
using ResultState = DH.Commons.Base.ResultState;

namespace DHSoftware
{
    public partial class MainWindow : AntdUI.Window
    {
        private Dictionary<string, List<string>> _cameraRelatedDetectionDict = null;

        private string _loginName;

        public string LoginName
        {
            get { return _loginName; }
            set
            {
                _loginName = value;
                UpdateLabel();
            }
        }

        private bool _ShowConfig;

        public bool ShowConfig
        {
            get { return _ShowConfig; }
            set
            {
                _ShowConfig = value;
                UpdateConfig();
            }
        }

        private bool _addscheme;

        public bool Addscheme
        {
            get { return _addscheme; }
            set
            {
                _addscheme = value;
                UpdateScheme();
            }
        }

        private bool _deletescheme;

        public bool Deleteschememe
        {
            get { return _deletescheme; }
            set
            {
                _deletescheme = value;
                UpdateScheme();
            }
        }

        private bool _loadscheme;

        public bool Loadscheme
        {
            get { return _loadscheme; }
            set
            {
                _loadscheme = value;
                UpdateScheme();
            }
        }

        private void UpdateScheme()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action(UpdateScheme));
                return;
            }

            if (Loadscheme)
            {
                btnDeleteProject.Visible = true;
            }
            else
            {
                btnDeleteProject.Visible = false;
            }
            if (Addscheme)
            {
                btnAddProject.Visible = true;
            }
            else
            {
                btnAddProject.Visible = false;
            }
            if (Deleteschememe)
            {
                btnLoadProject.Visible = true;
            }
            else
            {
                btnLoadProject.Visible = false;
            }
        }

        private void UpdateLabel()
        {
            if (lbName.InvokeRequired)
            {
                lbName.Invoke(new Action(UpdateLabel));
                return;
            }
            lbName.Text = _loginName;
        }

        private void UpdateConfig()
        {
            if (ShowConfig)
            {
                if (segmented1.InvokeRequired)
                {
                    segmented1.Invoke(new Action(UpdateConfig));
                    return;
                }
                // 恢复显示时
                segmented1.Items.Insert(4, itemToHide);
            }
            else
            {
                if (segmented1.InvokeRequired)
                {
                    segmented1.Invoke(new Action(UpdateConfig));
                    return;
                }
                segmented1.Items.Remove(itemToHide);
            }
        }

        public MainWindow()
        {
            InitializeComponent();

            //refreshTimer.Start();
            //初始化数据
            InitData();
            //绑定事件
            BindEventHandler();
            //UserConfigFrm userControlFrm = new UserConfigFrm();

            //userControlFrm.Window = this;
            //userControlFrm.Dock = DockStyle.Fill;
            //tabPage2.Controls.Add(userControlFrm);
        }

        /// <summary>
        /// 窗体对象实例
        /// </summary>
        private static MainWindow _instance;

        internal static MainWindow Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new MainWindow();
                return _instance;
            }
        }

        private SegmentedItem itemToHide;

        private void InitData()
        {
            itemToHide = segmented1.Items[4];
            segmented1.Items.Remove(itemToHide);
        }

        public void LoadScheme()
        {
            try
            {
                //方案配置初始化
                SchemeHelper.Initialize();
                //读取方案列表
                List<string> list = SchemeHelper.GetAllSchemes();
                string CurrentScheme = "默认方案";
                //如果是空,新增默认数据
                if (list == null || list.Count <= 0)
                {
                    list = new() { CurrentScheme };
                    //显示到方案列表
                    sltProjects.Items.Clear();

                    sltProjects.Items.Add(CurrentScheme);
                    //保存到方案配置
                    SchemeHelper.AddScheme(CurrentScheme);
                    SchemeHelper.SetCurrentScheme(CurrentScheme);
                    //新构建配置文件
                    ConfigHelper.InitializeScheme(CurrentScheme);

                    sltProjects.SelectedIndex = 0;
                }
                else
                {
                    foreach (string s in list)
                    {
                        sltProjects.Items.Add(s);
                    }
                    CurrentScheme = SchemeHelper.GetCurrentScheme();
                    sltProjects.SelectedValue = CurrentScheme;
                }
                SystemModel.CurrentScheme = CurrentScheme;
                //加载当前方案配置
                ConfigHelper.LoadConfig();
            }
            catch (Exception ex)
            {
                AntdUI.Message.error(this, ex.Message, autoClose: 3);
            }
        }

        public void ConnectCamera()
        {
            Cameras.Clear();
            HKCameras.Clear();
            if (ConfigModel.CameraBaseList.Count > 0)
            {
                for (int i = 0; i < ConfigModel.CameraBaseList.Count; i++)
                {
                    var cameraBase = ConfigModel.CameraBaseList[i];
                    if (cameraBase.CamType == EnumCamType.度申Do3think)
                    {
                        Do3ThinkCamera cam = new Do3ThinkCamera();

                        cam.CameraName = cameraBase.CameraName;
                        cam.CameraIP = cameraBase.CameraIP;
                        cam.IsEnabled = cameraBase.IsEnabled;
                        Cameras.Add(cam);
                        cam.CameraConnect();
                        cam.OnHImageOutput += OnCameraHImageOutput;
                    }
                    else if (cameraBase.CamType == EnumCamType.海康hik)
                    {
                        HikVisionCamera cam = new HikVisionCamera();
                        cam.CameraName = cameraBase.CameraName;
                        cam.CameraIP = cameraBase.CameraIP;
                        cam.IsEnabled = cameraBase.IsEnabled;
                        HKCameras.Add(cam);
                        // cam.CameraConnect();
                        cam.OnHImageOutput += OnCameraHImageOutput;
                    }
                }
            }
        }

        public void ConnectPLC()
        {
            if (ConfigModel.PLCBaseList.Count > 0)
            {
                for (int i = 0; i < ConfigModel.PLCBaseList.Count; i++)
                {
                    var plcBase = ConfigModel.PLCBaseList[i];
                    if (plcBase.PLCType == EnumPLCType.信捷XC网口)
                    {
                        PLC.IP = plcBase.IP;
                        PLC.PLCType = plcBase.PLCType;
                        PLC.Enable = plcBase.Enable;
                        PLC.PLCName = plcBase.PLCName;
                        PLC.PLCItemList = plcBase.PLCItemList;
                        PLC.Port = plcBase.Port;
                        PLC.PLCConnect();
                    }
                }
            }
        }

        public void InitModel()
        {
            Dectection.Clear();
            _cameraRelatedDetectionDict = new();

            if (ConfigModel.DetectionList.Count > 0)
            {
                for (int i = 0; i < ConfigModel.DetectionList.Count; i++)
                {
                    DetectionConfig detectionConfig = ConfigModel.DetectionList[i];
                    var detection = ConfigModel.DetectionList[i];
                    detectionConfig.CameraCollects = detection.CameraCollects;
                    detectionConfig.ModelconfThreshold = detection.ModelconfThreshold;
                    detectionConfig.ModelWidth = detection.ModelWidth;
                    detectionConfig.ModelHeight = detection.ModelHeight;
                    detectionConfig.In_lable_path = detection.In_lable_path;
                    detectionConfig.IsEnabled = detection.IsEnabled;
                    detectionConfig.ShowLocation.X = (i + 1) % 5+ (i + 1) / 5;
                  //  detectionConfig.ShowLocation.X = detection.ShowLocation.X;
                    detectionConfig.ShowLocation.Y = (i + 1) / 5+1;
                   // detectionConfig.ShowLocation.Y = detection.ShowLocation.Y;
                    DetectionConfigs.Add(detectionConfig);
                }
            }
            DetectionConfigs.ForEach(detection =>
            {
                detection.CameraCollects.ForEach(cam =>
                {
                    List<string> Dets = new List<string>
                   {
                        detection.Id
                   };
                    if (!_cameraRelatedDetectionDict.ContainsKey(cam.CameraSourceId))
                    {
                        _cameraRelatedDetectionDict.Add(cam.CameraSourceId, Dets);
                    }
                    else
                    {
                        _cameraRelatedDetectionDict[cam.CameraSourceId].Add(detection.Id);
                    }
                }
               );
            });
            string inferenceDevice = "CPU";

            //
            _visionEngine = new SimboVisionDriver();
            _visionEngine.DetectionConfigs = DetectionConfigs;

            //初始化模型 加载模型
            _visionEngine.Init();
            CtrlVisionRunBase ctrlVisionRun = new CtrlVisionRunBase(_visionEngine);
            ctrlVisionRun.Dock = DockStyle.Fill;
            tabImgDisplay.Controls.Add(ctrlVisionRun);
        }

        private void BindEventHandler()
        {
            btnAddProject.Click += BtnAddProject_Click;
            btnDeleteProject.Click += BtnDeleteProject_Click;
            btnLoadProject.Click += BtnLoadProject_Click;
        }

        private void BtnDeleteProject_Click(object? sender, EventArgs e)
        {
            try
            {
                if (sltProjects.Items.Count == 0 || sltProjects.SelectedIndex == -1) return;

                var result = AntdUI.Modal.open(this, "删除警告!", "确认要删除该方案吗?", TType.Warn);
                if (result == DialogResult.OK)
                {
                    int selectedIndex = sltProjects.SelectedIndex;

                    // 删除当前选中项
                    SchemeHelper.DeleteScheme(sltProjects.Text);
                    ConfigHelper.DeleteSchemeConfig(sltProjects.Text);
                    AntdUI.Message.success(this, $"删除方案{sltProjects.Text}成功!", autoClose: 3);
                    sltProjects.Items.RemoveAt(selectedIndex);
                    // 自动选择下一个(如果存在)
                    if (sltProjects.Items.Count > 0)
                    {
                        // 如果删除的不是最后一项,则选中原位置的新项,否则选中最后一项
                        sltProjects.SelectedIndex = selectedIndex < sltProjects.Items.Count
                            ? selectedIndex
                            : sltProjects.Items.Count - 1;

                        SystemModel.CurrentScheme = sltProjects.Text;
                        SchemeHelper.SetCurrentScheme(SystemModel.CurrentScheme);
                        //加载当前方案配置
                        ConfigHelper.LoadConfig();
                    }
                    else
                    {
                        sltProjects.SelectedIndex = -1; // 清空选择
                        AntdUI.Modal.open(this, "空方案警告!", "当前方案全部删除,需重启程序!", TType.Warn);
                    }
                }
            }
            catch (Exception ex)
            {
                AntdUI.Message.error(this, ex.Message, autoClose: 3);
            }
        }

        private void BtnLoadProject_Click(object? sender, EventArgs e)
        {
            try
            {
                if (sltProjects.Items.Count == 0 || sltProjects.SelectedIndex == -1) return;
                if (SystemModel.CurrentScheme == sltProjects.Text)
                {
                    AntdUI.Message.warn(this, "当前已是该方案,无需重复载入!", autoClose: 3);
                    return;
                }
                //修改当前软件当前方案
                SystemModel.CurrentScheme = sltProjects.Text;
                //修改配置当前方案
                SchemeHelper.SetCurrentScheme(SystemModel.CurrentScheme);
                //将配置文件替换为当前方案
                ConfigHelper.LoadConfig();
                AntdUI.Message.success(this, $"载入方案{SystemModel.CurrentScheme}成功!", autoClose: 3);
            }
            catch (Exception ex)
            {
                AntdUI.Message.error(this, ex.Message, autoClose: 3);
            }
        }

        private void BtnAddProject_Click(object? sender, EventArgs e)
        {
            try
            {
                var form = new AddSchemeControl(this, "新增方案操作") { Size = new System.Drawing.Size(400, 300) };
                AntdUI.Modal.open(new AntdUI.Modal.Config(this, "", form, TType.None)
                {
                    BtnHeight = 0,
                });
                if (form.submit)
                {
                    string SchemeName = form.SchemeName;
                    //保存到方案配置
                    SchemeHelper.AddScheme(SchemeName);
                    if (form.NullScheme)
                    {
                        //新构建配置文件
                        ConfigHelper.InitializeScheme(SchemeName);
                    }
                    else
                    {
                        //派生当前方案
                        ConfigHelper.DeriveScheme(SchemeName);
                    }
                    //刷新方案列表
                    sltProjects.Items.Clear();
                    List<string> list = SchemeHelper.GetAllSchemes();
                    foreach (string s in list)
                    {
                        sltProjects.Items.Add(s);
                    }
                    string CurrentScheme = SchemeHelper.GetCurrentScheme();
                    sltProjects.SelectedValue = CurrentScheme;
                    AntdUI.Message.success(this, $"新增方案{SchemeName}成功!", autoClose: 3);
                }
            }
            catch (Exception ex)
            {
                AntdUI.Message.error(this, ex.Message, autoClose: 3);
            }
        }

        public List<HikVisionCamera> HKCameras { get; } = new List<HikVisionCamera>();
        public List<Do3ThinkCamera> Cameras { get; } = new List<Do3ThinkCamera>();
        public Dictionary<string, SimboObjectDetection> Dectection { get; } = new Dictionary<string, SimboObjectDetection>();
        public XinJEPLCTcpNet PLC { get; } = XinJEPLCTcpNet.Instance;
        private SLDMotion sLDMotion = new SLDMotion();

        private void MainWindow_Load(object sender, EventArgs e)
        {
        }

        private bool _isClosing = false; // 状态标志

        private void MainWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_isClosing) return;
            _isClosing = true;
            // 取消默认关闭行为
            e.Cancel = true;

            // 立即隐藏主窗口
            this.Hide();

            // 显示关闭界面
            CloseWindow.Instance.Show();
            Thread.Sleep(200);
            try
            {
                // 执行关闭操作
                foreach (var camera in Cameras)
                {
                    camera.CameraDisConnect();
                }
                foreach (var camera in HKCameras)
                {
                    camera.CameraDisConnect();
                }
                PLC.PLCDisConnect();
                CloseWindow.Instance.Close();// 关闭提示窗口
                                             //Application.Exit();
                System.Environment.Exit(0);
            }
            catch (Exception ex)
            {
                CloseWindow.Instance.Close();

                System.Environment.Exit(0);
            }
        }

        private void segmented1_SelectIndexChanged(object sender, EventArgs e)
        {
            // Get the index of the selected item
            int selectedIndex = segmented1.SelectIndex;

            // Handle each button based on its index
            switch (selectedIndex)
            {
                case 0: // "启动" (Start)
                    HandleStartButton();
                    break;

                case 1: // "停止" (Stop)
                    HandleStopButton();
                    break;

                case 2: // "复位" (Reset)
                    HandleResetButton();
                    break;

                case 3: // "设置" (Settings)
                    HandleLoginButton();
                    break;

                case 4: // "登录" (Login)
                    HandleSettingsButton();
                    break;

                default:
                    break;
            }
            segmented1.SelectIndex = -1;
        }

        public bool CurrentMachine = false;
        public volatile int ProductNum_Total = 0;
        public volatile int ProductNum_OK = 0;
        private readonly object _cameraSummaryLock = new object();
        public SimboVisionDriver? _visionEngine = null;

        public PLCBase? _PLCConfig = null;
        private List<DetectionConfig> DetectionConfigs = new List<DetectionConfig>();
        private List<SimboStationMLEngineSet> SimboStationMLEngineList = new List<SimboStationMLEngineSet>();
        private Dictionary<string, HDevEngineTool> HalconToolDict = new Dictionary<string, HDevEngineTool>();
        public List<RecongnitionLabel> RecongnitionLabelList { get; set; } = new List<RecongnitionLabel>();
        public DateTime startTime;

        private void HandleStartButton()
        {
            StartProcess();
        }

        private static int currentRegister = 411;  // 初始为 D411

        private void StartProcess()
        {
            startTime= DateTime.Now;
            //计数清零
            PieceCount = 0;
            //吹气点位归置
            currentRegister = 411;
            
            if (PLC?.Enable == true)
            {
                PLC.CountToZero();
                PLC.OnNewPieces -= MainMotion_NewPieces;
                PLC.OnNewPieces += MainMotion_NewPieces;
            }

            ConfigModel.CameraBaseList.ForEach(d =>
            {
                if (d is CameraBase cam)
                {
                    cam.SnapshotCount = 0;
                }
            });

            //PrepareBatchNO();
            // isInPositionChecking = false;
            //isFullTrayChecking = false;
            //队列清空
            // var temp = new List<ITriggerSet>();
            // temp.AddRange(XKRSPLCConfig.TriggerConfigCollection);
            // temp.AddRange(XKRSPLCConfig.SnapshotTriggerConfigCollection);

            //temp.ForEach(t =>
            //{
            //    var diskInfo = XKRSPLCConfig.DiskInfoList.FirstOrDefault(u => u.DiskName == t.DiskName);
            //    if (diskInfo != null)
            //    {
            //        t.AxisNum = diskInfo.DiskAxisNum;
            //    }
            //    else
            //    {
            //        t.AxisNum = -1;
            //    }
            //});

            //if (temp.Any(u => u.AxisNum < 0))
            //{
            //    LogAsync(DateTime.Now, LogLevel.Error, "触发信号归属转盘未确认");
            //    return new ProcessResponse(false);
            //}

            // _diskInfoListInOrder = XKRSPLCConfig.DiskInfoList.OrderBy(u => u.DiskSequence).ToList();
            //  var axisNumList = _diskInfoListInOrder.Select(u => u.DiskAxisNum).ToList();

            /// PrepareMLEngine();

            // if (_PLCConfig?.Enable == true)
            //挡料电机操作
            //  _PLC.FeedingMotor(_PLCConfig.CunToZeroSpeed, _PLCConfig.CunPos, _PLCConfig.CunSpeed, _PLCConfig.CunDirection);

            //流程开启操作配置
            // ProcessInitialAction();
            //  if (_PLC?Enabled == true)
            //皮带
            //   _PLC.Belt(true);

            //DeviceCollection.ForEach(d =>
            //{
            //    if (d is CameraBase c)
            //    {
            //        c.OnHImageOutput -= OnCameraHImageOutput;
            //        c.OnHImageOutput += OnCameraHImageOutput;
            //        c.SnapshotCount = 0;
            //    }
            //});
            _productLists.Clear();

            #region 虚拟相机

            //mOfflineImageTimer = new System.Timers.Timer();

            //mOfflineImageTimer.Elapsed += OnEmitSerialPortAsync;
            //mOfflineImageTimer.Interval = 1000;
            //mOfflineImageTimer.Start();

            #endregion 虚拟相机

            var settings = _visionEngine.DetectionConfigs.Where(u => u.IsEnabled && u.IsAddStation).ToList();
            if (settings != null)
            {
                settings = settings.Where(s => s.IsEnabled).ToList();
                ProductBaseCount = settings.Count;

                for (int i = 0; i < ProductBaseCount * ProductListMulti; i++)
                {
                    ConcurrentDictionary<uint, ProductData> products = new ConcurrentDictionary<uint, ProductData>();
                    _productLists.Add(products);
                }
            }

            //   _MGSCameraList = DeviceCollection
            //.OfType<MGSCameraDriver>()  // 直接筛选出 MGSCameraDriver 类型的元素
            //.Where(camera => camera.IConfig != null && camera.IConfig.IsEnabled)  // 进一步筛选 IConfig 不为 null 且 IsEnabled 为 true
            //.ToList();

            //   ProductBaseCount = _MGSCameraList.Count;

            for (int i = 0; i < ProductBaseCount * ProductListMulti; i++)
            {
                ConcurrentDictionary<uint, ProductData> products = new ConcurrentDictionary<uint, ProductData>();
                _productLists.Add(products);
            }

            // 转盘操作
            // if (_PLC?.IIConfig?.IsEnabled == true)

            //   _PLC.TurntableOpen(XKRSPLCConfig.TurnSpeed, XKRSPLCConfig.TurnDirection);
            PLCItem itemSpeed = PLC.PLCItemList.FirstOrDefault(u => u.Name == "转盘速度");
            if (itemSpeed != null)
            {
                PLC.TurntableOpen();
            }

            Thread.Sleep(500);

            //振动盘
            //if (XKRSPLCConfig.IsEnableVibratory)
            //{
            //    if (_PLC.IIConfig.IsEnabled)
            //        _PLC.Vibratory(true);
            //}

            //InitialOEEStatistic();

            // MachineState = MachineState.Running;
        }

        private void PrepareMLEngine()
        {
            //if (_visionEngine == null)
            //{
            //    _visionEngine = DeviceCollection.FirstOrDefault(u => u is VisionEngineBase) as VisionEngineBase;
            //}

            //if (_visionEngine == null)
            //{
            //    throw new ProcessException($"未能获取检测设备");
            //}

            //相机模组
            //_cameraRelatedDetectionDict = new();

            //detectionList.ForEach(detection =>
            //{
            //    detection.CameraCollects.ForEach(cam =>
            //    {
            //        List<string> Dets = new List<string>
            //        {
            //            detection.Id
            //        };
            //        if (!_cameraRelatedDetectionDict.ContainsKey(cam.CameraSourceId))
            //        {
            //            _cameraRelatedDetectionDict.Add(cam.CameraSourceId, Dets);
            //        }
            //        else
            //        {
            //            _cameraRelatedDetectionDict[cam.CameraSourceId].Add(detection.Id);
            //        }

            //    });
            //});

            //_visionEngine.OnDetectionWarningStop += VisionEngine_OnDetectionWarningStopAsync;
        }

#if false
        private void HandleStartButton2()
        {
            CurrentMachine = true;

            //_visionEngine.Start();
            //[Category("深度学习检测配置")]
            //[DisplayName("检测标签定义集合")]
            //[Description("定义检测标签的集合,例如:Seg/Detection模式:断裂、油污、划伤...;Class模式:ok、ng、上面、下面、套环、正常...")]
            //[TypeConverter(typeof(CollectionCountConvert))]
            //[Editor(typeof(ComplexCollectionEditor<RecongnitionLabel>), typeof(UITypeEditor))]
            RecongnitionLabel recongnition = new RecongnitionLabel
            {
                LabelName = "youwu",
                LabelDescription = "油污",
                LabelCategory = "A_NG"
            };
            RecongnitionLabel recongnition2 = new RecongnitionLabel
            {
                LabelName = "youwu",
                LabelDescription = "油污",
                LabelCategory = "A_NG"
            };
            RecongnitionLabel recongnition3 = new RecongnitionLabel
            {
                LabelName = "youwu",
                LabelDescription = "油污",
                LabelCategory = "A_NG"
            };
            RecongnitionLabelList.Add(recongnition);
            RecongnitionLabelList.Add(recongnition2);
            RecongnitionLabelList.Add(recongnition3);

            var det1 = new DetectionConfig("相机1", ModelType.目标检测, @"D:\PROJECTS\X015\Vision\Cam1.onnx", false, "Cam1");
            var det2 = new DetectionConfig("相机2", ModelType.目标检测, @"D:\PROJECTS\X015\Vision\Cam2.onnx", false, "Cam2");
            var det3 = new DetectionConfig("相机3", ModelType.目标检测, @"D:\PROJECTS\X015\Vision\Cam3.onnx", false, "Cam3");
            var det4 = new DetectionConfig("相机4", ModelType.目标检测, @"D:\PROJECTS\X015\Vision\Cam4.onnx", false, "Cam4");
            var det5 = new DetectionConfig("相机5", ModelType.目标检测, @"D:\PROJECTS\X015\Vision\Cam5.onnx", false, "Cam5");
            var det6 = new DetectionConfig("相机6", ModelType.目标检测, @"D:\PROJECTS\X015\Vision\Cam6.onnx", false, "Cam6");
            var det7 = new DetectionConfig("相机7", ModelType.目标检测, @"D:\PROJECTS\X015\Vision\Cam7.onnx", false, "Cam7");
            var det8 = new DetectionConfig("相机8", ModelType.目标检测, @"D:\PROJECTS\X015\Vision\Cam8.onnx", false, "Cam8");
            List<RelatedCamera> CameraCollects = new List<RelatedCamera>();
            CameraCollects.Add(new RelatedCamera("Cam1"));
            List<RelatedCamera> CameraCollects2 = new List<RelatedCamera>();
            CameraCollects2.Add(new RelatedCamera("Cam2"));
            List<RelatedCamera> CameraCollects3 = new List<RelatedCamera>();
            CameraCollects3.Add(new RelatedCamera("Cam3"));
            List<RelatedCamera> CameraCollects4 = new List<RelatedCamera>();
            CameraCollects4.Add(new RelatedCamera("Cam4"));
            List<RelatedCamera> CameraCollects5 = new List<RelatedCamera>();
            CameraCollects5.Add(new RelatedCamera("Cam5"));
            List<RelatedCamera> CameraCollects6 = new List<RelatedCamera>();
            CameraCollects6.Add(new RelatedCamera("Cam6"));
            List<RelatedCamera> CameraCollects7 = new List<RelatedCamera>();
            CameraCollects7.Add(new RelatedCamera("Cam7"));
            List<RelatedCamera> CameraCollects8 = new List<RelatedCamera>();
            CameraCollects8.Add(new RelatedCamera("Cam8"));

            float Conf = 0.5f;

            det1.CameraCollects = CameraCollects;
            det1.ModelconfThreshold = Conf;
            det1.ModelWidth = 640;
            det1.ModelHeight = 640;
            det1.In_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam1.txt";
            det1.IsEnabled = true;
            det1.ShowLocation.X = 1;
            det1.ShowLocation.Y = 1;

            det2.CameraCollects = CameraCollects2;
            det2.ModelconfThreshold = Conf;
            det2.ModelWidth = 640;
            det2.ModelHeight = 640;
            det2.In_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam2.txt";
            det2.IsEnabled = true;
            det2.ShowLocation.X = 2;
            det2.ShowLocation.Y = 1;

            det3.CameraCollects = CameraCollects3;
            det3.ModelconfThreshold = Conf;
            det3.ModelWidth = 640;
            det3.ModelHeight = 640;
            det3.In_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam3.txt";
            det3.IsEnabled = true;
            det3.ShowLocation.X = 3;
            det3.ShowLocation.Y = 1;

            det4.CameraCollects = CameraCollects4;
            det4.ModelconfThreshold = Conf;
            det4.ModelWidth = 640;
            det4.ModelHeight = 640;
            det4.In_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam4.txt";
            det4.IsEnabled = true;
            det4.ShowLocation.X = 4;
            det4.ShowLocation.Y = 1;

            det5.CameraCollects = CameraCollects5;
            det5.ModelconfThreshold = Conf;
            det5.ModelWidth = 640;
            det5.ModelHeight = 640;
            det5.In_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam5.txt";
            det5.IsEnabled = true;
            det5.ShowLocation.X = 1;
            det5.ShowLocation.Y = 2;

            det6.CameraCollects = CameraCollects6;
            det6.ModelconfThreshold = Conf;
            det6.ModelWidth = 640;
            det6.ModelHeight = 640;
            det6.In_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam6.txt";
            det6.IsEnabled = true;
            det6.ShowLocation.X = 2;
            det6.ShowLocation.Y = 2;

            det7.CameraCollects = CameraCollects7;
            det7.ModelconfThreshold = Conf;
            det7.ModelWidth = 640;
            det7.ModelHeight = 640;
            det7.In_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam7.txt";
            det7.IsEnabled = true;
            det7.ShowLocation.X = 3;
            det7.ShowLocation.Y = 2;

            det8.CameraCollects = CameraCollects8;
            det8.ModelconfThreshold = Conf;
            det8.ModelWidth = 640;
            det8.ModelHeight = 640;
            det8.In_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam8.txt";
            det8.IsEnabled = true;
            det8.ShowLocation.X = 4;
            det8.ShowLocation.Y = 2;

            DetectionConfigs.Add(det1);
            DetectionConfigs.Add(det2);
            DetectionConfigs.Add(det3);
            DetectionConfigs.Add(det4);
            DetectionConfigs.Add(det5);
            DetectionConfigs.Add(det6);
            DetectionConfigs.Add(det7);
            DetectionConfigs.Add(det8);

            Cameras.Clear();
            HKCameras.Clear();
            Dectection.Clear();
            _cameraRelatedDetectionDict = new();

#if false
            for (int i = 1; i <= 8; i++)
            {
                HikVisionCamera camera = new HikVisionCamera();
                camera.CameraName = $"Cam{i}";
                camera.CameraIP = $"192.168.{i}.1";
                camera.ComputerIP = $"192.168.{i}.1";
                camera.CameraConnect();
                camera.OnHImageOutput += OnCameraHImageOutput;
                HKCameras.Add(camera);
            }
#else
            //Do3ThinkCamera do3ThinkCamera1 = new Do3ThinkCamera();

            //do3ThinkCamera1.dvpStreamFormat = dvpStreamFormat.S_RAW8;
            //do3ThinkCamera1.CameraName = "Cam1";
            //do3ThinkCamera1.CameraConnect();
            //do3ThinkCamera1.OnHImageOutput += OnCameraHImageOutput;
            // Cameras.Add(do3ThinkCamera1);
            for (int i = 1; i <= 8; i++)
            {
                Do3ThinkCamera cam = new Do3ThinkCamera();
                if (i == 1)
                {
                    cam.dvpStreamFormat = dvpStreamFormat.S_RAW8;
                }
                else
                {
                    cam.dvpStreamFormat = dvpStreamFormat.S_RGB24;
                }

                cam.CameraName = $"Cam{i}";
                Cameras.Add(cam);
                cam.CameraConnect();
                cam.OnHImageOutput += OnCameraHImageOutput;
            }

#endif

            DetectionConfigs.ForEach(detection =>
            {
                detection.CameraCollects.ForEach(cam =>
                {
                    List<string> Dets = new List<string>
                   {
                        detection.Id
                   };
                    if (!_cameraRelatedDetectionDict.ContainsKey(cam.CameraSourceId))
                    {
                        _cameraRelatedDetectionDict.Add(cam.CameraSourceId, Dets);
                    }
                    else
                    {
                        _cameraRelatedDetectionDict[cam.CameraSourceId].Add(detection.Id);
                    }
                }
               );
            });
            string inferenceDevice = "CPU";

            _visionEngine = new SimboVisionDriver();
            _visionEngine.DetectionConfigs = DetectionConfigs;

            _visionEngine.Init();
            CtrlVisionRunBase ctrlVisionRun = new CtrlVisionRunBase(_visionEngine);
            tabImgDisplay.Controls.Add(ctrlVisionRun);

            //Add the code for the "启动" button click here

            ////初始化Halcon工具
            //InitialHalconTools();

            ////深度学习模型加载
            //bool resultOK = InitialSimboMLEnginesAsync();
            //if (resultOK)
            //{
            //    //初始化失败
            //    // return;
            //}
            //位置比较卡

            sLDMotion.AxisSettings = new List<AxisSetting>();
            AxisSetting axis1 = new AxisSetting();
            axis1.AxisIndex = 0;
            axis1.AxisName = "转盘1";
            axis1.IsAxisEnabled = true;
            //axis1.AlarmLogic = AxisDirection.Positive;
            sLDMotion.IODefinitionCollection = new List<IODefinition>();
            Motion(sLDMotion.IODefinitionCollection);

            sLDMotion.SnapshotSettings = new List<SnapshotSetting>();
            int[] cameraPositions = { 24161, 33608, 39702, 45701 };

            sLDMotion.SnapshotSettings.Add(new SnapshotSetting
            {
                IsEnabled = true,
                CameraIO = sLDMotion.IODefinitionCollection.FirstOrDefault(t => t.IOType == IOType.OUTPUT && t.IOIndex == 13),
                CameraPosition = 7613,
                StationNumber = 0
            });
            for (int i = 0; i < 4; i++)
            {
                sLDMotion.SnapshotSettings.Add(new SnapshotSetting
                {
                    IsEnabled = true,
                    CameraIO = sLDMotion.IODefinitionCollection.FirstOrDefault(t => t.IOType == IOType.OUTPUT && t.IOIndex == i),
                    CameraPosition = cameraPositions[i],
                    StationNumber = 0
                });
            }

            sLDMotion.BlowSettings = new List<BlowSetting>();
            int[] BlowPositions = { 61353, 68566 };
            sLDMotion.BlowSettings.Add(new BlowSetting
            {
                IsEnabled = true,
                BlowIO = sLDMotion.IODefinitionCollection.FirstOrDefault(t => t.IOType == IOType.OUTPUT && t.IOIndex == 5),
                BlowPosition = BlowPositions[0],
                StationNumber = 0
            });
            sLDMotion.BlowSettings.Add(new BlowSetting
            {
                IsEnabled = true,
                BlowIO = sLDMotion.IODefinitionCollection.FirstOrDefault(t => t.IOType == IOType.OUTPUT && t.IOIndex == 6),
                BlowPosition = BlowPositions[1],
                StationNumber = 0
            });

            //SnapshotSetting sna1 = new SnapshotSetting();
            //sna1.IsEnabled = true;
            //sna1.CameraIO= sLDMotion.IODefinitionCollection.FirstOrDefault(t => t.IOType == IOType.OUTPUT && t.IOIndex == 0);
            //sna1.CameraPosition = 17000;
            //sna1.StationNumber = 0;

            // sLDMotion.SnapshotSettings.Add(sna1);
            sLDMotion.AxisSettings.Add(axis1);
            sLDMotion.Init();
            sLDMotion.OnNewPieces -= MainMotion_NewPieces;
            sLDMotion.OnNewPieces += MainMotion_NewPieces;
            // sLDMotion.Start();

            //PLC.IP = "192.168.6.6";
            //PLC.Port = 502;
            //PLC.PLCConnect();
            //PLC.OnNewPieces -= MainMotion_NewPieces;
            //PLC.OnNewPieces += MainMotion_NewPieces;
            ProductBaseCount = 8;
            for (int i = 0; i < ProductBaseCount * ProductListMulti; i++)
            {
                ConcurrentDictionary<uint, ProductData> products = new ConcurrentDictionary<uint, ProductData>();
                _productLists.Add(products);
            }
            sLDMotion.AxisStop();
            bool e = sLDMotion.CArdReset();
            //转盘速度
            sLDMotion.JOGRun(14000, 100000);
            startTime = DateTime.Now;
        }
        public void Motion(List<IODefinition> iODefinitions)
        {
            for (int i = 0; i < 16; i++)
            {
                iODefinitions.Add(new IODefinition
                {
                    IOType = IOType.INPUT,
                    IOIndex = i,
                    IODesc = $"入料传感器{i + 1}"
                });
            }
            for (int i = 0; i < 16; i++)
            {
                iODefinitions.Add(new IODefinition
                {
                    IOType = IOType.OUTPUT,
                    IOIndex = i,
                    IODesc = $"入料传感器{i + 1}"
                });
            }
        }
#endif

        private uint PieceCount = 0;
        private List<ConcurrentDictionary<uint, ProductData>> _productLists = new List<ConcurrentDictionary<uint, ProductData>>();
        private int ProductListMulti = 2;
        private int ProductBaseCount = 0;

        private int PieceNumberToIndex(uint pn)
        {
            // 物料编号,取余 集合数量

            int ret = (int)(pn % (ProductBaseCount * ProductListMulti));
            return ret;
        }

        private DateTime _ctTime = DateTime.Now;

        public async void MainMotion_NewPieces(int axisIndex, uint pieceNumber)
        {
            //if (MachineState != MachineState.Running && MachineState != MachineState.Warning)
            //{
            //    return;
            //}

            PieceCount++;

            int index = PieceNumberToIndex(pieceNumber);
            // productDatas.Add(pData);
            //转盘2 的物料是不是重新覆盖之前的pDta
            if (axisIndex == 1)
            {
                ProductData pData = new ProductData("", pieceNumber, ProductBaseCount);
                _productLists[index][pieceNumber] = pData;
            }
            string logStr = $"时间:{DateTime.Now} 轴{axisIndex}新产品{pieceNumber}加入队列{index}----入料计数{PieceCount}\n";
            Task.Run(() =>
            {
                //this.BeginInvoke(new MethodInvoker(delegate () { richTextBox1.AppendText(logStr); }));
            });
            DateTime dtNow = DateTime.Now;
            UpdateCT(null, (float)(dtNow - _ctTime).TotalSeconds);
            _ctTime = dtNow;
        }

        public async Task UpdateCT(object objData, float ctTime)
        {
            await Task.Run(() =>
            {
                //OnUpdateCT?.Invoke(objData, ctTime);
            });
        }

        /// <summary>
        /// 相机回调
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="camera"></param>
        /// <param name="imageSet"></param>
        private void OnCameraHImageOutput(DateTime dt, CameraBase camera, Mat imageSet)
        {
            //if (camera.CameraName.Equals("cam1", StringComparison.OrdinalIgnoreCase))
            //{
            //    Console.WriteLine();
            //}
            //if (camera.CameraName.Equals("cam2", StringComparison.OrdinalIgnoreCase))
            //{
            //    Console.WriteLine();
            //}

            // 获取该相机的拍照计数
            uint productNumber = (uint)camera.SnapshotCount;

            Task.Run(async () =>
            {
                using (Mat localImageSet = imageSet.Clone())  // 复制 Mat 避免并发问题
                {
                    // imageSet?.Dispose();
                    // 拍照计数与物件编号一致,查找对应的产品
                    ProductData product = null;
                    //内外壁模组多个相机的处理方法
                    //计算队列的方法不变
                    int index = PieceNumberToIndex(productNumber);
                    // 找到产品存放在哪个队列里
                    ConcurrentDictionary<uint, ProductData> tmpDic = _productLists[index];

                    try
                    {
                        int retryTimes = 100;
                        while (product == null && retryTimes > 0)
                        {
                            if (tmpDic.ContainsKey(productNumber))
                            {
                                product = tmpDic[productNumber];
                            }
                            else
                            {
                                // Thread.Sleep(20);
                                await Task.Delay(20);
                            }
                            retryTimes--;
                        }
                        // 如果产品为空,则销毁图片,提示错误
                        if (null == product)
                        {
                            List<uint> pnList = tmpDic.Keys.ToList();

                            string pnStr = "";
                            if (pnList != null && pnList.Count > 0)
                            {
                                pnStr = string.Join(",", pnList);
                            }

                            //LogAsync(DateTime.Now, LogLevel.Error, $"{camera.Name} 未找到产品,编号:{productNumber},队列{index}数量:{tmpDic.Count},列表:{pnStr}");
                            localImageSet.Dispose();
                            this.BeginInvoke(new MethodInvoker(delegate ()
                            {
                                int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y;

                                richTextBox1.AppendText(productNumber + "提前推出" + camera.CameraName);

                                // 设置回原来的滚动位置
                                richTextBox1.SelectionStart = richTextBox1.TextLength;
                                richTextBox1.ScrollToCaret();
                            }));
                            //重新生成实例 销毁之前的实例

                            using (StreamWriter sw = new StreamWriter("D://123log.txt", true, Encoding.UTF8))
                            {
                                sw.WriteLine(productNumber + "提前推出" + camera.CameraName);
                            }
                            return;
                        }

                        // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 找到产品{productNumber},队列{index}数量:{tmpDic.Count}");

                        if (!_cameraRelatedDetectionDict.ContainsKey(camera.CameraName))
                        {
                            localImageSet.Dispose();
                            this.BeginInvoke(new MethodInvoker(delegate ()
                            {
                                int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y;

                                richTextBox1.AppendText(productNumber + "提前推出" + camera.CameraName);

                                // 设置回原来的滚动位置
                                richTextBox1.SelectionStart = richTextBox1.TextLength;
                                richTextBox1.ScrollToCaret();
                            }));
                            //重新生成实例 销毁之前的实例

                            using (StreamWriter sw = new StreamWriter("D://123log.txt", true, Encoding.UTF8))
                            {
                                sw.WriteLine(productNumber + "提前推出" + camera.CameraName);
                            }
                            //  LogAsync(DateTime.Now, LogLevel.Warning, $"{camera.Name} 找到产品{productNumber},但是没有推理1");

                            return;
                        }

                        double totalTime = 0.0;
                        List<ResultState> resultStates = new List<ResultState>();
                        List<string>? detectionDict = _cameraRelatedDetectionDict[camera.CameraName];

                        for (int i = 0; i < detectionDict.Count; i++)
                        {
                            string detectionId = detectionDict[i];

                            // 1. 预处理
                            using (Mat inferenceImage = localImageSet.Clone()) // 仅在此处克隆,确保推理过程中 Mat 有独立副本
                            {
                                DetectStationResult temp1 = _visionEngine.RunInference(inferenceImage, detectionId);

                                resultStates.Add(temp1.ResultState);

                                product.ResultCollection.Add(temp1);
                            }
                        }

                        product.InferenceOne();

                        // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理完成,产品{productNumber}");

                        if (!product.InferenceFinished())
                        {
                            return;
                        }
                        ProductNum_Total++;
                        CalculateOEE();
                        this.BeginInvoke(new MethodInvoker(delegate ()
                        {
                            int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y;

                            richTextBox1.AppendText($"统计结果成功,{productNumber}  吹气!\n");

                            // 设置回原来的滚动位置
                            richTextBox1.SelectionStart = richTextBox1.TextLength;
                            richTextBox1.ScrollToCaret();
                        }));

                        #region 6. 统计产品结果

                        product.ProductResult = product.ResultCollection.Any(u => u.ResultState != ResultState.OK)
                            ? ResultState.B_NG
                            : ResultState.OK;
                        product.ProductLabelCategory = product.ProductResult.GetEnumDescription();
                        product.ProductLabel = product.ProductResult.GetEnumDescription();

                        #endregion 6. 统计产品结果

                        // 出列
                        ProductData temp = null;

                        int tryTimes = 10;
                        while (temp == null && tryTimes > 0)
                        {
                            if (tmpDic.TryRemove(productNumber, out temp))
                            {
                                break;
                            }

                            tryTimes--;
                            Thread.Sleep(5);
                        }
                        if (temp == null)
                        {
                            string logStr = $"{DateTime.Now}产品{productNumber}出列失败:true," +
                               $"当前队列产品数量:{tmpDic.Count}";
                            this.BeginInvoke(new MethodInvoker(delegate ()
                            {
                                int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y;

                                richTextBox1.AppendText(logStr);

                                // 设置回原来的滚动位置
                                richTextBox1.SelectionStart = richTextBox1.TextLength;
                                richTextBox1.ScrollToCaret();
                            }));
                        }
                        else
                        {
                            try
                            {
                                string logStr = $"{DateTime.Now}产品{productNumber}出列成功:true," +
                              $"产品结果:{temp.ProductResult.GetEnumDescription()}," +
                              $"当前队列产品数量:{tmpDic.Count}";
                                this.BeginInvoke(new MethodInvoker(delegate ()
                                {
                                    int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y;

                                    richTextBox1.AppendText(logStr);

                                    // 设置回原来的滚动位置
                                    richTextBox1.SelectionStart = richTextBox1.TextLength;
                                    richTextBox1.ScrollToCaret();
                                }));
                                //重新生成实例 销毁之前的实例
                                var saveData = temp.GetProductData();
                                using (StreamWriter sw = new StreamWriter("D://123log.txt", true, Encoding.UTF8))
                                {
                                    sw.WriteLine(logStr);
                                }
                            }
                            catch (Exception) { }
                            finally
                            {
                                // temp.Dispose();
                                temp = null;
                            }
                        }

                        // UpdateCT((float)(dtNow - _ctTime).TotalSeconds);
                        //_ctTime = dtNow;
                        // });
                    }
                    catch (Exception ex)
                    {
                        //LogAsync(DateTime.Now, LogLevel.Error, $"流程检测未捕获的异常:{ex.GetExceptionMessage()}");
                        product?.Dispose();
                    }
                }
            });
        }

        public void SetResult()
        {
            ////  detectResult.IsPreTreatDone = detectResult.VisionImageSet.PreTreatedFlag
            ////2024-02-29 目标检测不能全是NG
            //if (IsPreTreatNG || IsObjectDetectNG)
            //{
            //    return;
            //}

            //if (IsPreTreatDone && IsMLDetectDone && IsAfterTreatDone)
            //{
            //    ResultState = ResultState.OK;
            //    ResultLabel = ResultState.OK.GetEnumDescription();
            //}
        }

        private void HandleStopButton()
        {
            Cameras.Clear();
            Dectection.Clear();
            // Add the code for the "停止" button click here
            PLC.TurntableStop();
            CurrentMachine = true;
            sLDMotion.Stop();
        }

        public int UPH = 0;

        public void CalculateOEE()
        {
            TimeSpan timeSpan = DateTime.Now - startTime;

            UPH = (int)(ProductNum_Total / timeSpan.TotalHours) + 100;
            //UPM = (int)UPH / 60;
            this.BeginInvoke(new MethodInvoker(delegate ()
            {
                labuph.Text = UPH.ToString();
            }));
        }

        private void HandleResetButton()
        {
            // Add the code for the "复位" button click here
            MessageBox.Show("复位按钮按下");
        }

        private void HandleSettingsButton()
        {
            // Add the code for the "设置" button click here

            SettingWindow.Instance.Show();
        }

        private void HandleLoginButton()
        {
            // Add the code for the "登录" button click here
            LoginWindow.Instance.Owner = this;
            LoginWindow.Instance.Show();
        }

        private void splitter1_SplitterMoved(object sender, SplitterEventArgs e)
        {
        }
    }
}