using DH.Commons.Enums;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static DH.Commons.Enums.EnumHelper;



namespace DH.UI.Model.Winform
{
    public partial class Canvas : UserControl
    {
        readonly CanvasImage cvImage = new CanvasImage();

        #region Grid
        readonly GridCtrl gridCtrl = new GridCtrl();

        private void GridValueChanged(int gridValue)
        {
            cvImage.GridValue = gridValue;
        }

        private void ShowGridChanged(bool isShowGrid)
        {
            cvImage.ShowGrid = isShowGrid;
        }

        private void GridColorChanged(Color obj)
        {
            cvImage.Pen_Grid.Color = obj;
        }
        #endregion

        public Canvas()
        {
            InitializeComponent();
            DoubleBuffered = true;
            SetStyle(ControlStyles.OptimizedDoubleBuffer |
                            ControlStyles.ResizeRedraw |
                            ControlStyles.AllPaintingInWmPaint, true);

            cvImage.Dock = DockStyle.Fill;
            scMain.Panel1.Controls.Add(cvImage);

            dgElements.AutoGenerateColumns = false;

            var checkHead = new DataGridViewCheckboxHeaderCell();
            checkHead.OnCheckBoxClicked += CheckHead_OnCheckBoxClicked;
            dgElements.Columns[0].HeaderCell = checkHead;
            dgElements.Columns[0].HeaderCell.Value = string.Empty;

            Elements.CollectionChanged += Elements_CollectionChanged;

            cvImage.OnMouseLocationUpdated = OnMouseLocationUpdated;
            cvImage.OnMouseStateChanged += OnMouseStateChanged;

            gridCtrl.IsShowGridChanged = ShowGridChanged;
            gridCtrl.GridValueChanged = GridValueChanged;
            gridCtrl.GridColorChanged = GridColorChanged;
            gridCtrl.Padding = new Padding(0, 5, 0, 5);
            tsTool.Items.Add(new GridCtrlHost(gridCtrl));
            tsTool.Invalidate();

            _eleCollectionChangedTimer = new System.Threading.Timer(OnElementCollectionChangedBufferTimer, null, -1, -1);

            //tsmiShowStatusBar.Checked = tsmiShowToolBar.Checked = IsShowElementList = IsShowROITool = IsShowStatusBar = IsShowToolBar = false;
        }

        private void OnMouseStateChanged(MouseState ms)
        {
            if (ms != MouseState.SelectionZone && ms != MouseState.SelectionZoneDoing)
            {
                if (this.IsHandleCreated)
                {
                    this.Invoke(new Action(() =>
                    {
                        tsBtnModeSelection.Checked = false;
                        tsBtnModeNormal.Checked = true;
                    }));
                }
            }
        }

        #region 底部状态栏
        public bool IsShowStatusBar
        {
            get => stsStatus.Visible;
            set => stsStatus.Visible = value;
        }

        private void OnMouseLocationUpdated(Point screenPoint, PointF imagePoint, string colorDesc)
        {
            //await Task.Run(() => tsslLocation.Text = $"屏幕坐标X:{screenPoint.X},Y:{screenPoint.Y}    图片坐标X:{imagePoint.X},Y:{imagePoint.Y}   颜色:{colorDesc}");
            this.Invoke(new Action(() =>
            {
                tsslLocation.Text = $"屏幕坐标X:{screenPoint.X},Y:{screenPoint.Y}    图片坐标X:{imagePoint.X.ToString("f2")},Y:{imagePoint.Y.ToString("f2")}   颜色:{colorDesc}";
            }));
        }

        //private void MouseLocationUpdated(Point screenPoint, Point imagePoint, string colorDesc)
        //{
        //    if (InvokeRequired)
        //    {
        //        Invoke(new Action<Point, Point, string>(MouseLocationUpdated), screenPoint, imagePoint);
        //    }
        //    else
        //    {
        //        tsslLocation.Text = $"屏幕坐标X:{screenPoint.X},Y:{screenPoint.Y}    图片坐标X:{imagePoint.X},Y:{imagePoint.Y}   颜色:{colorDesc}";
        //    }
        //}
        #endregion

        #region 属性
        #region CanvasImage相关
        //private MouseState mouseState = MouseState.Normal;
        //public MouseState MouseState
        //{
        //    get
        //    {
        //        return mouseState;
        //    }
        //    set
        //    {
        //        if (mouseState != value)
        //        {
        //            mouseState = value;

        //            tsslMouseState.Text = mouseState.ToString();

        //            if (mouseState >= MouseState.SelectionZone)
        //            {
        //                tsBtnModeSelection.Checked = true;
        //            }
        //            else
        //            {
        //                tsBtnModeNormal.Checked = true;
        //            }
        //        }
        //    }
        //}

        public string ImageFilePath { get; set; }

        public Bitmap MAP
        {
            get => cvImage.MAP;
            set => cvImage.MAP = value;
        }
        public Matrix Matrix
        {
            get => cvImage.Matrix;
            set => cvImage.Matrix = value;
        }
        public MouseState MouseState
        {
            get => cvImage.MouseState;
            set => cvImage.MouseState = value;
        }
        public ObservableCollection<IShapeElement> Elements
        {
            get => cvImage.Elements;
        }
        #endregion

        private bool isShowElementList = false;
        public bool IsShowElementList
        {
            get => isShowElementList;
            set
            {
                //if (isShowElementList != value)
                {
                    isShowElementList = value;
                    scMain.Panel2Collapsed = !value;
                }
            }
        }

        private bool isShowROITool = false;
        public bool IsShowROITool
        {
            get => isShowROITool;
            set
            {
                tsROIs.Visible = isShowROITool = value;
            }
        }
        #endregion

        #region 图片操作
        /// <summary>
        /// 载入图片
        /// </summary>
        /// <param name="map"></param>
        public void LoadImage(Bitmap map)
        {
            cvImage.LoadImage(map);
            OnImageChanged?.Invoke();
        }
        public void Clear()
        {
            cvImage.Clear();
        }

        /// <summary>
        /// 设置图片为原始尺寸
        /// </summary>
        public void SetMapSize()
        {
            cvImage.SetMapSize();
        }

        /// <summary>
        /// 设置图片为适配尺寸
        /// </summary>
        public void SetScreenSize()
        {
            cvImage.SetScreenSize();
        }
        #endregion

        #region 基元列表
        private void chkShowChecked_CheckedChanged(object sender, EventArgs e)
        {
            dgElements.DataSource = null;

            if (Elements != null && Elements.Count > 0)
            {
                if (chkShowChecked.Checked)
                {
                    dgElements.DataSource = Elements.Where(u => u.IsEnabled && u.IsShowing).ToList();
                }
                else
                {
                    dgElements.DataSource = Elements.Where(u => u.IsShowing).ToList();
                }
            }
        }

        private void CheckHead_OnCheckBoxClicked(object sender, DataGridViewCheckboxHeaderEventArgs e)
        {
            //foreach (IShapeElement ele in Elements)
            //{
            //    ele.IsEnabled = e.CheckedState;
            //}
            for (int i = 0; i < Elements.Count; i++)
            {
                Elements[i].IsEnabled = e.CheckedState;
            }
            OnElementChanged(null);
        }

        private void dgElements_SelectionChanged(object sender, EventArgs e)
        {
            if (dgElements.SelectedRows.Count > 0)
            {
                var ele = Elements.FirstOrDefault(u => u.ID == dgElements.SelectedRows[0].Cells["colID"].Value.ToString());
                propGridElement.SelectedObject = ele;
            }
        }

        private void dgElements_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (dgElements.SelectedRows.Count > 0)
            {
                var ele = Elements.FirstOrDefault(u => u.ID == dgElements.SelectedRows[0].Cells["colID"].Value.ToString());

                for (int i = 0; i < Elements.Count; i++)
                {
                    Elements[i].State = ElementState.Normal;
                }

                ele.State = ElementState.Selected;

                SetDeviceByElement?.Invoke(ele);

                Invalidate();
            }
        }

        System.Threading.Timer _eleCollectionChangedTimer = null;

        private void OnElementCollectionChangedBufferTimer(object state)
        {
            OnElementChanged(null);
            for (int i = 0; i < Elements.Count; i++)
            {
                Elements[i].PropertyChanged -= Ele_PropertyChanged;
                Elements[i].PropertyChanged += Ele_PropertyChanged;
            }
            //foreach (IShapeElement ele in Elements)
            //{
            //    ele.PropertyChanged -= Ele_PropertyChanged;
            //    ele.PropertyChanged += Ele_PropertyChanged;
            //}
        }

        private void Elements_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            //_eleCollectionChangedTimer?.Change(200, -1);
            OnElementChanged(null);
            for (int i = 0; i < Elements.Count; i++)
            {
                Elements[i].PropertyChanged -= Ele_PropertyChanged;
                Elements[i].PropertyChanged += Ele_PropertyChanged;
            }
        }

        private void Ele_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "IsEnabled")
            {
                OnElementChanged(sender as IShapeElement);
            }
            else
            {
                Invoke(new Action(() =>
                {
                    cvImage.Invalidate();
                }));
            }
        }

        private void OnElementChanged(IShapeElement ele)
        {
            if (ele != null)
                OnElementChangedHandle?.Invoke(ele);

            if (InvokeRequired)
            {
                Invoke(new Action(() => OnElementChanged(ele)));
            }
            else
            {
                if (isShowElementList)
                {
                    dgElements.DataSource = null;
                    if (Elements != null && Elements.Count > 0)
                    {
                        if (chkShowChecked.Checked)
                        {
                            dgElements.DataSource = Elements.ToList().Where(u => u.IsEnabled && u.IsShowing).ToList();
                        }
                        else
                        {
                            dgElements.DataSource = Elements.ToList().Where(u => u.IsShowing).ToList();
                        }
                    }
                    Invalidate();
                }
            }
        }

        private void propGridElement_SelectedObjectsChanged(object sender, EventArgs e)
        {
            propGridElement.ExpandAllGridItems();
        }

        #region 基元列表右键菜单
        private void tsmiResort_Click(object sender, EventArgs e)
        {
            //Elements.Sort();
        }

        private void tsmiClearActualValue_Click(object sender, EventArgs e)
        {
            //foreach (IShapeElement ele in Elements)
            //{
            //    if (ele.IsEnabled)
            //    {
            //        ele.SetActualValue(0.0);
            //    }
            //}
        }

        private void tsmiInitialState_Click(object sender, EventArgs e)
        {
            //foreach (IShapeElement ele in Elements)
            //{
            //    if (ele.IsEnabled)
            //    {
            //        ele.State = ElementState.Normal;
            //        ele.InitialMeasureResult();
            //    }
            //}
        }

        private void tsmiClearStandardValue_Click(object sender, EventArgs e)
        {
            //foreach (IShapeElement ele in Elements)
            //{
            //    if (ele.IsEnabled)
            //    {
            //        ele.SetStandardValue(0.0);
            //    }
            //}
        }
        #endregion
        #endregion

        #region 图像区域右键菜单
        private void tsmiKeepUnselected_Click(object sender, EventArgs e)
        {
            KeepElements(false);
        }

        private void tsmiKeepSelected_Click(object sender, EventArgs e)
        {
            KeepElements(true);
        }

        private void KeepElements(bool isKeepSelected)
        {
            for (int i = 0; i < Elements.Count; i++)
            {
                var ele = Elements[i];
                if (ele.IsEnabled)
                {
                    if (ele.State == ElementState.Selected)
                    {
                        ele.IsEnabled = isKeepSelected;
                    }
                    else
                    {
                        ele.IsEnabled = !isKeepSelected;
                    }
                }
            }
        }

        private void tsmiUnselectElements_Click(object sender, EventArgs e)
        {
            //if (MouseState == MouseState.SelectedElement)
            //{
            //    MouseState = MouseState.Normal;

            //    //Elements.ForEach(ele =>
            //    foreach (IShapeElement ele in Elements)
            //    {
            //        ele.State = ElementState.Normal;
            //    }
            //    //);
            //}
        }
        #endregion

        #region 基元的设备属性 运动设置和相机设置
        public Action<IShapeElement> SetElementDevicePara;

        public Action<IShapeElement> SetDeviceByElement;
        #endregion

        #region 一般操作工具条
        public bool IsShowToolBar
        {
            get => tsTool.Visible;
            set => tsTool.Visible = value;
        }

        private void tsBtnLoadImage_Click(object sender, EventArgs e)
        {
            Thread InvokeThread = new Thread(new ThreadStart(OpenLoadImage));
            InvokeThread.SetApartmentState(ApartmentState.STA);
            InvokeThread.Start();
            InvokeThread.Join();
        }

        private void OpenLoadImage()
        {
            ImageFilePath = "";
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                ImageFilePath = ofd.FileName;
                LoadImage((Bitmap)Bitmap.FromFile(ImageFilePath));
            }
        }

        private void tsBtnSaveImage_Click(object sender, EventArgs e)
        {
            if (MAP == null)
                return;

            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "JPG文件|*.jpg|BMP文件|*.bmp";
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                string filePath = sfd.FileName;
                if (filePath.EndsWith("bmp"))
                {
                    MAP.Save(filePath, ImageFormat.Bmp);
                }
                else
                {
                    MAP.Save(filePath, ImageFormat.Jpeg);
                }
                MessageBox.Show("图片保存成功!");
            }
        }

        private void tsBtnSaveImageWithElements_Click(object sender, EventArgs e)
        {
            if (MAP == null)
                return;

            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "JPG文件|*.jpg|BMP文件|*.bmp";
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                string filePath = sfd.FileName;

                Bitmap bmp = new Bitmap(MAP.Width, MAP.Height, PixelFormat.Format32bppArgb);
                //Bitmap bmp = new Bitmap(MAP.Width, MAP.Height, MAP.PixelFormat);
                //Bitmap bmp = new Bitmap(MAP.Width, MAP.Height);
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                    g.DrawImage(MAP, 0, 0);

                    for (int i = 0; i < Elements.Count; i++)
                    {
                        var ele = Elements[i];
                        if (ele.IsEnabled)
                            ele.Draw(g);
                    }
                }

                if (filePath.EndsWith("bmp"))
                {
                    bmp.Save(filePath, ImageFormat.Bmp);
                }
                else
                {
                    bmp.Save(filePath, ImageFormat.Jpeg);
                }
                MessageBox.Show("带基元图片保存成功!");
            }
        }

        private void tsBtnMapSize_Click(object sender, EventArgs e)
        {
            SetMapSize();
        }

        private void tsBtnModeNormal_CheckedChanged(object sender, EventArgs e)
        {
            var btn = sender as ToolStripButton;
            if (btn.Checked)
            {
                btn.BackColor = SystemColors.ActiveCaption;

                foreach (ToolStripItem c in tsTool.Items)
                {
                    if (c is ToolStripButton)
                    {
                        if (c.Name.StartsWith("tsBtnMode") && c.Name != btn.Name)
                        {
                            var temp = c as ToolStripButton;
                            temp.Checked = false;
                            temp.BackColor = SystemColors.Control;
                        }
                    }
                }

                switch (btn.Name)
                {
                    case "tsBtnModeNormal":
                        MouseState = MouseState.Normal;
                        break;
                    case "tsBtnModeSelection":
                        MouseState = MouseState.SelectionZone;
                        break;
                }
            }
        }

        private void tsBtnScreenSize_Click(object sender, EventArgs e)
        {
            SetScreenSize();
        }
        #endregion

        #region 基元工具条
        //private void LoadElementTools()
        //{
        //    var eleDict = ElementFactory.GetAllElementsInfo();

        //    foreach (KeyValuePair<ElementAttribute, Type> pair in eleDict)
        //    {

        //    }
        //}

        public void SetNewROIType(IShapeElement element)
        {
            cvImage.DrawTemplate = element;
        }
        #endregion

        #region 事件
        public event Action<IShapeElement> OnElementChangedHandle;
        public event Action OnImageChanged;
        #endregion

        #region 工具栏显示/隐藏右键菜单
        private void tsmiShowToolBar_CheckedChanged(object sender, EventArgs e)
        {
            //IsShowToolBar = tsmiShowToolBar.Checked;
        }

        private void tsmiShowStatusBar_CheckedChanged(object sender, EventArgs e)
        {
            //IsShowStatusBar = tsmiShowStatusBar.Checked;
        }
        #endregion
    }
}