using JM1.JM1Params;
using MainShell.AlgorithmCalib.Model;
using MainShell.AlgorithmCalib.Service;
using MainShell.Common;
using MainShell.Hardware;
using MainShell.Motion;
using MaxwellFramework.Core.Interfaces;
using MwFramework.ManagerService;
using SemiconductorVisionAlgorithm.SemiParams;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;

namespace MainShell.AlgorithmCalib
{
    public class FusionCalibTask : DelegateBase
    {
        public Rectangle1 Rectangle { get; set; }

        private HardwareManager _hardware;
        private FusionCalibParItem _fusionCalibParItem;
        private List<double> _calibPosList = new List<double>();
        private SemiconductorVisionAlgorithm.SemiParams.Point[,] _initialwsPos;
        private Dictionary<int, SemiconductorVisionAlgorithm.SemiParams.Point[,]> _calibResultPointData = new Dictionary<int, SemiconductorVisionAlgorithm.SemiParams.Point[,]>();
        private FusionCalibMotionService _motion;
        //private VisionOperation _visionOperation;
        bool _isCancle = false;
        private int _calibCount = 0;
        private bool _isReDo = false;
        private bool _isWaferCalib = false;
        private double _initialwsRotate;

        public override bool Check(object state)
        {
            _isWaferCalib = _fusionCalibParItem.IsWaferCalib;
            IoC.Get<IProjectManager>().EnablePageAndDisableOther("视觉标定");
            return true;
        }

        public override void Do(object state)
        {
            try
            {
                _isCancle = false;
                if (_isReDo)
                {
                    _isReDo = false;
                }
                else
                {
                    _calibResultPointData.Clear();
                    _calibPosList.Clear();
                }
                var objects = state as object[];
                _fusionCalibParItem = objects[0] as FusionCalibParItem;


                //_visionOperation = IoC.Get<VisionOperation>();

                double waferStep = _fusionCalibParItem.CalibStep;
                string modelFileName = _fusionCalibParItem.ModelPath;
                string path = System.AppDomain.CurrentDomain.BaseDirectory + modelFileName;

                if (_calibPosList.Count != _fusionCalibParItem.Count || _calibResultPointData.Count != _fusionCalibParItem.Count)
                {
                    _calibResultPointData.Clear();
                    _calibPosList.Clear();
                    _calibCount = 0;
                    for (int i = 0; i < _fusionCalibParItem.Count; i++)
                    {
                        _calibPosList.Add(0);
                        _calibResultPointData.Add(i, new SemiconductorVisionAlgorithm.SemiParams.Point[0, 0]);
                    }
                }

                _initialwsPos = ApprochTable(waferStep, _fusionCalibParItem.MoveAxisPos, _hardware.Axis_Y1.State.ActualPos, _fusionCalibParItem.ApproachXPos, _fusionCalibParItem.ApproachYPos, 0, path);

                int count = 0;

                for (int i = _calibCount; i < _fusionCalibParItem.Count; i++)
                {
                    if (_isCancle)
                    {
                        return;
                    }
                    double x1, y1, x2, y2 = 0;
                    count++;
                    if (_fusionCalibParItem.IsWaferCalib)
                    {
                         x1 = _fusionCalibParItem.CameraAxisPos + _fusionCalibParItem.Step * i;
                         y1 = _fusionCalibParItem.StartY;

                        x2 = _fusionCalibParItem.StartX + _fusionCalibParItem.Step * i;
                        y2 = _hardware.Axis_Y2.State.ActualPos;
                    }
                    else
                    {
                        x1 = _fusionCalibParItem.StartX;
                        y1 =  _fusionCalibParItem.CameraAxisPos + _fusionCalibParItem.Step * i;

                        x2 = _hardware.Axis_X2.State.ActualPos;
                        y2 = _fusionCalibParItem.StartY + _fusionCalibParItem.Step * i;
                    }



                    SemiconductorVisionAlgorithm.SemiParams.Point[,] points = null;
                    points = ApprochTable(waferStep, x1, y1, x2, y2, count, path);
                    if (_calibResultPointData.ContainsKey(i))
                    {
                        _calibResultPointData[i] = points;
                    }
                    else
                    {
                        _calibResultPointData.Add(i, points);
                    }
                    if (_fusionCalibParItem.IsWaferCalib)
                    {
                        _calibPosList[i] = _hardware.Axis_X1.State.ActualPos;
                    }
                    else
                    {
                        _calibPosList[i] = _hardware.Axis_X1.State.ActualPos;
                    }
                }
                if (_fusionCalibParItem.IsWaferCalib)
                {
                    SemiJM1Vision.SemiJM1Manager.Instance.cal_wafer_fusion_die(_calibResultPointData, _calibPosList, _initialwsPos, _fusionCalibParItem.CalibStep, waferStep, _fusionCalibParItem.CalibCount);
                    string filePath = System.AppDomain.CurrentDomain.BaseDirectory + @"CalibData";
                    SemiJM1Vision.SemiJM1Manager.Instance.Save(filePath);

                }
                else
                {
                    SemiJM1Vision.SemiJM1Manager.Instance.cal_wafer_fusion_pad(_fusionCalibParItem.Index,_calibResultPointData, _calibPosList, _initialwsPos, _fusionCalibParItem.CalibStep, waferStep, _fusionCalibParItem.CalibCount);
                    string filePath = System.AppDomain.CurrentDomain.BaseDirectory + @"CalibData";
                    SemiJM1Vision.SemiJM1Manager.Instance.set_center(new SemiconductorVisionAlgorithm.SemiParams.Point(0, 0));
                    SemiJM1Vision.SemiJM1Manager.Instance.Save(filePath);
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                var result = MwMessageBox.Show("是否继续?", "继续", MessageBoxButton.YesNo, MessageBoxImage.Information);
                if (result == MessageBoxResult.Yes)
                {
                    _isReDo = true;
                    this.Do(state);
                }
                else
                {
                    _isReDo = false;
                }
            }

            MessageBox.Show("校正完成");
        }


        private SemiconductorVisionAlgorithm.SemiParams.Point[,] ApprochTable(double calibStep, double x1, double y1, double x2, double y2, int count, string path)
        {
            SemiconductorVisionAlgorithm.SemiParams.Point[,] pointArray =
                new SemiconductorVisionAlgorithm.SemiParams.Point[_fusionCalibParItem.CalibCount, _fusionCalibParItem.CalibCount];
            _motion.MoveWsAvoidance(x2, y1);
            _motion.MovePhsAvoidance(x1, y2);
            for (int y = 0; y < _fusionCalibParItem.CalibCount; y++)
            {
                double X1, X2, Y1, Y2 = 0;
                Y1 = y * calibStep + y1;
                Y2 = y * calibStep + y2;
                for (int x = 0; x < _fusionCalibParItem.CalibCount; x++)
                {
                    int index = y % 2 == 0 ? x : _fusionCalibParItem.CalibCount - 1 - x;
                    X2 = index * calibStep + x2;
                    X1 = index * calibStep + x1;
                    if (_isCancle)
                    {
                        return pointArray;
                    }
                    SemiconductorVisionAlgorithm.SemiParams.Point point = new SemiconductorVisionAlgorithm.SemiParams.Point();

                    if (_fusionCalibParItem.IsWaferCalib)
                    {
                        _motion.MoveWsAvoidance(X2, Y1);
                        //if (!_visionOperation.ApproachPointCircle(_hardware.TopCameraExtend, _hardware.Axis_X2, _hardware.Axis_Y1, path, Rectangle, out point))
                        //{
                        //    Cancel();
                        //}
                        pointArray[index, y] = new SemiconductorVisionAlgorithm.SemiParams.Point(_hardware.Axis_X2.State.ActualPos, _hardware.Axis_Y1.State.ActualPos);
                    }
                    else
                    {
                        _motion.MovePhsAvoidance(X1, Y2);
                        //if (!_visionOperation.ApproachPointCircle(_hardware.TopCameraExtend, _hardware.Axis_X1, _hardware.Axis_Y2, path, Rectangle, out point))
                        //{
                        //    Cancel();
                        //}
                        pointArray[index, y] = new SemiconductorVisionAlgorithm.SemiParams.Point(_hardware.Axis_X1.State.ActualPos, _hardware.Axis_Y2.State.ActualPos);
                    }
                }
            }

            return pointArray;
        }



        public override void Finish()
        {
            base.Finish();
            IoC.Get<IProjectManager>().SwitchState();
        }

        public override void Cancel()
        {
            _isCancle = true;
        }
    }
}
