using CanFly.Canvas.Helper;
using CanFly.Canvas.Shape;
using CanFly.Helper;
using HalconDotNet;
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 GuideLineLineCtrl : BaseGuideControl
    {
        private FlyShape? _line1;
        private FlyShape? _line2;

        private float _line1X1;
        private float _line1Y1;
        private float _line1X2;
        private float _line1Y2;
        private float _lineWidth;

        private float _line2X1;
        private float _line2Y1;
        private float _line2X2;
        private float _line2Y2;
        private float _line2Width;

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


        public GuideLineLineCtrl()
        {
            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;

            NumRectWidth2.ValueChanged -= NumericUpDown2_ValueChanged;
            NumRectWidth2.Value = 40;
            NumRectWidth2.ValueChanged += NumericUpDown2_ValueChanged;

        }
        protected override void UpdateShape(FlyShape shape)
        {
            switch (shape.ShapeType)
            {
                case ShapeTypeEnum.Line:
                    // 判断是否为第一条直线或第二条直线
                    if (_line1 == shape)
                    {
                        //_line1 = shape;
                        var pts1 = _line1.Points;
                        _line1X1 = pts1[0].X;
                        _line1Y1 = pts1[0].Y;
                        _line1X2 = pts1[1].X;
                        _line1Y2 = pts1[1].Y;
                        _lineWidth = _line1.LineVirtualRectWidth;

                        tbLine1X1.Text = _line1X1.ToString("F3");
                        tbLine1Y1.Text = _line1Y1.ToString("F3");
                        tbLine1X2.Text = _line1X2.ToString("F3");
                        tbLine1Y2.Text = _line1Y2.ToString("F3");
                        //NumRectWidth1.Value = (decimal)_lineWidth;
                    }
                    else
                    {
                        //_line2 = shape;
                        var pts2 = _line2.Points;
                        _line2X1 = pts2[0].X;
                        _line2Y1 = pts2[0].Y;
                        _line2X2 = pts2[1].X;
                        _line2Y2 = pts2[1].Y;
                        _line2Width = _line2.LineVirtualRectWidth;

                        tbLine2X1.Text = _line2X1.ToString("F3");
                        tbLine2Y1.Text = _line2Y1.ToString("F3");
                        tbLine2X2.Text = _line2X2.ToString("F3");
                        tbLine2Y2.Text = _line2Y2.ToString("F3");
                        // NumRectWidth2.Value = (decimal)_line2Width;
                    }

                    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 Canvas_newShape()
        {
            // 自动切换到下一条直线绘制
            if (_line1 == null)
            {
                _line1 = this.canvas.Shapes.LastOrDefault(shp => shp.ShapeType == ShapeTypeEnum.Line);
            }
            else if (_line2 == null)
            {
                _line2 = this.canvas.Shapes.LastOrDefault(shp => shp.ShapeType == ShapeTypeEnum.Line);
            }

            // 停止绘制模式,用户可以根据需要重新启用
            this.canvas.StopDraw();
            //this.canvas.StopDraw();
        }

        private void btnCreateLineOne_Click(object sender, EventArgs e)
        {
            // this.canvas.Shapes.RemoveAll(shp => shp == _line1); // 移除第一条直线
            this._line1 = null;
            this.canvas.Invalidate();
            this.canvas.StartDraw(ShapeTypeEnum.Line); // 启动绘制模式
            this.canvas.Enabled = true;
        }

        private void btnCreateLineTwo_Click(object sender, EventArgs e)
        {
            // this.canvas.Shapes.RemoveAll(shp => shp == _line2); // 移除第二条直线
            this._line2 = null;
            this.canvas.Invalidate();
            this.canvas.StartDraw(ShapeTypeEnum.Line); // 启动绘制模式
            this.canvas.Enabled = true;
        }

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

            flag = new List<double>();
            Distance = new List<double>();
            Line1_RowBegin = new List<double>();
            Line1_ColBegin = new List<double>();
            Line1_RowEnd = new List<double>();
            Line1_ColEnd = new List<double>();
            Line2_RowBegin = new List<double>();
            Line2_ColBegin = new List<double>();
            Line2_RowEnd = new List<double>();
            Line2_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._line1.LineVirtualRectPoints;
            if (Points.Count() < 4)
            {
                return;
            }
            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[] array1X = new float[] { x1, x2, x3, x4, x5 };
            HTuple hTupleArray1X = new HTuple(array1X);

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


            strarray1X = string.Join(",", array1X);
            strarray1Y = string.Join(",", array1Y);


            // 获取矩形的 4 个点
            PointF[] Points2 = this._line2.LineVirtualRectPoints;
            if (Points2.Count() < 4)
            {
                return;
            }
            PointF Point21 = Points2[0];
            PointF Point22 = Points2[1];
            PointF Point23 = Points2[2];
            PointF Point24 = Points2[3];
            PointF Point25 = Points2[0];

            float x21 = Point21.X;
            float y21 = Point21.Y;

            float x22 = Point22.X;
            float y22 = Point22.Y;

            float x23 = Point23.X;
            float y23 = Point23.Y;

            float x24 = Point24.X;
            float y24 = Point24.Y;

            float x25 = Point25.X;
            float y25 = Point25.Y;


            float[] array2X = new float[] { x21, x22, x23, x24, x25 };
            HTuple hTupleArray2X = new HTuple(array2X);

            float[] array2Y = new float[] { y21, y22, y23, y24, y25 };
            HTuple hTupleArray2Y = new HTuple(array2Y);


            strarray2X = string.Join(",", array2X);
            strarray2Y = string.Join(",", array2Y);

            inputPara["Line1_LX"] = _line1X1;
            inputPara["Line1_LY"] = _line1Y1;
            inputPara["Line1_RX"] = _line1X2;
            inputPara["Line1_RY"] = _line1Y2;

            inputPara["Line2_LX"] = _line2X1;
            inputPara["Line2_LY"] = _line2Y1;
            inputPara["Line2_RX"] = _line2X2;
            inputPara["Line2_RY"] = _line2Y2;



            inputPara["Line1_XRect"] = hTupleArray1X;
            inputPara["Line1_YRect"] = hTupleArray1Y;

            inputPara["Line2_XRect"] = hTupleArray2X;
            inputPara["Line2_YRect"] = hTupleArray2Y;

            List<string> outputKeys = new List<string>()
            {
                "OUTPUT_Flag",
                "Distance",
                "Line1_RowBegin",
                "Line1_ColBegin",
                "Line1_RowEnd",
                "Line1_ColEnd",
                 "Line2_RowBegin",
                 "Line2_ColBegin",
                  "Line2_RowEnd",
                  "Line2_ColEnd"

            };

            ExecuteHScript(
                    inputImg,
                    inputPara,
                    outputKeys);
        }


        private void btnLoadImage_Click(object sender, EventArgs e)
        {
            OpenImageFile(bitmap =>
            {
                this.canvas.LoadPixmap(bitmap);
                this.canvas.Enabled = true;
                _line1 = new FlyShape();
                _line2 = new FlyShape();
                _line1.AddPoint(new Point(10, 10));
                _line1.AddPoint(new Point(50, 10));
                _line2.AddPoint(new Point(10, 20));
                _line2.AddPoint(new Point(60, 20));
                _line1.ShapeType = ShapeTypeEnum.Line;
                _line2.ShapeType = ShapeTypeEnum.Line;

                _line1.IsDrawLineVirtualRect = true;
                _line1.LineVirtualRectWidth = 40;
                _line2.IsDrawLineVirtualRect = true;
                _line2.LineVirtualRectWidth = 40;

                canvas.Shapes.Add(_line1);
                canvas.Shapes.Add(_line2);
                canvas.Invalidate();

                UpdateShape(_line1);
                UpdateShape(_line2);
            });
        }
        string strarray1X = string.Empty;
        string strarray1Y = string.Empty;
        string strarray2X = string.Empty;
        string strarray2Y = string.Empty;
        List<double> flag =new List<double>();
        List<double> Distance = new List<double>();
        List<double> Line1_RowBegin = new List<double>();
        List<double> Line1_ColBegin = new List<double>();
        List<double> Line1_RowEnd = new List<double>();
        List<double> Line1_ColEnd = new List<double>();
        List<double> Line2_RowBegin = new List<double>();
        List<double> Line2_ColBegin = new List<double>();
        List<double> Line2_RowEnd = new List<double>();
        List<double> Line2_ColEnd = new List<double>();
        protected override void OnExecuteHScriptResult(
          bool success,
          Dictionary<string, HTuple> resultDic,
          int timeElasped)
        {
            if (!success)
            {
                return;
            }

            //"OUTPUT_Flag",
            //    "Distance",
            //    "Line1_RowBegin",
            //    "Line1_ColBegin",
            //    "Line1_RowEnd",
            //    "Line1_ColEnd",
            //     "Line2_RowBegin",
            //     "Line2_ColBegin",
            //      "Line2_RowEnd",
            //      "Line2_ColEnd"


            flag = resultDic["OUTPUT_Flag"].HTupleToDouble();
            Distance = resultDic["Distance"].HTupleToDouble();
            Line1_RowBegin = resultDic["Line1_RowBegin"].HTupleToDouble();
            Line1_ColBegin = resultDic["Line1_ColBegin"].HTupleToDouble();
            Line1_RowEnd = resultDic["Line1_RowEnd"].HTupleToDouble();
            Line1_ColEnd = resultDic["Line1_ColEnd"].HTupleToDouble();
            Line2_RowBegin = resultDic["Line2_RowBegin"].HTupleToDouble();
            Line2_ColBegin = resultDic["Line2_ColBegin"].HTupleToDouble();
            Line2_RowEnd = resultDic["Line2_RowEnd"].HTupleToDouble();
            Line2_ColEnd = resultDic["Line2_ColEnd"].HTupleToDouble();

            if (flag.Count > 0)
            {
                lblResult.Text = flag[0].ToString();

            }
            else
            {
                lblResult.Text = "无";
            }
            if (Distance.Count > 0)
            {
                lblDistance.Text = Distance[0].ToString();
            }
            else
            {
                lblDistance.Text = "0";
            }

            if (flag.Count > 0 && Distance.Count > 0 && Line1_RowBegin.Count > 0 && Line1_ColBegin.Count > 0 && Line1_RowEnd.Count > 0 && Line1_ColEnd.Count > 0 && Line2_RowBegin.Count > 0 && Line2_ColBegin.Count > 0 && Line2_RowEnd.Count > 0 && Line2_ColEnd.Count > 0)
            {
                float width = 0;
                this.canvas.DrawLine(new PointF((float)Line1_ColBegin[0], (float)Line1_RowBegin[0]), new PointF((float)Line1_ColEnd[0], (float)Line1_RowEnd[0]), width);
                this.canvas.DrawLine(new PointF((float)Line2_ColBegin[0], (float)Line2_RowBegin[0]), new PointF((float)Line2_ColEnd[0], (float)Line2_RowEnd[0]), width);
                this.canvas.Invalidate();
                lblElapsed.Text = $"{timeElasped} ms";
            }
        }

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

        private void NumericUpDown2_ValueChanged(object sender, EventArgs e)
        {
            if (_line2 != null)
            {
                // _line2.IsDrawLineVirtualRect = true;
                _line2.LineVirtualRectWidth = (float)NumRectWidth2.Value;
                UpdateShape(_line2);
                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;
            }



            //inputPara["Line1_LX"] = _line1X1;
            //inputPara["Line1_LY"] = _line1Y1;
            //inputPara["Line1_RX"] = _line1X2;
            //inputPara["Line1_RY"] = _line1Y2;

            //inputPara["Line2_LX"] = _line2X1;
            //inputPara["Line2_LY"] = _line2Y1;
            //inputPara["Line2_RX"] = _line2X2;
            //inputPara["Line2_RY"] = _line2Y2;



            //inputPara["Line1_XRect"] = hTupleArray1X;
            //inputPara["Line1_YRect"] = hTupleArray1Y;

            //inputPara["Line2_XRect"] = hTupleArray2X;
            //inputPara["Line2_YRect"] = hTupleArray2Y;


            string input = $"Line1_LX:{_line1X1};" +
                $"Line1_LY:{_line1Y1};" +
                $"Line1_RX:{_line1X2};" +
                $"Line1_RY:{_line1Y2};" +
                $"Line2_LX:{_line2X1};" +
                $"Line2_LY:{_line2Y1};" +
                $"Line2_RX:{_line2X2};" +
                $"Line2_RY:{_line2Y2};" +
                $"Line1_XRect:{strarray1X};" +
                $"Line1_YRect:{strarray1Y};" +
                $"Line2_XRect:{strarray2X};" +
                $"Line2_YRect:{strarray2Y}"
                ;


            string result = $"Distance:{Distance[0]}";


            DataToTriggerEvent(input, result);

        }
    }
}