using CanFly.Canvas.Helper;
using CanFly.Canvas.Shape;
using CanFly.Canvas.UI;
using CanFly.Helper;
using HalconDotNet;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CanFly.UI.GuidePanel
{
    public partial class GuideLineCtrl : BaseGuideControl
    {



        private FlyShape? _line;


        private float _lineX1;
        private float _lineY1;
        private float _lineX2;
        private float _lineY2;
        private float _lineWidth;
        private PointF[] _rectPoints = new PointF[4];
        //private float _LineLX=new float();
        //private float _LineLY =new float();
        //private float _LineRX =new float();
        //private float _LineRY =new float();





        protected override string GetScriptFileName() => "Line_detect.hdvp";



        public GuideLineCtrl()
        {
            InitializeComponent();

            this.canvas.mouseMoved += Canvas_mouseMoved;
            this.canvas.OnShapeUpdateEvent += UpdateShape;
            this.canvas.selectionChanged += Canvas_selectionChanged;

            this.canvas.OnShapeMoving += Canvas_OnShapeMoving;
            this.canvas.newShape += Canvas_newShape;

            this.ctrlTitleBar.OnCloseClicked += OnControlClose;

            NumRectWidth1.ValueChanged -= NumRectWidth1_ValueChanged;
            NumRectWidth1.Value = 40;
            NumRectWidth1.ValueChanged += NumRectWidth1_ValueChanged;

        }



        protected override void UpdateShape(FlyShape shape)
        {
            switch (shape.ShapeType)
            {
                case ShapeTypeEnum.Line:
                    this._line = shape;
                    _line.IsDrawLineVirtualRect = true;
                    var pts = this._line.Points;

                    _lineX1 = pts[0].X;
                    _lineY1 = pts[0].Y;
                    _lineX2 = pts[1].X;
                    _lineY2 = pts[1].Y;
                    _lineWidth = shape.LineVirtualRectWidth;
                    _rectPoints = shape.LineVirtualRectPoints;
                    //_LineLX = (shape.LineVirtualRectPoints[0].X + shape.LineVirtualRectPoints[3].X) / 2;
                    //_LineLY = (shape.LineVirtualRectPoints[0].Y + shape.LineVirtualRectPoints[3].Y) / 2;
                    //_LineRX = (shape.LineVirtualRectPoints[1].X + shape.LineVirtualRectPoints[2].X) / 2;
                    //_LineRY = (shape.LineVirtualRectPoints[1].Y + shape.LineVirtualRectPoints[2].Y) / 2;

                    tbLineX1.Text = _lineX1.ToString("F3");
                    tbLineY1.Text = _lineY1.ToString("F3");
                    tbLineX2.Text = _lineX2.ToString("F3");
                    tbLineY2.Text = _lineY2.ToString("F3");
                    // NumRectWidth1.Value = (decimal)_lineWidth;
                    break;

                default:
                    break;
            }
        }





        private void GuideLineCircleCtrl_Load(object sender, EventArgs e)
        {



        }




        private void Canvas_mouseMoved(PointF pos)
        {
            if (InvokeRequired)
            {
                Invoke(Canvas_mouseMoved, pos);
                return;
            }

            lblStatus.Text = $"X:{pos.X}, Y:{pos.Y}";

        }




        private void Canvas_selectionChanged(List<FlyShape> shapes)
        {
            //if (shapes.Count != 1)
            //{
            //    // panelGuide.Controls.Clear();
            //    return;
            //}
            //SwitchGuideForm(shapes[0].ShapeType);
            // Canvas_OnShapeUpdateEvent(shapes[0]);

            if (shapes.Count != 1)
            {
                return;
            }
            UpdateShape(shapes[0]);

        }



        private void Canvas_OnShapeMoving(List<FlyShape> shapes)
        {
            if (shapes.Count != 1)
            {
                return;
            }

            UpdateShape(shapes[0]);
        }







        private void btnCreateLine_Click(object sender, EventArgs e)
        {
            if (this.canvas.pixmap == null)
            {
                MessageBox.Show("请先打开图片");
                return;
            }

            tbLineX1.Text = string.Empty;
            tbLineY1.Text = string.Empty;
            tbLineX2.Text = string.Empty;
            tbLineY2.Text = string.Empty;


            this.canvas.Shapes.RemoveAll(shp => shp.ShapeType == ShapeTypeEnum.Line);
            this.canvas.Invalidate();
            this.canvas.StartDraw(ShapeTypeEnum.Line);

        }



        private void btnLoadImage_Click(object sender, EventArgs e)
        {
            OpenImageFile(bitmap =>
            {
                this.canvas.LoadPixmap(bitmap);
                this.canvas.Enabled = true;


            });
        }


        private void Canvas_newShape()
        {
            this.canvas.StopDraw();
        }
        string strarrayX = string.Empty;
        string strarrayY = string.Empty;
        private void btnExecute_Click(object sender, EventArgs e)
        {
            if (this.canvas.pixmap == null)
            {
                MessageBox.Show("请先打开图片");
                return;
            }
            if (this.tbLineX1.Text.Trim().Length == 0)
            {
                MessageBox.Show("请先创建直线");
                return;
            }
            this.canvas.OutsideShapes.Clear();
            this.canvas.Invalidate();


            flag = new List<double>();
            RowBegin = new List<double>();
            ColBegin = new List<double>();
            RowEnd = new List<double>();
            ColEnd = new List<double>();
            Dictionary<string, HObject> inputImg = new Dictionary<string, HObject>();

            if (hImage == null)
            {
                HOperatorSet.ReadImage(out hImage, CurrentImageFile);
            }
            inputImg["INPUT_Image"] = hImage;
            // 创建一维数组

            Dictionary<string, HTuple> inputPara = new Dictionary<string, HTuple>();

            // 获取矩形的 4 个点
            PointF[] Points = this._line.LineVirtualRectPoints;
            PointF Point1 = Points[0];
            PointF Point2 = Points[1];
            PointF Point3 = Points[2];
            PointF Point4 = Points[3];
            PointF Point5 = Points[0];

            float x1 = Point1.X;
            float y1 = Point1.Y;

            float x2 = Point2.X;
            float y2 = Point2.Y;

            float x3 = Point3.X;
            float y3 = Point3.Y;

            float x4 = Point4.X;
            float y4 = Point4.Y;

            float x5 = Point5.X;
            float y5 = Point5.Y;


            float[] arrayX = new float[] { x1, x2, x3, x4, x5 };
            HTuple hTupleArrayX = new HTuple(arrayX);

            float[] arrayY = new float[] { y1, y2, y3, y4, y5 };
            HTuple hTupleArrayY = new HTuple(arrayY);

            strarrayX = string.Join(",", arrayX);
            strarrayY = string.Join(",", arrayY);

            inputPara["LX"] = _lineX1;
            inputPara["LY"] = _lineY1;
            inputPara["RX"] = _lineX2;
            inputPara["RY"] = _lineY2;
            inputPara["XRect"] = hTupleArrayX;
            inputPara["YRect"] = hTupleArrayY;



            List<string> outputKeys = new List<string>()
            {
                "OUTPUT_Flag",
                "RowBegin",
                "ColBegin",
                "RowEnd",
                "ColEnd"
            };

            ExecuteHScript(
                    inputImg,
                    inputPara,
                    outputKeys);

        }


        List<double> flag = new List<double>();
        List<double> RowBegin = new List<double>();
        List<double> ColBegin = new List<double>();
        List<double> RowEnd = new List<double>();
        List<double> ColEnd = new List<double>();


        protected override void OnExecuteHScriptResult(
            bool success,
            Dictionary<string, HTuple> resultDic,
            int timeElasped)
        {
            if (!success)
            {
                return;
            }


            /*
               "OUTPUT_Flag",
                "RXCenter",
                "RYCenter",
                "RRadius"
             */

            flag = resultDic["OUTPUT_Flag"].HTupleToDouble();
            RowBegin = resultDic["RowBegin"].HTupleToDouble();
            ColBegin = resultDic["ColBegin"].HTupleToDouble();
            RowEnd = resultDic["RowEnd"].HTupleToDouble();
            ColEnd = resultDic["ColEnd"].HTupleToDouble();
            if (flag.Count > 0)
            {
                lblResult.Text = flag[0].ToString();

            }
            else
            {
                lblResult.Text = "无";
            }
            if (flag.Count > 0 && RowBegin.Count > 0 && ColBegin.Count > 0 && RowEnd.Count > 0 && ColEnd.Count > 0)
            {
                float width = 0;
                this.canvas.DrawLine(new PointF((float)ColBegin[0], (float)RowBegin[0]), new PointF((float)ColEnd[0], (float)RowEnd[0]), width);
                this.canvas.Invalidate();
                lblElapsed.Text = $"{timeElasped} ms";
            }
        }


        private void NumRectWidth1_ValueChanged(object sender, EventArgs e)
        {
            if (_line != null)
            {
                //_line1.IsDrawLineVirtualRect = true;
                _line.LineVirtualRectWidth = (float)NumRectWidth1.Value;
                UpdateShape(_line);
                this.canvas.Invalidate();
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            if (lblResult.Text.Equals("无"))
            {
                MessageBox.Show("请先进行绘制");
                return;
            }
            if (lblResult.Text != "0")
            {
                MessageBox.Show("测量计算错误,无法保存");
                return;
            }
            //flag = resultDic["OUTPUT_Flag"].HTupleToDouble();
            //RowBegin = resultDic["RowBegin"].HTupleToDouble();
            //ColBegin = resultDic["ColBegin"].HTupleToDouble();
            //RowEnd = resultDic["RowEnd"].HTupleToDouble();
            //ColEnd = resultDic["ColEnd"].HTupleToDouble();


            string input = $"LX:{_lineX1};" +
          $"LY:{_lineY1};" +
          $"RX:{_lineX2};" +
          $"RY:{_lineY2};" +
          $"Line_XRect:{strarrayX};" +
          $"Line_YRect:{strarrayY}";


            string result = $"RowBegin:{string.Join(";", RowBegin[0])};ColBegin:{string.Join(";", ColBegin[0])};RowEnd:{string.Join(";", RowEnd[0])};ColEnd:{string.Join(";", ColEnd[0])}";

            DataToTriggerEvent(input, result);
        }
    }
}