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 GuideLineCircleCtrl : BaseGuideControl
    {


        private FlyShape? _circle;
        private FlyShape? _line;


        private float _lineX1;
        private float _lineY1;
        private float _lineX2;
        private float _lineY2;
        private float _lineWidth;


        private float _circleX;
        private float _circleY;
        private float _circleR;




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



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

                    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;
                case ShapeTypeEnum.Circle:
                    this._circle = shape;

                    _circleX = shape.Points[0].X;
                    _circleY = shape.Points[0].Y;
                    _circleR = PointHelper.Distance(shape.Points[0], shape.Points[1]);

                    this.tbCircleX.Text = _circleX.ToString("F3");
                    this.tbCircleY.Text = _circleY.ToString("F3");
                    this.tbCircleR.Text = _circleR.ToString("F3");

                    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 btnCreateCircle_Click(object sender, EventArgs e)
        {
            if (this.canvas.pixmap == null)
            {
                MessageBox.Show("请先打开图片");
                return;
            }
            this.tbCircleX.Text = string.Empty;
            this.tbCircleY.Text = string.Empty;
            this.tbCircleR.Text = string.Empty;
            this.canvas.Shapes.RemoveAll(shp => shp.ShapeType == ShapeTypeEnum.Circle);

            this.canvas.Invalidate();
            this.canvas.StartDraw(ShapeTypeEnum.Circle);
        }



        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;
            }
            if (this.tbLineX1.Text.Trim().Length == 0)
            {
                MessageBox.Show("请先创建圆形");
                return;
            }

            this.canvas.OutsideShapes.Clear();
            this.canvas.Invalidate();

            flag = new List<double>();
            Distance = new List<double>();
            fRowCenter = new List<double>();
            fColCenter = new List<double>();
            fRadius = 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>();

            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["XCenter"] = _circleX;
            inputPara["YCenter"] = _circleY;
            inputPara["Radius"] = _circleR;
            inputPara["Line_XRect"] = hTupleArrayX;
            inputPara["Line_YRect"] = hTupleArrayY;



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

            ExecuteHScript(
                    inputImg,
                    inputPara,
                    outputKeys);

        }
        List<double> flag = new List<double>();
        List<double> Distance = new List<double>();
        List<double> fRowCenter = new List<double>();
        List<double> fColCenter = new List<double>();
        List<double> fRadius = 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",
            //    "distance",
            //    "fRowCenter",
            //    "fColCenter",
            //    "fRadius",
            //    "RowBegin",
            //    "ColBegin",
            //    "RowEnd",
            //    "ColEnd"

            flag = resultDic["OUTPUT_Flag"].HTupleToDouble();
            Distance = resultDic["distance"].HTupleToDouble();
            fRowCenter = resultDic["fRowCenter"].HTupleToDouble();
            fColCenter = resultDic["fColCenter"].HTupleToDouble();
            fRadius = resultDic["fRadius"].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 (Distance.Count > 0)
            {
                lblDistance.Text = Distance[0].ToString();
            }
            else
            {
                lblDistance.Text = "0";
            }

            if (flag.Count > 0 && Distance.Count > 0 && fRowCenter.Count > 0 && fColCenter.Count > 0 && fRadius.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.DrawCircle(new PointF((float)fColCenter[0], (float)fRowCenter[0]), (float)fRadius[0]);

                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;
            }

           
           


            string input = $"LX:{_lineX1};" +
           $"LY:{_lineY1};" +
           $"RX:{_lineX2};" +
           $"RY:{_lineY2};" +
           $"XCenter:{_circleX};" +
           $"YCenter:{_circleY};" +
           $"Radius:{_circleR};" +
           $"Line_XRect:{strarrayX};"+
           $"Line_YRect:{strarrayY}";




            string result = $"distance:{Distance[0]};";
            DataToTriggerEvent(input, result);

        }
    }
}