using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ProductionControl
{
    public partial class FrmPhotoTag : Form
    {
        private Control.ControlCollection picBoxList;
        DevContainer devContainer;
        private int picIndex;
        private int tagIndex;
        private double Xmm,Ymm;
        private Bitmap currBmp;


        //
        private double ratio = 1;        // 图片的起始显示比例
        private double ratioStep = 0.1;
        private Size pic_size;
        private int xPos;
        private int yPos;
        public FrmPhotoTag(Control.ControlCollection picBoxColl,int index, DevContainer _devContainer)
        {
            API.OutputDebugString("------1");
            InitializeComponent();
            this.picBoxList = picBoxColl;
            this.picIndex = index;
            devContainer = _devContainer;
            this.tsbtnMakeTag.Enabled = (_devContainer!=null && _devContainer.state);    
        }
        protected override bool ProcessDialogKey(Keys keyData)
        { 
            if (keyData == Keys.Up || keyData == Keys.Down || keyData == Keys.Left || keyData == Keys.Right)
                return false;
            else
                return base.ProcessDialogKey(keyData);
        }
        private void initUI()
        {

        }
        private void FrmPhoto_Load(object sender, EventArgs e)
        { 
            API.OutputDebugString("------2");
            Size size;
            if (!Config.SkipScannerCC && devContainer.state)
                size = devContainer.devScannerCC.size;
            else
                size = (picBoxList[this.picIndex * 2] as PictureBox).Image.Size;

            API.OutputDebugString("------3");
            this.pnlPic.ClientSize = new Size(this.pnlPic.ClientSize.Width,
                (int)(this.pnlPic.ClientSize.Width * (size.Height * 1.0f / size.Width)));
            this.pictureBox1.Size = this.pnlPic.ClientSize;
            this.pictureBox1.Location = new Point(0, 0);
            //this.pictureBox1.Image = bmp;

            API.OutputDebugString("------4");
            pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
            pictureBox1.MouseWheel += new MouseEventHandler(pictureBox1_MouseWheel);
            pictureBox1.MouseMove += pictureBox1_MouseMove;
            pictureBox1.MouseDown += pictureBox1_MouseDown;
            this.ActiveControl = this.pictureBox1; // 设置焦点   

            pic_size = this.pnlPic.ClientSize;

            //
            API.OutputDebugString("------5");
            //MessageBox.Show("菜单栏厚度" + SystemInformation.MenuHeight.ToString());  //获取标准菜单栏的厚度        
            //MessageBox.Show("标题栏厚度" + SystemInformation.CaptionHeight.ToString()); //获取标准标题栏的厚度
            this.Height = pnlPic.Bottom + SystemInformation.CaptionHeight + SystemInformation.MenuHeight*2 + statusStrip1.Height+30;
            this.Left = (Screen.PrimaryScreen.WorkingArea.Width - this.Width) / 2;
            this.Top = (Screen.PrimaryScreen.WorkingArea.Height - this.Height) / 2;

            //this.pictureBox2.Left = 0;
            //this.pictureBox2.Width = this.splitContainer1.Panel2.Width;
            //
            API.OutputDebugString("------6");
            if (devContainer.state)
            {
                //镜头马达
                if (!Config.SkipSmallAxis) devContainer.devSmallAxis.gotoPos(18000, false);
                if (!Config.SkipLight) devContainer.devLight.setDigitalValue(1, 100);

                if (!Config.SkipScannerCC)
                {
                    devContainer.devScannerCC.setParam(27000, devContainer.devScannerCC.Gain, devContainer.devScannerCC.ResultingFrameRate);
                    devContainer.devScannerCC.setPreviewWin(this.pictureBox1.Handle);
                    devContainer.devScannerCC.setMode(true);
                }
                //axis速度
                devContainer.devAxis.setAxisVelParam(8, 200, 400, 400); 
            }
        }
        private void FrmPhoto_Shown(object sender, EventArgs e)
        {
            showPic(this.picIndex);
        }
        private void tsbtnPre_Click(object sender, EventArgs e)
        {
            showPic(--this.picIndex);
        }

        private void tsbtnNext_Click(object sender, EventArgs e)
        {
            showPic(++this.picIndex);
        }
        private void FrmPhotoTag_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Up:
                case Keys.Left:
                    if (!this.tsbtnPre.Enabled) return;
                    tsbtnPre_Click(null, null);
                    break;
                case Keys.Down:
                case Keys.Right:
                    if (!this.tsbtnNext.Enabled) return;
                    tsbtnNext_Click(null, null);
                    break;
            }
        }
         
        private void showPic(int index)
        {
            try
            {
                PictureBox picBox = picBoxList[index*2] as PictureBox;
                string[] tags = picBox.Tag.ToString().Split(',');
                this.tagIndex = Convert.ToInt32(tags[0]);
                this.Xmm = Convert.ToDouble(tags[1]);
                this.Ymm = Convert.ToDouble(tags[2]);
                tsStateMsg.Text = $"第{index + 1}/{picBoxList.Count / 2}张";
                tsStateMsg.Text += $" [索引:{tagIndex}, X:{Xmm}mm, Y:{Ymm}mm]"; 
                currBmp = (Bitmap)picBox.Image;
                this.Text = $"{this.ClientSize.Width}*{this.ClientSize.Height}; " +
                    $"left:{pictureBox2.Left} width:{pictureBox2.Width} " +
                    $"panelW:{this.flowLayoutPanel1.ClientSize.Width}; ";

                this.pictureBox2.SizeMode=PictureBoxSizeMode.Zoom;
                this.pictureBox2.Width = this.flowLayoutPanel1.ClientSize.Width-5;
                this.pictureBox2.Height = (int)((currBmp.Height * 1.0f / currBmp.Width) * this.pictureBox2.Width + 0.5);
                this.Text += $"更新宽度：{pictureBox2.Width}";
                this.pictureBox2.Image = (Bitmap)currBmp.Clone();
                //
                CheckBox cb = picBoxList[index * 2 + 1] as CheckBox;
                this.chkAdd.Checked = cb.Checked;

                this.tsbtnPre.Enabled = (index > 0);
                this.tsbtnNext.Enabled = (index < picBoxList.Count / 2 - 1);

                //
                if (this.chkSyncMove.Checked)
                    moveAxis();  
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void chkAdd_CheckedChanged(object sender, EventArgs e)
        {
            CheckBox cb = picBoxList[picIndex * 2 + 1] as CheckBox;
            cb.Checked = this.chkAdd.Checked;
        }
        private void tsbtnSave_Click(object sender, EventArgs e)
        {
            try
            {
                if (Config.Defect_Small_SavePath.Trim() == "")
                    throw new Exception("请先到系统设置中设置缺陷小图保存路径！");

                //
                string savePath = "";
                if (Config.Defect_Small_SavePath != "")
                {
                    savePath = Config.Defect_Small_SavePath + "\\" + DateTime.Now.ToString("yyyyMMdd");
                    if (!Directory.Exists(savePath))
                        Directory.CreateDirectory(savePath);
                }

                //save
                PictureBox picBox = picBoxList[this.picIndex * 2] as PictureBox;
                string[] tags = picBox.Tag.ToString().Split(',');
                int tagIndex = Convert.ToInt32(tags[0]);
                //Xmm = Convert.ToDouble(tags[1]);
                //Ymm = Convert.ToDouble(tags[2]);
                CheckBox cb = picBoxList[this.picIndex * 2 + 1] as CheckBox; 
                ((Bitmap)cb.Tag).Save($"{savePath}\\X{Xmm}_Y{Ymm}_K{tagIndex}_{DateTime.Now.Ticks}.bmp", ImageFormat.Bmp);
                //OpenCvSharp.Cv2.ImWrite($"{savePath}\\X{Xmm}_Y{Ymm}_K{tagIndex}_{DateTime.Now.Ticks}.bmp", ((OpenCvSharp.Mat)cb.Tag));//保存图片 
                MessageBox.Show("保存成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        //打标
        private void tsbtnMakeTag_Click(object sender, EventArgs e)
        {
            if (devContainer.state)
            {
                if (!devContainer.devAxis.isReady(1) || !devContainer.devAxis.isReady(2))
                {
                    MessageBox.Show("轴状态为不可用！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0);
                    return;
                }

                var list = devContainer.libDefect.makeTag(tagIndex, Xmm, Ymm, currBmp.Width, currBmp.Height);
                devContainer.devAxis.move_ptp(1, list[0], AxMoveMode.绝对位置);
                devContainer.devAxis.move_ptp(2, list[1], AxMoveMode.绝对位置);
                while (!devContainer.devAxis.isReady(1) || !devContainer.devAxis.isReady(2))
                {
                    Thread.Sleep(100);
                    if (!devContainer.state)
                        break;
                }
                //
                if (!devContainer.io_output(CMDName.喷墨输出, false, true, 500))
                    MessageBox.Show("打标失败，请确认此指令是否设置正确！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0);
            }
        }
        private void moveAxis()
        {
            if (devContainer.state)
            {
                if (!devContainer.devAxis.isReady(0) || !devContainer.devAxis.isReady(2))
                {
                    MessageBox.Show("轴状态为不可用！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0);
                    return;
                }

                this.tsbtnPre.Enabled = this.tsbtnNext.Enabled =this.tsbtnMakeTag.Enabled= false;
                this.tsAxisState.Text = "      正在移动相机...";

                //创建任务
                Task task = new Task(() =>
                {
                    var list = devContainer.libDefect.viewTag(tagIndex, Xmm, Ymm, currBmp.Width, currBmp.Height);
                    devContainer.devAxis.move_ptp(0, list[0], AxMoveMode.绝对位置);
                    devContainer.devAxis.move_ptp(2, list[1], AxMoveMode.绝对位置);
                    while (!devContainer.devAxis.isReady(0) || !devContainer.devAxis.isReady(2))
                    {
                        Thread.Sleep(100);
                        Application.DoEvents();
                        if (!devContainer.state)
                            break;
                    }

                    this.Invoke(new System.Action(() =>
                    {
                        this.tsAxisState.Text = "";
                        this.tsbtnPre.Enabled = (picIndex > 0);
                        this.tsbtnNext.Enabled = (picIndex < picBoxList.Count / 2 - 1);
                        this.tsbtnMakeTag.Enabled = true;
                    }));
                });
                task.Start(); 
            }
        }
         
        private void tsbtnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        private void chkSyncMove_CheckedChanged(object sender, EventArgs e)
        {
            if (chkSyncMove.Checked)
                moveAxis();
        }

        //----------
        private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
        {
            Point pictureBoxPoint = this.PointToClient(Cursor.Position);
            //this.Text = $"{e.X}:{e.Y}; {pictureBoxPoint.X}:{pictureBoxPoint.Y}; {pictureBox1.Left}:{pictureBox1.Top}; " +
            //    $"{this.pictureBox1.Width}:{this.pictureBox1.Height}; {this.Width}:{this.Height}; " +
            //    $"Cursor:{Cursor.Position.X}:{Cursor.Position.Y}";
            if (e.Delta > 0)
            {
                ratio += ratioStep;
                if (ratio > 100) // 放大上限
                    ratio = 100;
                else
                {
                    int x = (int)(pictureBox1.Left - e.X * (e.X * 1.0d / pictureBox1.Width * ratioStep) + 0.5);
                    int y = (int)(pictureBox1.Top - e.Y * (e.Y * 1.0d / pictureBox1.Height * ratioStep) + 0.5);

                    //this.Text = $"{pictureBox1.Width}-{pic_size.Width};{ratio}，{pictureBox1.Left}-{e.X}* 比例:{e.X*1.0d/pictureBox1.Width}={e.X}/{pictureBox1.Width} * {(ratioStep)}={x} | " +
                    //    $"{pictureBox1.Top}-{e.Y}* {e.Y * 1.0f / pictureBox1.Height * (ratio - 1.0d)}={y}"; 
                    this.changePictureBoxSize(new Point(x, y), ratio);
                }

            }
            else if (ratio - ratioStep >= 1)
            {
                ratio -= ratioStep;
                //if (ratio < 0.1)  // 放大下限
                //    ratio = 0.1;
                //else 
                int x = (int)(pictureBox1.Left + e.X * (e.X * 1.0d / pictureBox1.Width * ratioStep) + 0.5);
                int y = (int)(pictureBox1.Top + e.Y * (e.Y * 1.0d / pictureBox1.Height * ratioStep) + 0.5);
                this.changePictureBoxSize(new Point(x, y), ratio);
            }
        }
        private void changePictureBoxSize(Point location, double ratio)
        {
            var picSize = pictureBox1.Size;
            picSize.Width = Convert.ToInt32(pic_size.Width * ratio);
            picSize.Height = Convert.ToInt32(pic_size.Height * ratio);
            pictureBox1.Size = picSize;

            if (location.X > 0) location.X = 0;
            if (location.Y > 0) location.Y = 0;
            if (picSize.Width + location.X < this.pnlPic.ClientSize.Width) location.X = -(picSize.Width - this.pnlPic.ClientSize.Width);
            if (picSize.Height + location.Y < this.pnlPic.ClientSize.Height) location.Y = -(picSize.Height - this.pnlPic.ClientSize.Height);

            //Point location = new Point();
            //location.X = (this.ClientSize.Width - this.pictureBox1.Width) / 2;
            //location.Y = (this.ClientSize.Height - this.pictureBox1.Height) / 2;
            this.pictureBox1.Location = location;
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            try
            {
                // 鼠标按下拖拽图片
                if (e.Button == MouseButtons.Left)
                {
                    this.Text = $"{e.X}:{e.Y};{xPos}:{yPos}";
                    // 限制拖拽出框
                    if (pictureBox1.Width > this.pnlPic.ClientSize.Width
                        || pictureBox1.Height > this.pnlPic.ClientSize.Height)
                    {
                        int moveX = e.X - xPos;
                        int moveY = e.Y - yPos;
                        if ((pictureBox1.Left + moveX) <= 0
                            && (pictureBox1.Top + moveY) <= 0
                            && (pictureBox1.Right + moveX) >= this.pnlPic.ClientSize.Width
                            && (pictureBox1.Bottom + moveY) >= this.pnlPic.ClientSize.Height)
                        {
                            pictureBox1.Left += moveX;//设置x坐标.
                            pictureBox1.Top += moveY;//设置y坐标. 
                        }
                    }
                }
            }
            catch (Exception dd)
            {
                MessageBox.Show(dd.Message);
            }
        } 

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            xPos = e.X;//当前x坐标.
            yPos = e.Y;//当前y坐标.
        }

    }
}
