using MaxwellControl.Controls;
using MaxwellControl.Tools;
using MXJM.Common.EventArgsFolder;
using MaxwellFramework.Core.Interfaces;
using MaxWellGeneralLog.Extension;
using MwFramework.ManagerService;
using MXJM.Common;
using MXJM.Common.View;
using MXJM.Common.ViewModel;
using MXJM.Logic;
using MXJM.Logic.SystemSetting;
using MXJM.Parameter.SystemSetting;
using Stylet;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using MessageBox = MaxwellControl.Controls.MessageBox;
using System.Threading;
using MwFramework.Controls.ControlCanvas.DrawingControl;
using MXJM.Logic.Operation;
using MwFramework.Controls.ControlCanvas.Model;
using Maxwell.SemiFramework.DefaultConfig.Vision;
using SemiconductorVisionAlgorithm.SemiParams;
using Point = System.Windows.Point;
using MwFramework.Device;
using MXJM.Parameter;
using MwFramework.Controls.Components;
using System.Windows.Shapes;
using Rectangle = Maxwell.SemiFramework.DefaultConfig.Vision.Rectangle;
using MXJM.Parameter.Process;
using OpenCvSharp;
using MwFramework.Controls.UIControl.Axis;
using StyletIoC;
using Microsoft.Win32;
using SemiconductorVisionAlgorithm.SemiWaferRecip;
using JM1;
using JM1Vision;

namespace MXJM.SystemSetting.ViewModel
{
    public class CameraFusionCali02AViewModel : Screen, IPage, IHandle<WaferFusionCalibrationResultEventArgs>, IHandle<CameraPatternEventArgs>
    {
        private bool _stopMotion=false;
        public string Name { get; set; } = "CameraFusionCali02ASys";

        //private AxisParameterSettingViewModel _axisParameterSettingViewModel;
        //[Inject]
        //public AxisParameterSettingViewModel AxisParameterSettingViewModel
        //{
        //    get { return _axisParameterSettingViewModel; }
        //    set
        //    {
        //        _axisParameterSettingViewModel = value;
        //        OnPropertyChanged(nameof(AxisParameterSettingViewModel));
        //    }
        //}
        private CameraAxisViewModel _cameraAxisViewModelSevice = new CameraAxisViewModel();
        public CameraAxisViewModel CameraAxisViewModelSevice
        {
            get { return _cameraAxisViewModelSevice; }
            set
            {
                _cameraAxisViewModelSevice = value;
                OnPropertyChanged(nameof(CameraAxisViewModelSevice));
            }
        }

        private ParameterHelper _parameterHelper = new ParameterHelper();
        public ParameterHelper ParameterHelper
        {
            get
            {
                return _parameterHelper;
            }
            set
            {
                _parameterHelper = value;
                OnPropertyChanged(nameof(ParameterHelper));
            }
        }

        private CameraWaferFusionCalibrationSetting _parameter = new CameraWaferFusionCalibrationSetting();
        public CameraWaferFusionCalibrationSetting Parameter
        {
            get
            {
                return _parameter;
            }
            set
            {
                _parameter = value;
                OnPropertyChanged(nameof(Parameter));
            }
        }

        private CameraWaferFusionCalibrationItem _cameraWaferFusionCalibrationItem = new CameraWaferFusionCalibrationItem();
        public CameraWaferFusionCalibrationItem CameraWaferFusionCalibrationItem
        {
            get
            {
                return _cameraWaferFusionCalibrationItem;
            }
            set
            {
                _cameraWaferFusionCalibrationItem = value;
                OnPropertyChanged(nameof(CameraWaferFusionCalibrationItem));
            }
        }
        private OriginalPointItem _originalPointItem = new OriginalPointItem();
        public OriginalPointItem OriginalPointItem
        {
            get
            {
                return _originalPointItem;
            }
            set
            {
                _originalPointItem = value;
                OnPropertyChanged(nameof(OriginalPointItem));
            }
        }

        private DelegateBase _motion = new DelegateBase();
        public DelegateBase Motion
        {
            get
            {
                return _motion;
            }
            set
            {
                _motion = value;
                OnPropertyChanged(nameof(Motion));
            }
        }

        private double _waferVerifyX = 0.0;
        public double WaferVerifyX
        {
            get
            {
                return _waferVerifyX;
            }
            set
            {
                _waferVerifyX = value;
                OnPropertyChanged(nameof(WaferVerifyX));
            }
        }

        private double _waferVerifyY = 0.0;
        public double WaferVerifyY
        {
            get
            {
                return _waferVerifyY;
            }
            set
            {
                _waferVerifyY = value;
                OnPropertyChanged(nameof(WaferVerifyY));
            }
        }

        private double _desPixelX = 0.0;
        public double DesPixelX
        {
            get
            {
                return _desPixelX;
            }
            set
            {
                _desPixelX = value;
                OnPropertyChanged(nameof(DesPixelX));
            }
        }

        private double _desPixelY = 0.0;
        public double DesPixelY
        {
            get
            {
                return _desPixelY;
            }
            set
            {
                _desPixelY = value;
                OnPropertyChanged(nameof(DesPixelY));
            }
        }

        private double _desRulerX = 0.0;
        public double DesRulerX
        {
            get
            {
                return _desRulerX;
            }
            set
            {
                _desRulerX = value;
                OnPropertyChanged(nameof(DesRulerX));
            }
        }

        private double _desRulerY = 0.0;
        public double DesRulerY
        {
            get
            {
                return _desRulerY;
            }
            set
            {
                _desRulerY = value;
                OnPropertyChanged(nameof(DesRulerY));
            }
        }

        private double x_mean_offset;
        public double X_mean_offset
        {
            get
            {
                return x_mean_offset;
            }
            set
            {
                x_mean_offset = value;
                OnPropertyChanged(nameof(X_mean_offset));
            }
        }

        private double x_deviation;
        public double X_deviation
        {
            get
            {
                return x_deviation;
            }
            set
            {
                x_deviation = value;
                OnPropertyChanged(nameof(X_deviation));
            }
        }

        private double x_max_offset;
        public double X_max_offset
        {
            get
            {
                return x_max_offset;
            }
            set
            {
                x_max_offset = value;
                OnPropertyChanged(nameof(X_max_offset));
            }
        }

        private double y_mean_offset;
        public double Y_mean_offset
        {
            get
            {
                return y_mean_offset;
            }
            set
            {
                y_mean_offset = value;
                OnPropertyChanged(nameof(Y_mean_offset));
            }
        }

        private double y_deviation;
        public double Y_deviation
        {
            get
            {
                return y_deviation;
            }
            set
            {
                y_deviation = value;
                OnPropertyChanged(nameof(Y_deviation));
            }
        }

        private double y_max_offset;
        public double Y_max_offset
        {
            get
            {
                return y_max_offset;
            }
            set
            {
                y_max_offset = value;
                OnPropertyChanged(nameof(Y_max_offset));
            }
        }

        private bool _isUseModel = true;
        public bool IsUseModel
        {
            get
            {
                return _isUseModel;
            }
            set
            {
                _isUseModel = value;
                OnPropertyChanged(nameof(IsUseModel));
            }
        }

        private CameraType _CameraTypeVM = CameraType.Position;
        /// <summary>
        /// 相机类型
        /// </summary>
        public CameraType CameraTypeVM
        {
            get { return _CameraTypeVM; }
            set
            { SetAndNotify(ref _CameraTypeVM, value); }
        }

        private Dictionary<int, List<FusionPoint>> _circlePointDic = new Dictionary<int, List<FusionPoint>>();
        private FusionPoint[,] _movePoints = null;

        private Dispatcher _currentDispatcher;
        private IParamList _paramList;
        private GlobalDeviceService _gs;
        private SafeAxisMotion _safeAxisMotion;
        private VisionOperation _visionOperation;
        private ModelEditWindow _modelEditWindow;
        private string calibDataFilePath = System.AppDomain.CurrentDomain.BaseDirectory + @"CalibData";


        public CameraFusionCali02AViewModel(GlobalDeviceService gs, IParameterManager paraService)
        {
            _currentDispatcher = Dispatcher.CurrentDispatcher;
            _paramList = paraService as IParamList;
            _gs = gs;

            _safeAxisMotion = IoC.Get<SafeAxisMotion>();
            _visionOperation = IoC.Get<VisionOperation>();

            _parameter = _paramList.GetParameter<CameraWaferFusionCalibrationSetting>();
            //_cameraWaferFusionCalibrationItem = _parameter.CameraWaferFusionCalibrationItem;
            _originalPointItem = _parameter.OriginalPointItem;

            _modelEditWindow = new ModelEditWindow();
            _modelEditWindow.Owner = Application.Current.MainWindow;
            _modelEditWindow.Closing -= ModelEditWindow_Closing;
            _modelEditWindow.Closing += ModelEditWindow_Closing;
            CameraAxisViewModelSevice.CameraAxisDevices = _gs.CameraAxisDevicesWS;
            _motion = (DelegateBase)TaskManager.Instance.GetIntance(typeof(CameraFusionCalibrationMotion02A));
        }

        private void ModelEditWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            e.Cancel = true;
            _modelEditWindow.Hide();
        }

        public void viewLoad()
        {
            try
            {
                //IParameterManager paraService = IoC.Get<IParameterManager>();
                //_paramList = paraService as IParamList;
                Parameter = _paramList.GetParameter<CameraWaferFusionCalibrationSetting>();
                CameraWaferFusionCalibrationItem = _parameter.CameraWaferFusionCalibrationItem;
                OriginalPointItem = _parameter.OriginalPointItem;
                IniAxisCheckParam();

                ParameterHelper.RaiseValueAccept();

                var eventAggregator = IoC.Get<IEventAggregator>();
                eventAggregator.Unsubscribe(this);
                eventAggregator.Subscribe(this);
            }
            catch (Exception ex)
            {
                LogManager.LogSysError(ex, true);
            }
        }
        public void viewUnLoad()
        {
            var eventAggregator = IoC.Get<IEventAggregator>();
            eventAggregator.Unsubscribe(this);
        }
        //protected override void OnDeactivate()
        //{
        //    base.OnDeactivate();
        //    var eventAggregator = IoC.Get<IEventAggregator>();
        //    eventAggregator.Unsubscribe(this);
        //}

        public void btnSave()
        {
            if (MessageBox.Show("是否保存", null, "确认保存", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK)
            {
                try
                {
                    Parameter.Write();
                    AxisCheckSetting.Write();
                    ParameterHelper.RaiseValueAccept();
                }
                catch (Exception ex)
                {
                    LogManager.LogSysError(ex, true);
                    
                }
            }
        }

        public void btnSetGantryPosition1()
        {
            if (MessageBox.Show("是否使用当前位置", null, "确认", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK)
            {
                try
                {
                    OriginalPointItem.Gantry1X = _gs.Axis_X11.State.ActualPos;
                    OriginalPointItem.Gantry1Y = _gs.Axis_Y11.State.ActualPos;
                }
                catch (Exception ex)
                {
                    LogManager.LogSysError(ex, true);
                    
                }
            }
        }
        public void btnMoveGantryPosition1()
        {
            if (MessageBox.Show("是否移动到该点", null, "确认", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK)
            {

                Task.Factory.StartNew(() =>
                {
                    try
                    {
                        _safeAxisMotion.SafeMovePHS(OriginalPointItem.Gantry1X, OriginalPointItem.Gantry1Y, true, false, isCalib: true);
                    }
                    catch (Exception ex)
                    {
                        LogManager.LogSysError(ex, true);
                        
                    }
                });

            }
        }
        public void btnSetGantryPosition2()
        {
            if (MessageBox.Show("是否使用当前位置", null, "确认", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK)
            {
                try
                {
                    OriginalPointItem.Gantry2X = _gs.Axis_X21.State.ActualPos;
                    OriginalPointItem.Gantry2Y = _gs.Axis_Y21.State.ActualPos;
                }
                catch (Exception ex)
                {
                    LogManager.LogSysError(ex, true);
                    
                }
            }
        }
        public void btnMoveGantryPosition2()
        {
            if (MessageBox.Show("是否移动到该点", null, "确认", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK)
            {
                Task.Factory.StartNew(() =>
                {
                    try
                    {
                        _safeAxisMotion.SafeMoveWS(OriginalPointItem.Gantry2X, OriginalPointItem.Gantry2Y, true, false, isCalib: true);
                    }
                    catch (Exception ex)
                    {
                        LogManager.LogSysError(ex, true);
                        
                    }
                });

            }
        }

        public void btnSetCameraPosition()
        {
            if (MessageBox.Show("是否使用当前位置", null, "确认", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK)
            {
                try
                {
                    CameraWaferFusionCalibrationItem.CameraX = _gs.Axis_X11.State.ActualPos;
                    CameraWaferFusionCalibrationItem.CameraY = _gs.Axis_Y11.State.ActualPos;
                    //CameraWaferFusionCalibrationItem.WaferStartX = _gs.Axis_X11.State.ActualPos;
                    //CameraWaferFusionCalibrationItem.WaferStartY = _gs.Axis_Y11.State.ActualPos;
                }
                catch (Exception ex)
                {
                    LogManager.LogSysError(ex, true);
                    
                }
            }
        }

        public void btnMoveCameraPosition()
        {
            if (MessageBox.Show("是否移动到该点", null, "确认", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK)
            {

                Task.Factory.StartNew(() =>
                {
                    try
                    {
                        _safeAxisMotion.SafeMovePHS(CameraWaferFusionCalibrationItem.CameraX, _gs.Axis_Y11.State.ActualPos, true, false, isCalib: true);
                    }
                    catch (Exception ex)
                    {
                        LogManager.LogSysError(ex, true);
                        
                    }
                });

            }
        }

        public void btnSetWaferStartPosition()
        {
            if (MessageBox.Show("是否使用当前位置", null, "确认", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK)
            {
                Task.Factory.StartNew(() =>
                {
                    try
                    {
                        CameraWaferFusionCalibrationItem.WaferStartX = _gs.Axis_X21.State.ActualPos;
                        CameraWaferFusionCalibrationItem.WaferStartY = _gs.Axis_Y21.State.ActualPos;
                    }
                    catch (Exception ex)
                    {
                        LogManager.LogSysError(ex, true);
                        
                    }
                });

            }
        }
        public void btnMoveWaferStartPosition()
        {
            if (MessageBox.Show("是否移动到该点", null, "确认", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK)
            {
                try
                {
                    _safeAxisMotion.SafeMoveWS(CameraWaferFusionCalibrationItem.WaferStartX, CameraWaferFusionCalibrationItem.WaferStartY, true, false, isCalib: true);
                }
                catch (Exception ex)
                {
                    LogManager.LogSysError(ex, true);
                    
                }
            }
        }
        public void btnMakeModel()
        {
            try
            {
                if (_modelEditWindow.IsActive)
                {
                    if (_modelEditWindow.WindowState == WindowState.Minimized)
                    {
                        _modelEditWindow.WindowState = WindowState.Normal;
                    }
                }


                string modelFileName = CameraWaferFusionCalibrationItem.ModelPath;
                string path = System.AppDomain.CurrentDomain.BaseDirectory + modelFileName;
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                if (_modelEditWindow.MatchTemplateViewModel.Service.Cameras != null && _modelEditWindow.MatchTemplateViewModel.Service.Cameras.Count > 0)
                {
                    _modelEditWindow.MatchTemplateViewModel.Service.SelectCameraIndex = _modelEditWindow.MatchTemplateViewModel.Service.Cameras.FindIndex(w => w.Camera.Id == _gs.Camera_Extend.Id);
                }
                _modelEditWindow.MatchTemplateViewModel.ModelViewItem.TemplatePath = path;
                _modelEditWindow.ShowDialog();
            }
            catch (Exception ex)
            {
                LogManager.LogSysError(ex, true);
                
            }
        }
        public void btnMoveWafer()
        {
            CameraWaferFusionCalibrationItem.VerityrealPointRealPoints = new List<Point>();
            List<Point> points = new List<Point>();
            Task.Run(() =>
            {
                for (var i = 0; i < _cameraWaferFusionCalibrationItem.WaferVerityCountY; i++)
                {
                    for (var j = 0; j < _cameraWaferFusionCalibrationItem.WaferVerityCountX; j++)
                    {
                        if (_stopMotion)
                        {
                            _stopMotion = false;
                            return;
                        }
                        double yPos = _cameraWaferFusionCalibrationItem.WaferStartVerifyY + i * _cameraWaferFusionCalibrationItem.WaferVerityStep;
                        double xPos;
                        if (i % 2 == 0)
                        {
                            xPos = _cameraWaferFusionCalibrationItem.WaferStartVerifyX + j * _cameraWaferFusionCalibrationItem.WaferVerityStep;
                        }
                        else
                        {
                            xPos = _cameraWaferFusionCalibrationItem.WaferStartVerifyX + (_cameraWaferFusionCalibrationItem.WaferVerityCountX - j - 1) * _cameraWaferFusionCalibrationItem.WaferVerityStep;
                        }
                        points.Add(new Point(xPos, yPos));
                        _safeAxisMotion.SafeMoveWS(xPos, yPos, isCalib: true);
                        if (ApproachPointWS())
                        {
                            CameraWaferFusionCalibrationItem.WSVerityApproachXpos = _gs.Axis_X21.State.ActualPos;
                            CameraWaferFusionCalibrationItem.WSVerityApproachYpos = _gs.Axis_Y21.State.ActualPos;
                            Point ruler = new Point(CameraWaferFusionCalibrationItem.WSVerityApproachXpos, CameraWaferFusionCalibrationItem.WSVerityApproachYpos);
                            Point real = _visionOperation.GetRealByRuler(_gs.Camera_ExtendWS.Id, ruler);
                            CameraWaferFusionCalibrationItem.VerityrealPointRealPoints.Add(new Point(real.X, real.Y));
                        }
                        else
                        {
                            MessageBox.Show("逼近失败！");
                        }
                    }
                }
                MessageBox.Show("飞拍结束");
            });
        }
        public void btnVerityWafer()
        {
            if (CameraWaferFusionCalibrationItem.VerityrealPointRealPoints != null && CameraWaferFusionCalibrationItem.VerityrealPointRealPoints.Count > 0)
            {
                if (MessageBox.Show("是否已移动到Pad位置，确认开始验证", null, "确认", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK)
                {
                    Task.Factory.StartNew(() =>
                    {
                        List<SemiconductorVisionAlgorithm.SemiParams.Point> WSrulerThen = new List<SemiconductorVisionAlgorithm.SemiParams.Point>();
                        List<SemiconductorVisionAlgorithm.SemiParams.Point> WSrulerNow = new List<SemiconductorVisionAlgorithm.SemiParams.Point>();
                        Point padReal = _visionOperation.GetRealByRuler(_gs.Camera_Extend.Id, new Point(_gs.Axis_X11.State.ActualPos, _gs.Axis_Y11.State.ActualPos));
                        for (var i = 0; i < CameraWaferFusionCalibrationItem.VerityrealPointRealPoints.Count; i++)
                        {
                            if (_stopMotion)
                            {
                                _stopMotion = false;
                                return;
                            }
                            SemiconductorVisionAlgorithm.SemiParams.Point rulerPoint = new SemiconductorVisionAlgorithm.SemiParams.Point();
                            JM1Vision.JM1Manager.Instance.get_ws_pos(_gs.Camera_Extend.Id, _gs.Camera_ExtendWS.Id, new SemiconductorVisionAlgorithm.SemiParams.Point(padReal.X, padReal.Y), new SemiconductorVisionAlgorithm.SemiParams.Point(CameraWaferFusionCalibrationItem.VerityrealPointRealPoints[i].X, CameraWaferFusionCalibrationItem.VerityrealPointRealPoints[i].Y), out rulerPoint);
                            WSrulerThen.Add(new SemiconductorVisionAlgorithm.SemiParams.Point(rulerPoint.X, rulerPoint.Y));
                            _safeAxisMotion.SafeMoveWS(rulerPoint.X, rulerPoint.Y, isCalib: true);
                            if (ApproachPointWS())
                            {
                                WSrulerNow.Add(new SemiconductorVisionAlgorithm.SemiParams.Point(_gs.Axis_X21.State.ActualPos, _gs.Axis_Y21.State.ActualPos));
                            }
                            else
                            {
                                MessageBox.Show("逼近失败！");
                            }
                        }
                        string filePath = System.AppDomain.CurrentDomain.BaseDirectory + @"CalibData";
                        JM1Vision.JM1Manager.Instance.pos_verify(filePath, WSrulerThen, WSrulerNow);
                        MessageBox.Show("验证完成！");
                    });
                }
            }
            else
            {
                MessageBox.Show("请先执行飞拍！");
                return;
            }
        }

        public void btnStopVerityWafer()
        {
            try
            {
                if (MessageBox.Show("是否停止", null, "确认停止", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK)
                {
                    _stopMotion = true;
                }
            }
            catch (Exception ex)
            {
                LogManager.LogSysError(ex, true);

            }
        }
        public void btnMoveToStartPoint()
        {
            _safeAxisMotion.SafeMoveXY(_gs.Axis_X21, _gs.Axis_Y21, CameraWaferFusionCalibrationItem.WaferStartVerifyX, CameraWaferFusionCalibrationItem.WaferStartVerifyY);
        }
        public void btnMoveToCenter()
        {
            Task.Factory.StartNew(() =>
            {
                try
                {
                    //if (IsUseModel)
                    //{
                    //    //VisionOperation visionOperation = IoC.Get<VisionOperation>();

                    //    //string modelFileName = _cameraWaferFusionCalibrationItem.ModelPath;
                    //    //string path = System.AppDomain.CurrentDomain.BaseDirectory + modelFileName;

                    //    ////相机拍照
                    //    //visionOperation.ApproachPoint(_gs.Axis_X11, _gs.Axis_Y11, path, out Point point, 1);
                    //}
                    //else
                    //{
                    if (ApproachPointWS(1))
                    {
                        CameraWaferFusionCalibrationItem.WaferStartVerifyX = _gs.Axis_X21.State.ActualPos;
                        CameraWaferFusionCalibrationItem.WaferStartVerifyY = _gs.Axis_Y21.State.ActualPos;
                        MessageBox.Show("中心对齐完成");
                    }
                    else
                    {
                        MessageBox.Show("逼近失败！");
                    }
                    //}

                }
                catch (Exception ex)
                {
                    LogManager.LogSysError(ex, true);
                    
                }
            });
        }
        private bool ApproachPointWS(int approachTime=10)
        {
            string modelFileName = _cameraWaferFusionCalibrationItem.ModelPath;
            string path = System.AppDomain.CurrentDomain.BaseDirectory + modelFileName;
            Rectangle1 r = GetRectangle();

            VisionOperation visionOperation = IoC.Get<VisionOperation>();
            //相机拍照
            return visionOperation.ApproachPointCircle(_gs.Camera_ExtendWS, _gs.Axis_X21, _gs.Axis_Y21, path, r, out System.Windows.Point point, approachTime);
        }

        private bool FindPointWSCircle()
        {
            string modelFileName = _cameraWaferFusionCalibrationItem.ModelPath;
            string path = System.AppDomain.CurrentDomain.BaseDirectory + modelFileName;
            Rectangle1 r = GetRectangle();

            VisionOperation visionOperation = IoC.Get<VisionOperation>();
            //相机拍照
            return visionOperation.FindPointWSCircle(_gs.Camera_ExtendWS, _gs.Axis_X21, _gs.Axis_Y21, path, r, out System.Windows.Point point,1);
        }

        private Rectangle1 GetRectangle()
        {
            var region = CameraAxisViewModelSevice.Regions;
            Rectangle rectangle = null;
            Rectangle1 r = null;
            if (region != null && region.Count > 0)
            {
                RectRegion rect = region[0].Region as RectRegion;
                double start_x = rect.CenterPoint.X - rect.Width / 2;
                double start_y = rect.CenterPoint.Y - rect.Height / 2;
                double end_x = rect.CenterPoint.X + rect.Width / 2;
                double end_y = rect.CenterPoint.Y + rect.Height / 2;
                rectangle = new Rectangle(new System.Windows.Point(start_y, start_x), new System.Windows.Point(end_y, end_x));
                r = new Rectangle1();
                r.Start_X = rectangle.StartPoint.X;
                r.Start_Y = rectangle.StartPoint.Y;
                r.End_X = rectangle.EndPoint.X;
                r.End_Y = rectangle.EndPoint.Y;
            }
            else
            {
                throw new Exception("请添加矩形！");
            }

            return r;
        }

        public void btnMoveWSCalibPosPosition()
        {
            Task.Factory.StartNew(() =>
            {
                try
                {
                    _safeAxisMotion.SafeAbsoluteMove(_gs.Axis_X11, CameraWaferFusionCalibrationItem.WSPlatCalibXPos, block: false);
                    _safeAxisMotion.SafeMoveWS(CameraWaferFusionCalibrationItem.WSApproachXPos, CameraWaferFusionCalibrationItem.WSApproachYPos, isBlock: false);
                }
                catch (Exception ex)
                {
                    LogManager.LogSysError(ex, true);
                    
                }
            });
        }

        public void BtnMoveX1ToCalibPos()
        {
            Task.Factory.StartNew(() =>
            {
                try
                {
                    _safeAxisMotion.SafeAbsoluteMove(_gs.Axis_X11, CameraWaferFusionCalibrationItem.WSPlatCalibXPos);
                }
                catch (Exception ex)
                {
                    LogManager.LogSysError(ex, true);
                    
                }
            });
        }

        public void btnApproachCalibPos()
        {
            Task.Factory.StartNew(() =>
            {
                try
                {
                    if (ApproachPointWS())
                    {
                        CameraWaferFusionCalibrationItem.WSApproachXPos = _gs.Axis_X21.State.ActualPos;
                        CameraWaferFusionCalibrationItem.WSApproachYPos = _gs.Axis_Y21.State.ActualPos;
                        MessageBox.Show($"逼近值，X2:{CameraWaferFusionCalibrationItem.WSApproachXPos},Y2:{CameraWaferFusionCalibrationItem.WSApproachYPos}");
                    }
                    else
                    {
                        MessageBox.Show("逼近失败！");
                    }
                }
                catch (Exception ex)
                {
                    LogManager.LogSysError(ex, true);
                    
                }
            });
        }

        public void btnGotoCalibPos()
        {
            Task.Factory.StartNew(() =>
            {
                try
                {
                    if (FindPointWSCircle())
                    {
                        CameraWaferFusionCalibrationItem.WSApproachXPos = _gs.Axis_X21.State.ActualPos;
                        CameraWaferFusionCalibrationItem.WSApproachYPos = _gs.Axis_Y21.State.ActualPos;
                        CameraWaferFusionCalibrationItem.CenterX = _gs.Axis_X21.State.ActualPos;
                        CameraWaferFusionCalibrationItem.CenterY = _gs.Axis_Y21.State.ActualPos;
                        MessageBox.Show($"对齐值，X2:{CameraWaferFusionCalibrationItem.WSApproachXPos},Y2:{CameraWaferFusionCalibrationItem.WSApproachYPos}");
                    }
                    else
                    {
                        MessageBox.Show("对齐失败！");
                    }
                }
                catch (Exception ex)
                {
                    LogManager.LogSysError(ex, true);
                    
                }
            });
        }

        public void BtnCalculateCameraPosition()
        {
            try
            {
                //起点覆盖标定范围，起点往负方向6mm
                int offset = -10; 
                double X2MinPos = 0;
                var device = IoC.Get<GlobalDeviceService>();
                device.Axis_X21.GetSoftMel(ref X2MinPos);
                //var moveParX2 = AxisParameterSettingViewModel.AxisListModel.Find(p => p.AxisNum == device.Axis_X21.AxisIndex && p.AxisName == device.Axis_X21.Name);
                //if(moveParX2!=null)
                //{
                var delx = CameraWaferFusionCalibrationItem.WSApproachXPos - X2MinPos + offset;
                    CameraWaferFusionCalibrationItem.CameraX = CameraWaferFusionCalibrationItem.WSPlatCalibXPos - delx;
                //}
            }
            catch (Exception ex)
            {
                LogManager.LogSysError(ex, true);
                
            }
        }

        public void BtnCalculateWSPosition()
        {
            try
            {
                //起点覆盖标定范围，起点往负方向6mm
                int offset = -10;
                double X2MinPos = 0;
                var device = IoC.Get<GlobalDeviceService>();
                device.Axis_X21.GetSoftMel(ref X2MinPos);
                //var moveParX2 = AxisParameterSettingViewModel.AxisListModel.Find(p => p.AxisNum == device.Axis_X21.AxisIndex && p.AxisName == device.Axis_X21.Name);
                //if (moveParX2 != null)
                //{
                var delx = CameraWaferFusionCalibrationItem.WSApproachXPos - X2MinPos + offset;
                    CameraWaferFusionCalibrationItem.CameraX = CameraWaferFusionCalibrationItem.WSPlatCalibXPos - delx;
                //}
                double x11Offset = CameraWaferFusionCalibrationItem.CameraX - CameraWaferFusionCalibrationItem.WSPlatCalibXPos;
                CameraWaferFusionCalibrationItem.WaferStartX = CameraWaferFusionCalibrationItem.WSApproachXPos + x11Offset;
                CameraWaferFusionCalibrationItem.WaferStartY = CameraWaferFusionCalibrationItem.WSApproachYPos;
            }
            catch (Exception ex)
            {
                LogManager.LogSysError(ex, true);
                
            }
        }


        public void btnMovePosition()
        {
            if (MessageBox.Show("是否移动到该点", null, "确认", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK)
            {
                Task.Factory.StartNew(() =>
                {
                    try
                    {
                        double x1 = CameraWaferFusionCalibrationItem.SelectedAxisAndPixelPointItem.AxisX1;
                        double y1 = CameraWaferFusionCalibrationItem.SelectedAxisAndPixelPointItem.AxisY1;
                        double x2 = CameraWaferFusionCalibrationItem.SelectedAxisAndPixelPointItem.AxisX2;
                        double y2 = CameraWaferFusionCalibrationItem.SelectedAxisAndPixelPointItem.AxisY2;
                        _safeAxisMotion.SafeMovePHSAndWS(x1, y1, x2, y2, true, false, isCalib: true);
                    }
                    catch (Exception ex)
                    {
                        LogManager.LogSysError(ex, true);
                        
                    }

                });

            }
        }

        public void btnRecognize()
        {

            Task.Factory.StartNew(() =>
            {
                try
                {
                    string modelFileName = _cameraWaferFusionCalibrationItem.ModelPath;
                    string path = System.AppDomain.CurrentDomain.BaseDirectory + modelFileName;
                    _visionOperation.ApproachPoint(_gs.Axis_X11, _gs.Axis_Y11, path, out Point point, 1);
                }
                catch (Exception ex)
                {
                    LogManager.LogSysError(ex, true);
                    
                }

            });
        }



        public void btnStart()
        {
            try
            {
                if (MessageBox.Show("是否开始", null, "确认开始", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK)
                {
                    CameraWaferFusionCalibrationItem.AxisAndPixelPointItemList.Clear();
                    FusionCalib(false);
                }

            }
            catch (Exception ex)
            {
                LogManager.LogSysError(ex, true);
                
            }
        }

        private void FusionCalib(bool isRecheck, bool isAsyn = true)
        {
            Motion = (DelegateBase)TaskManager.Instance.GetIntance(typeof(CameraFusionCalibrationMotion02A));
            CameraFusionCalibrationMotion02A cameraFusionCalibration = Motion as CameraFusionCalibrationMotion02A;
            if (cameraFusionCalibration != null)
            {
                cameraFusionCalibration.Rectangle = GetRectangle();
            }
            if(CameraWaferFusionCalibrationItem.UseCircleCalib)
            {
                _movePoints= GenerateCircleDic();
            }
            if (isAsyn)
                TaskManager.Instance.AsyncStart(Motion, new object[] { isRecheck, _movePoints });
            else Motion.Run(IsUseModel);

        }

        public void btnVarify()
        {

            CameraWaferFusionCalibrationItem.AxisAndPixelPointItemList.Clear();
            Task.Run(() =>
            {
                try
                {
                    //再跑一遍
                    FusionCalib(true, false);

                    if (CameraWaferFusionCalibrationItem.AxisAndPixelPointItemList == null || CameraWaferFusionCalibrationItem.AxisAndPixelPointItemList.Count == 0)
                    {
                        MessageBox.Show("结果列表为空");
                        return;
                    }
                    List<Point> realPointList = new List<Point>();
                    List<Point> hsRulerPointList = new List<Point>();
                    List<Point> wsRulerPointList = new List<Point>();

                    foreach (var item in CameraWaferFusionCalibrationItem.AxisAndPixelPointItemList)
                    {
                        Point ruler = _visionOperation.GetRulerByPixel(_gs.Camera_Extend.Id, new Point(item.AxisX1, item.AxisY1), new Point(item.PixelX, item.PixelY));
                        Point ruler1 = _visionOperation.GetRulerByPixel(_gs.Camera_ExtendWS.Id, new Point(item.AxisX2, item.AxisY2), new Point(item.PixelX, item.PixelY));
                        Point real = _visionOperation.GetRealByRuler(_gs.Camera_Extend.Id, ruler);
                        realPointList.Add(real);
                        hsRulerPointList.Add(new Point(ruler.X, ruler.Y));
                        wsRulerPointList.Add(new Point(ruler1.X, ruler1.Y));
                    }


                    string filePath = System.AppDomain.CurrentDomain.BaseDirectory + @"CalibData";
                    //JM1Vision.JM1Manager.Instance.Save(filePath);

                    //if (JM1Vision.JM1Manager.Instance.straight_verify(_visionOperation.ConvertToVisonPointList(hsRulerPointList).Select(x => x.X).ToList(),
                    //        _visionOperation.ConvertToVisonPointList(wsRulerPointList), filePath))
                    //{
                    //    MessageBox.Show("验证完成！");
                    //}
                    //else
                    //{
                    //    MessageBox.Show("验证失败！");
                    //}

                    X_mean_offset = x_mean_offset;
                    X_deviation = x_deviation;
                    X_max_offset = x_max_offset;
                    Y_mean_offset = y_mean_offset;
                    Y_deviation = y_deviation;
                    Y_max_offset = y_max_offset;
                }
                catch (Exception ex)
                {
                    LogManager.LogSysError(ex, true);
                    
                }
            });

        }

        public void btnStop()
        {
            try
            {
                if (MessageBox.Show("是否停止", null, "确认停止", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK)
                {
                    Motion.Cancel();
                    _stopMotion= true;
                }

            }
            catch (Exception ex)
            {
                LogManager.LogSysError(ex, true);
                
            }
        }

        public void btnFix()
        {
            try
            {
                if (CameraWaferFusionCalibrationItem.AxisAndPixelPointItemList == null || CameraWaferFusionCalibrationItem.AxisAndPixelPointItemList.Count == 0)
                {
                    MessageBox.Show("结果列表为空");
                    return;
                }
                List<Point> realPointList = new List<Point>();
                List<Point> hsRulerPointList = new List<Point>();
                List<Point> wsRulerPointList = new List<Point>();

                foreach (var item in CameraWaferFusionCalibrationItem.AxisAndPixelPointItemList)
                {
                    Point ruler = _visionOperation.GetRulerByPixel(_gs.Camera_Extend.Id, new Point(item.AxisX1, item.AxisY1), new Point(item.PixelX, item.PixelY));
                    Point ruler1 = _visionOperation.GetRulerByPixel(_gs.Camera_ExtendWS.Id, new Point(item.AxisX2, item.AxisY2), new Point(item.PixelX, item.PixelY));
                    Point real = _visionOperation.GetRealByRuler(_gs.Camera_Extend.Id, ruler);
                    realPointList.Add(real);
                    hsRulerPointList.Add(new Point(ruler.X, ruler.Y));
                    wsRulerPointList.Add(new Point(ruler1.X, ruler1.Y));
                }

                SemiconductorVisionAlgorithm.SemiParams.Point ini_wsPos = new SemiconductorVisionAlgorithm.SemiParams.Point(CameraWaferFusionCalibrationItem.WSApproachXPos,
                    CameraWaferFusionCalibrationItem.WSApproachYPos);
                //JM1Vision.JM1Manager.Instance.cal_interpolate_affine(CameraWaferFusionCalibrationItem.WSPlatCalibXPos, ini_wsPos,
                //     _visionOperation.ConvertToVisonPointList(hsRulerPointList).Select(x => x.X).ToList(), _visionOperation.ConvertToVisonPointList(wsRulerPointList));


                string filePath = System.AppDomain.CurrentDomain.BaseDirectory + @"CalibData";
                JM1Vision.JM1Manager.Instance.Save(filePath);


            }
            catch (Exception ex)
            {
                LogManager.LogSysError(ex, true);
                
            }
        }

        private double _dieRealX;
        private double _dieRealY;
        public void btnSetDiePosition()
        {
            if (MessageBox.Show("是否使用当前位置", null, "确认", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK)
            {
                try
                {
                    double dieRulerX = _gs.Axis_X21.State.ActualPos;
                    double dieRulerY = _gs.Axis_Y21.State.ActualPos;
                    Rectangle1 rectangle = GetRectangle();
                    _visionOperation.GetCirclePixCenter(_gs.Camera_ExtendWS, calibDataFilePath, rectangle, out Point circleCenterPix);
                    Point pointRuler = _visionOperation.GetRulerByPixel(_gs.Camera_ExtendWS.Id, new Point(dieRulerX, dieRulerY), circleCenterPix);
                    Point realPoint = _visionOperation.GetRealByRuler(_gs.Camera_ExtendWS.Id, pointRuler);

                    _dieRealX = realPoint.X;
                    _dieRealY = realPoint.Y;
                }
                catch (Exception ex)
                {
                    LogManager.LogSysError(ex, true);
                    
                }
            }
        }

        private double _padRealX;
        private double _padRealY;
        public void btnSetPadPosition()
        {
            if (MessageBox.Show("是否使用当前位置", null, "确认", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK)
            {
                try
                {
                    double padRulerX = _gs.Axis_X11.State.ActualPos;
                    double padRulerY = _gs.Axis_Y11.State.ActualPos;
                    Point realPoint = _visionOperation.GetRealByRuler(_gs.Camera_Extend.Id, new Point(padRulerX, padRulerY));

                    _padRealX = realPoint.X;
                    _padRealY = realPoint.Y;
                }
                catch (Exception ex)
                {
                    LogManager.LogSysError(ex, true);
                    
                }
            }
        }

        public void btnCalculate()
        {
            try
            {
                JM1Vision.JM1Manager.Instance.get_ws_pos(_gs.Camera_Extend.Id, _gs.Camera_ExtendWS.Id,
                    _visionOperation.ConvertToVisonPoint(new Point(_padRealX, _padRealY)),
                    _visionOperation.ConvertToVisonPoint(new Point(_dieRealX, _dieRealY)),
                     out SemiconductorVisionAlgorithm.SemiParams.Point uppt);

                WaferVerifyX = uppt.X - _gs.Axis_X21.State.ActualPos;
                WaferVerifyY = uppt.Y - _gs.Axis_Y21.State.ActualPos;
            }
            catch (Exception ex)
            {
                LogManager.LogSysError(ex, true);
                
            }
        }

        public void btnMoveToVerifyPoint()
        {
            if (MessageBox.Show("是否移动到该点", null, "确认", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK)
            {
                try
                {
                    _safeAxisMotion.SafeRelativeMove(_gs.Axis_X21, WaferVerifyX, false);
                    _safeAxisMotion.SafeRelativeMove(_gs.Axis_Y21, WaferVerifyY, false);
                }
                catch (Exception ex)
                {
                    LogManager.LogSysError(ex, true);
                    
                }
            }
        }

        private MwCameraExtend GetCameraType()
        {
            MwCameraExtend cameraExtend = _gs.Camera_Extend;
            if (this.CameraTypeVM == CameraType.Position)
            {
                cameraExtend = this._gs.Camera_Extend;
            }
            else if (this.CameraTypeVM == CameraType.WS)
            {
                cameraExtend = this._gs.Camera_ExtendWS;
            }
            else
            {
                MessageBox.Show("请选择相机类型");
            }
            return cameraExtend;
        }

        public void btnCameraTest()
        {
            Task.Factory.StartNew(() =>
            {
                try
                {
                    MwCameraExtend mwCamera = GetCameraType();
                    IAxis axisX = _gs.Axis_X11;
                    IAxis axisY = _gs.Axis_Y11;
                    if (mwCamera.Name== "定位相机")
                    {
                        axisX = _gs.Axis_X11;
                        axisY = _gs.Axis_Y11;
                    }
                    else if (mwCamera.Name == "虚拟定位相机")
                    {
                        axisX = _gs.Axis_X21;
                        axisY = _gs.Axis_Y21;
                    }

                        var region = CameraAxisViewModelSevice.Regions;
                    Rectangle rectangle = null;
                    if (region != null && region.Count > 0)
                    {
                        RectRegion rect = region[0].Region as RectRegion;
                        double start_x = rect.CenterPoint.X - rect.Width / 2;
                        double start_y = rect.CenterPoint.Y - rect.Height / 2;
                        double end_x = rect.CenterPoint.X + rect.Width / 2;
                        double end_y = rect.CenterPoint.Y + rect.Height / 2;
                        rectangle = new Rectangle(new Point(start_y, start_x), new Point(end_y, end_x));
                    }
                    else
                    {
                        MessageBox.Show("请先在相机视野中绘制矩形框");
                    }

                    VisionOperation visionOperation = IoC.Get<VisionOperation>();
                    //相机拍照

                    string filePath = System.AppDomain.CurrentDomain.BaseDirectory + @"CalibData";
                    visionOperation.FindCircle(mwCamera, rectangle, filePath,
                            out double pixelX, out double pixelY);

                    Point ruler = new Point(axisX.State.ActualPos, axisY.State.ActualPos);
                    Point real = visionOperation.GetRealByPixel(mwCamera.Id, ruler, new Point(pixelX, pixelY));
                    DesPixelX = real.X;
                    DesPixelY = real.Y;
                    Point ruler1 = visionOperation.GetRulerByReal(mwCamera.Id, real);
                    DesRulerX = ruler1.X;
                    DesRulerY = ruler1.Y;
                }
                catch (Exception ex)
                {
                    LogManager.LogSysError(ex, true);
                    
                }
            });
        }

        public void MovePosAction()
        {
            try
            {
                _cameraAxisViewModelSevice.MovePosAction();
            }
            catch (Exception ex)
            {
                LogManager.LogSysError(ex, true);
                
            }
        }

        public void Handle(WaferFusionCalibrationResultEventArgs message)
        {
            _currentDispatcher.Invoke((Action)delegate
            {
                try
                {
                    CameraWaferFusionCalibrationItem.AxisAndPixelPointItemList.Add(message.AxisAndPixelPointItem);

                }
                catch (Exception)
                {

                }

            });
        }

        public void Handle(CameraPatternEventArgs message)
        {
            _currentDispatcher.Invoke((Action)delegate
            {
                CameraAxisViewModelSevice.CameraAxisDevices.Shapes.Clear();

                foreach (var item in message.Results)
                {
                    CameraAxisViewModelSevice.CameraAxisDevices.Shapes.Add(new RectShapeDrawing()
                    {
                        X = item.Rectangle.StartPoint.Y,
                        Y = item.Rectangle.StartPoint.X,
                        X1 = item.Rectangle.EndPoint.Y,
                        Y1 = item.Rectangle.EndPoint.X
                    });

                    CameraAxisViewModelSevice.CameraAxisDevices.Shapes.Add(new ShapeDrawing() { X = item.Cross.Y, Y = item.Cross.X });
                    //图像匹配结果显示在目标点附近
                    CameraAxisViewModelSevice.CameraAxisDevices.Shapes.Add(new TextShapeDrawing()
                    {
                        X = item.Cross.Y + 5,
                        Y = item.Cross.X - 5,
                        Text = string.Format("X: {0}, Y： {1}， Score：{2}",
                                                     item.Cross.X.ToString("#0.000"), item.Cross.Y.ToString("#0.000"), item.Score.ToString("#0.000"))
                    });
                }

                ResultItemsClear();
            });
        }

        public void ResultItemsClear()
        {
            //Task.Factory.StartNew(() =>
            //{
            //    Thread.Sleep(600);
                _currentDispatcher.Invoke((Action)delegate
                {
                    CameraAxisViewModelSevice.CameraAxisDevices.Shapes.Clear();
                });
            //});
        }

        #region 轴精度检测

        public AxisCheckSetting AxisCheckSetting { get; set; }

        private AxisCheckItem _axisCheckItem;
        public AxisCheckItem AxisCheckItem
        {
            get
            {
                return _axisCheckItem;
            }
            set
            {
                _axisCheckItem = value;
                OnPropertyChanged(nameof(AxisCheckItem));
            }
        }

        private void IniAxisCheckParam()
        {
            try
            {
                AxisCheckSetting = _paramList.GetParameter<AxisCheckSetting>();
                AxisCheckItem = AxisCheckSetting.AxisCheckItem;
                if (AxisCheckItem.PHSPerpendicularityCheck.PrecisionCheckList.Count == 2)
                {
                    foreach (var item in AxisCheckItem.PHSPerpendicularityCheck.PrecisionCheckList)
                    {
                        item.AxisX = _gs.Axis_X11;
                        item.AxisY = _gs.Axis_Y11;
                        item.GetPointEvent = PHSItem_GetPointEvent;
                        item.GetStraightnessEvent = Item_GetStraightnessEvent;
                    }
                }
                else
                {
                    AxisCheckItem.PHSPerpendicularityCheck.PrecisionCheckList.Clear();
                    AxisCheckItem.PHSPerpendicularityCheck.PrecisionCheckList.Add(new AxisStraightnessCheckParam { AxisX = _gs.Axis_X11, AxisY = _gs.Axis_Y11, AxisName = _gs.Axis_X11.Name });
                    AxisCheckItem.PHSPerpendicularityCheck.PrecisionCheckList.Add(new AxisStraightnessCheckParam { AxisX = _gs.Axis_X11, AxisY = _gs.Axis_Y11, AxisName = _gs.Axis_Y11.Name });
                    AxisCheckItem.PHSPerpendicularityCheck.PrecisionName = "PHS垂直度";

                    foreach (var item in AxisCheckItem.PHSPerpendicularityCheck.PrecisionCheckList)
                    {
                        item.GetPointEvent = PHSItem_GetPointEvent;
                        item.GetStraightnessEvent = Item_GetStraightnessEvent;
                    }
                }

                if (AxisCheckItem.WSPerpendicularityCheck.PrecisionCheckList.Count == 2)
                {
                    foreach (var item in AxisCheckItem.WSPerpendicularityCheck.PrecisionCheckList)
                    {
                        item.AxisX = _gs.Axis_X21;
                        item.AxisY = _gs.Axis_Y21;
                        item.GetPointEvent = WSItem_GetPointEvent;
                        item.GetStraightnessEvent = Item_GetStraightnessEvent;
                    }
                }
                else
                {
                    AxisCheckItem.WSPerpendicularityCheck.PrecisionCheckList.Clear();
                    AxisCheckItem.WSPerpendicularityCheck.PrecisionCheckList.Add(new AxisStraightnessCheckParam { AxisX = _gs.Axis_X21, AxisY = _gs.Axis_Y21, AxisName = _gs.Axis_X21.Name });
                    AxisCheckItem.WSPerpendicularityCheck.PrecisionCheckList.Add(new AxisStraightnessCheckParam { AxisX = _gs.Axis_X21, AxisY = _gs.Axis_Y21, AxisName = _gs.Axis_Y21.Name });
                    AxisCheckItem.WSPerpendicularityCheck.PrecisionName = "WS垂直度";

                    foreach (var item in AxisCheckItem.WSPerpendicularityCheck.PrecisionCheckList)
                    {
                        item.GetPointEvent = WSItem_GetPointEvent;
                        item.GetStraightnessEvent = Item_GetStraightnessEvent;
                    }
                }

                if (AxisCheckItem.X1X2ParallelismCheck.PrecisionCheckList.Count == 2)
                {
                    var list = AxisCheckItem.X1X2ParallelismCheck.PrecisionCheckList;
                    for (int i = 0; i < list.Count; i++)
                    {
                        var item = list[i];
                        if (i == 0)
                        {
                            item.AxisX = _gs.Axis_X11;
                            item.AxisY = _gs.Axis_Y11;
                        }
                        else if (i == 1)
                        {
                            item.AxisX = _gs.Axis_X21;
                            item.AxisY = _gs.Axis_Y21;
                        }

                        item.GetPointEvent = X1X2Item_GetPointEvent;
                        item.GetStraightnessEvent = Item_GetStraightnessEvent;
                    }
                }
                else
                {
                    AxisCheckItem.X1X2ParallelismCheck.PrecisionCheckList.Clear();
                    AxisCheckItem.X1X2ParallelismCheck.PrecisionCheckList.Add(new AxisStraightnessCheckParam { AxisX = _gs.Axis_X11, AxisY = _gs.Axis_Y11, AxisName = _gs.Axis_X11.Name });
                    AxisCheckItem.X1X2ParallelismCheck.PrecisionCheckList.Add(new AxisStraightnessCheckParam { AxisX = _gs.Axis_X21, AxisY = _gs.Axis_Y21, AxisName = _gs.Axis_X21.Name });
                    AxisCheckItem.X1X2ParallelismCheck.PrecisionName = "X1X2平行度";

                    foreach (var item in AxisCheckItem.X1X2ParallelismCheck.PrecisionCheckList)
                    {
                        item.GetPointEvent = X1X2Item_GetPointEvent;
                        item.GetStraightnessEvent = Item_GetStraightnessEvent;
                    }
                }

                AxisCheckItem.PHSPerpendicularityCheck.GetAxisPrecisionEvent = PHSPerpendicularityCheck_GetAxisPrecisionEvent;
                AxisCheckItem.WSPerpendicularityCheck.GetAxisPrecisionEvent = WSPerpendicularityCheck_GetAxisPrecisionEvent;
                AxisCheckItem.X1X2ParallelismCheck.GetAxisPrecisionEvent = X1X2ParallelismCheck_GetAxisPrecisionEvent;
            }
            catch (Exception ex)
            {
                LogManager.LogSysError(ex, true);
            }

        }

        private List<double> Item_GetStraightnessEvent(string axisName, double[] arg1, double[] arg2)
        {
            List<double> doubles = new List<double>();
            JM1Vision.JM1Manager.Instance.FitLine(arg1, arg2, out double[] ds, out double slop, out double inter);
            doubles = ds.ToList();
            doubles.Add(slop);
            doubles.Add(inter);
            SaveData($"{axisName}直线度", doubles);
            return ds.ToList();
        }

        private Point PHSItem_GetPointEvent()
        {
            _visionOperation.ApproachPointCircle(_gs.Camera_Extend, _gs.Axis_X11, _gs.Axis_Y11, null, GetRectangle(), out System.Windows.Point point);
            return new Point(_gs.Axis_X11.GetPositionImmediate(), _gs.Axis_Y11.GetPositionImmediate());
        }

        private Point WSItem_GetPointEvent()
        {
            return GetWSApproPoint();
        }

        private Point X1X2Item_GetPointEvent()
        {
            return GetWSApproPoint();
        }

        private Point GetWSApproPoint()
        {
            _visionOperation.ApproachPointCircle(_gs.Camera_ExtendWS, _gs.Axis_X21, _gs.Axis_Y21, null, GetRectangle(), out System.Windows.Point point);
            return new Point(_gs.Axis_X21.GetPositionImmediate(), _gs.Axis_Y21.GetPositionImmediate());
        }


        private List<double> StaigthCheck(AxisPrecisionCheck axisPrecisionCheck)
        {
            List<double> doubles = new List<double>();
            if (axisPrecisionCheck.PrecisionCheckList.Count == 2)
            {
                if(axisPrecisionCheck.PrecisionCheckList[0].IsStop) return doubles;
                List<Point> pointsX = axisPrecisionCheck.PrecisionCheckList[0].CalculateStraightness();
                if (axisPrecisionCheck.PrecisionCheckList[1].IsStop) return doubles;
                List<Point> pointsY = axisPrecisionCheck.PrecisionCheckList[1].CalculateStraightness();
                if (pointsX.Count > 0 && pointsY.Count > 0)
                {
                    JM1Vision.JM1Manager.Instance.CalStaight(pointsX.Select(p => p.X).ToArray(), pointsX.Select(p => p.Y).ToArray(),
                        pointsY.Select(p => p.X).ToArray(), pointsY.Select(p => p.Y).ToArray(), out double[] ds);
                    doubles = ds.ToList();
                }
            }

            return doubles;
        }

        private List<double> PHSPerpendicularityCheck_GetAxisPrecisionEvent()
        {
            List<double> doubles = StaigthCheck(AxisCheckItem.PHSPerpendicularityCheck);
            SaveData("PHS垂直度", doubles);
            return doubles;
        }


        private List<double> WSPerpendicularityCheck_GetAxisPrecisionEvent()
        {
            List<double> doubles = StaigthCheck(AxisCheckItem.WSPerpendicularityCheck);
            SaveData("WS垂直度", doubles);
            return doubles;
        }   

        private List<double> X1X2ParallelismCheck_GetAxisPrecisionEvent()
        {
            List<double> doubles = new List<double>();
            try
            {
                if (AxisCheckItem.X1X2ParallelismCheck.PrecisionCheckList.Count == 2)
                {
                    List<Point> points = new List<Point>();
                    var param0 = AxisCheckItem.X1X2ParallelismCheck.PrecisionCheckList[0];
                    var param1 = AxisCheckItem.X1X2ParallelismCheck.PrecisionCheckList[1];
                    int times = param0.Times;
                    double startX1 = param0.StartPosX;
                    double startY1 = param0.StartPosY;
                    double startX2 = param1.StartPosX;
                    double startY2 = param1.StartPosY;
                    double interval = param0.IntervalDis;
                    _safeAxisMotion.MovePHSAndWS(startX1, startY1, startX2, startY2);
                    for (int i = 0; i < times; i++)
                    {
                        if (param0.IsStop) break;
                        double moveX1 = startX1 + i * interval;
                        double moveX2 = startX2 + i * interval;
                        _safeAxisMotion.MovePHSAndWS(moveX1, startY1, moveX2, startY2);
                        Point p = param0.GetPoint();
                        points.Add(p);
                    }

                    if (points.Count > 0)
                    {
                        JM1Vision.JM1Manager.Instance.CalParallel(points.Select(p => p.Y).ToArray(), out double[] ds);
                        doubles = ds.ToList();
                    }
                }

                SaveData("X1X2平行度", doubles);
                return doubles;
            }
            catch (Exception ex)
            {
                LogManager.LogSysError(ex, true);
            }
           
            return doubles;
        }

        private void SaveData(string name, List<double> doubles)
        {
            string pathOffset = "D:\\VisionCheck";
            string path1 = $"{pathOffset}\\{name}_{DateTime.Now.ToString("yy_MM_dd_mm_ss")}.csv";

            if (!Directory.Exists(pathOffset)) Directory.CreateDirectory(pathOffset);
            File.Create(path1).Close();
            using (StreamWriter writer = new StreamWriter(path1, false))
            {
                for (int i = 0; i < doubles.Count; i++)
                {
                    writer.WriteLine(doubles[i]);
                }
            }
        }

        #endregion

        #region //圆形标定相关
        public void TeachCircleCenter()
        {
            Task.Factory.StartNew(() =>
            {
                try
                {
                    if (ApproachPointWS(1))
                    {
                        CameraWaferFusionCalibrationItem.CenterX = _gs.Axis_X21.State.ActualPos;
                        CameraWaferFusionCalibrationItem.CenterY = _gs.Axis_Y21.State.ActualPos;
                        MessageBox.Show("中心对齐完成");
                    }
                    else
                    {
                        MessageBox.Show("逼近失败！");
                    }
                }
                catch (Exception ex)
                {
                    LogManager.LogSysError(ex, true);

                }
            });
        }
       
        private void GetCalibPoints(out List<List<SemiconductorVisionAlgorithm.SemiParams.Point>> rulerPoints, out List<List<SemiconductorVisionAlgorithm.SemiParams.Point>> realPoints)
        {
            var circle = new SemiconductorVisionAlgorithm.SemiParams.Circle(CameraWaferFusionCalibrationItem.CenterX,
                CameraWaferFusionCalibrationItem.CenterY, CameraWaferFusionCalibrationItem.Radius);
            WaferRecips.Instance.get_cross_points(circle, (double)CameraWaferFusionCalibrationItem.ColStep, (double)CameraWaferFusionCalibrationItem.RowStep,
                circle.X, circle.Y, out rulerPoints, out realPoints);

            var allPoints = realPoints.Where(l => l != null).SelectMany(innerList => innerList);

            var minX = allPoints.Min(p => p.X);
            var minY = allPoints.Min(p => p.Y);
            if (minX != 0 || minY != 0)
            {
                for (int i = 0; i < realPoints.Count; i++)
                {
                    var points = realPoints[i];
                    for (int j = 0; j < points.Count; j++)
                    {
                        var point = points[j];
                        point.X -= minX;
                        point.Y -= minY;
                    }
                }
            }
            var newList = rulerPoints.OrderBy(p => p.Count).ToList();
            var maxRowPoints = newList.LastOrDefault();
            _circlePointDic.Clear();
            for (int i = 0; i < rulerPoints.Count; i++)
            {
                var poslist = rulerPoints[i];
                var ypos = poslist.FirstOrDefault().Y;
                List<FusionPoint> points = new List<FusionPoint>();
                foreach (var x in maxRowPoints)
                {
                    FusionPoint fusionPoint = new FusionPoint
                    {
                        X = x.X,
                        Y = ypos,
                    };
                    foreach (var item in poslist)
                    {
                        if(item.X==x.X)
                        {
                            fusionPoint.IsExist = true;
                            break;
                        }
                    }
                    points.Add(fusionPoint);
                }
                _circlePointDic.Add(i + 1, points);
            }

        }
        public void ImportCircleFile()
        {
            CommonUtil.SafeExecuteAsync(() =>
            {
                OpenFileDialog openFileDialog = new OpenFileDialog();
                {
                    openFileDialog.Title = "选择CSV坐标文件";
                    openFileDialog.Filter = "CSV文件 (*.csv)|*.csv|所有文件 (*.*)|*.*";
                    openFileDialog.FilterIndex = 1;
                    openFileDialog.RestoreDirectory = true;

                    if ((bool)openFileDialog.ShowDialog())
                    {
                        var pointList = ImportCirclePointsFromCsv(openFileDialog.FileName);
                        // 找到X和Y的最小值
                        var minX = pointList.Min(p => p.X);
                        var minY = pointList.Min(p => p.Y);

                        // 平移坐标，使最小值为(0,0)
                        if (minX != 0 || minY != 0)
                        {
                            for (int i = 0; i < pointList.Count; i++)
                            {
                                var point= pointList[i];
                                point.X -= minX;
                                point.Y -= minY;
                            }
                        }
                        // 将点按Y坐标分组，创建字典
                        var pointsByY = GroupPointsByY(pointList);


                        // 将字典按Y坐标从大到小排序
                        var sortedPointsByY = pointsByY.OrderByDescending(kv => kv.Key)
                                                      .ToDictionary(kv => kv.Key, kv => kv.Value);
                        var maxPosList = sortedPointsByY.OrderByDescending(x => x.Value.Count).First().Value;
                        _circlePointDic.Clear();
                        int rowIndex = 1;
                        foreach (var item in sortedPointsByY.Keys.ToList())
                        {
                            var poslist= sortedPointsByY[item];
                            List<FusionPoint> points = new List<FusionPoint>();
                            foreach (var x in maxPosList)
                            {
                                FusionPoint fusionPoint = new FusionPoint
                                {
                                    X = x,
                                    Y = item,
                                    IsExist=true
                                };
                                if (!poslist.Contains(x))
                                    fusionPoint.IsExist = false;
                                points.Add(fusionPoint);
                                rowIndex++;
                            }
                            _circlePointDic.Add(rowIndex, points);
                        }
                    }

                }
            });
        }
        private List<Point> ImportCirclePointsFromCsv(string filePath)
        {
            List<Point> points = new List<Point>();

           
                // 检查文件是否存在
                if (!File.Exists(filePath))
                {
                    return points;
                }

                // 读取所有行
                string[] lines = File.ReadAllLines(filePath);

                // 检查是否有数据
                if (lines.Length <= 1) // 考虑到第一行是标题
                {
                    Console.WriteLine("警告：CSV文件没有数据或只有标题行");
                    return points;
                }

            // 跳过标题行，读取所有数据行
            for (int i = 1; i < lines.Length; i++)
            {
                string line = lines[i].Trim();

                // 跳过空行
                if (string.IsNullOrEmpty(line))
                    continue;

                // 分割CSV行
                string[] values = line.Split(',');

                // 确保有足够的列
                if (values.Length >= 2)
                {
                    // 解析X, Y坐标和距离
                    var x = double.Parse(values[0]);
                    var y = double.Parse(values[1]);


                    // 创建新的点对象并添加到列表
                    Point point = new Point
                    {
                        X = x,
                        Y = y,
                    };

                    points.Add(point);


                }
                else
                {
                    Console.WriteLine($"警告：第 {i + 1} 行格式不正确，应有至少3列");
                }
            }
            return points;
        }
        private Dictionary<double, List<double>> GroupPointsByY(List<Point> points)
        {
            Dictionary<double, List<double>> pointsByY = new Dictionary<double, List<double>>();

            foreach (var point in points)
            {
                // 如果这个Y坐标还没有在字典中，创建一个新列表
                if (!pointsByY.ContainsKey(point.Y))
                {
                    pointsByY[point.Y] = new List<double>();
                }

                // 将X坐标添加到对应Y坐标的列表中
                pointsByY[point.Y].Add(point.X);
            }

            // 对每个Y坐标对应的X列表进行排序（可选）
            foreach (var key in pointsByY.Keys.ToList())
            {
                pointsByY[key].Sort();
            }

            return pointsByY;
        }
        private Dictionary<int, List<FusionPoint>> MapTheoryPointToRulerPoint(double xoffset,double yoffset)
        {
            Dictionary<int, List<FusionPoint>> newDic = new Dictionary<int, List<FusionPoint>>();
            foreach (var item in _circlePointDic)
            {
                var list=item.Value;
                var newList=new List<FusionPoint>();
                for (int i = 0; i < list.Count; i++)
                {
                    newList.Add(new FusionPoint
                    {
                        X = list[i].X + xoffset,
                        Y = list[i].Y + yoffset,
                        IsExist = list[i].IsExist,
                    });
                }
                newDic.Add(item.Key, newList);
            }
            return newDic;
        }

        private FusionPoint[,] GenerateCircleDic()
        {
            _circlePointDic.Clear();
            var centerX = CameraWaferFusionCalibrationItem.CenterX;
            var centerY = CameraWaferFusionCalibrationItem.CenterY;
            var radius = CameraWaferFusionCalibrationItem.Radius;
            var space = CameraWaferFusionCalibrationItem.WaferStepXY;
            var xyCount = (CameraWaferFusionCalibrationItem.WaferCountXY - 1) / 2;
            var startX = centerX - xyCount * space;
            var startY = centerY - xyCount * space;

            var pointPos =new FusionPoint[CameraWaferFusionCalibrationItem.WaferCountXY, CameraWaferFusionCalibrationItem.WaferCountXY];
            for (int i = 0; i < CameraWaferFusionCalibrationItem.WaferCountXY; i++)
            {
                for (int j = 0; j < CameraWaferFusionCalibrationItem.WaferCountXY; j++)
                {
                    var fusionP = new FusionPoint()
                    {
                        X = startX + j * space,
                        Y = startY + i * space,
                    };
                    if(IsPointInside(new Point(fusionP.X, fusionP.Y),new Point(centerX,centerY),radius))
                    {
                        fusionP.IsExist = true;
                    }
                    pointPos[i, j] = fusionP;
                }
            }
            return pointPos;
        }
        private bool IsPointInside(Point point, Point center, double radius)
        {
            // 使用距离的平方进行比较，避免开方运算
            double distanceSquared =
                Math.Pow(point.X - center.X, 2) +
                Math.Pow(point.Y - center.Y, 2);

            return distanceSquared <= radius * radius;
        }
        #endregion
    }
    public class FusionPoint
    {
        public double X { get; set; }
        public double Y { get; set; }
        public bool IsExist { get; set; }
    }
}
