using SharpDX.Direct2D1;
using SharpDX.Mathematics.Interop;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using VIZ.Framework.Core;
using VIZ.Framework.Storage;
using VIZ.Framework.Domain;

namespace VIZ.Framework.Common
{
    /// <summary>
    /// 框选框插件
    /// </summary>
    public class SelectionBoxPlugin : VideoPluginBase
    {
        /// <summary>
        /// 框选框插件
        /// </summary>
        /// <param name="videoControl">视频控件</param>
        public SelectionBoxPlugin(VideoControl videoControl) : base(videoControl)
        {
            this.drawingWidth = ApplicationDomain.IniStorage.GetValue<VideoConfig, int>(p => p.VIDEO_SELECTION_BOX_BORDER_WIDTH);
            this.drawingColor = ApplicationDomain.IniStorage.GetValue<VideoConfig, RawColor4>(p => p.VIDEO_SELECTION_BOX_BORDER_COLOR);
        }

        /// <summary>
        /// 名称
        /// </summary>
        public override string Name => VideoControlPluginNames.SelectionBox;

        /// <summary>
        /// 选中时触发
        /// </summary>
        public event EventHandler<SelectionBoxSelectedEventArgs> Selected;

        /// <summary>
        /// 框选框信息
        /// </summary>
        private volatile SelectionBoxInfo selectionBoxInfo;

        /// <summary>
        /// 鼠标左键按下的坐标
        /// </summary>
        private Point? mouseLeftButtonDownPoint;

        /// <summary>
        /// 绘制颜色
        /// </summary>
        private RawColor4 drawingColor;

        /// <summary>
        /// 绘制宽度
        /// </summary>
        private float drawingWidth;

        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="trackingBoxInfos">跟踪框信息</param>
        public void Update(SelectionBoxInfo selectionBoxInfo)
        {
            this.selectionBoxInfo = selectionBoxInfo;
        }

        /// <summary>
        /// 渲染
        /// </summary>
        /// <param name="context">渲染上下文</param>
        public override void Render(VideoRenderContext context)
        {
            SelectionBoxInfo info = this.selectionBoxInfo;
            if (info == null)
                return;

            SolidColorBrush brush = new SolidColorBrush(context.Target, info.DrawingBorderColor);

            RawRectangleF rect;
            if (context.Mode == VideoRenderMode.UI)
            {
                rect = info.DrawingRect;
            }
            else
            {
                rect = ImageHelper.ConvertUiRectToImageRect(context.VideoRenderInfo.Frame.Width, context.VideoRenderInfo.Frame.Height, context.VideoRenderInfo.DrawingRect, info.DrawingRect.ToRect()).ToRawRectangleF();
            }
            context.Target.DrawRectangle(rect, brush, info.DrawingBorderWidth);
        }

        /// <summary>
        /// 附加
        /// </summary>
        public override void Attach()
        {
            this.VideoRender.PreviewMouseLeftButtonDown -= VideoRender_PreviewMouseLeftButtonDown;
            this.VideoRender.PreviewMouseLeftButtonDown += VideoRender_PreviewMouseLeftButtonDown;

            this.VideoRender.PreviewMouseLeftButtonUp -= VideoRender_PreviewMouseLeftButtonUp;
            this.VideoRender.PreviewMouseLeftButtonUp += VideoRender_PreviewMouseLeftButtonUp;

            this.VideoRender.PreviewMouseMove -= VideoRender_PreviewMouseMove;
            this.VideoRender.PreviewMouseMove += VideoRender_PreviewMouseMove;
        }

        /// <summary>
        /// 卸载
        /// </summary>
        public override void Detach()
        {
            this.VideoRender.PreviewMouseLeftButtonDown -= VideoRender_PreviewMouseLeftButtonDown;
        }

        /// <summary>
        /// 鼠标左键点击
        /// </summary>
        private void VideoRender_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (!this.IsEnabled)
                return;

            this.mouseLeftButtonDownPoint = e.GetPosition(this.VideoRender);
        }

        /// <summary>
        /// 鼠标左键抬起
        /// </summary>
        private void VideoRender_PreviewMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (this.mouseLeftButtonDownPoint == null || !this.IsEnabled)
                return;

            VideoRenderInfo renderInfo = this.VideoRender.RenderInfo;
            if (renderInfo == null)
            {
                this.selectionBoxInfo = null;
                return;
            }

            if (this.Selected == null)
                return;

            Point beginPoint = this.mouseLeftButtonDownPoint.Value;
            Point endPoint = e.GetPosition(this.VideoRender);

            this.mouseLeftButtonDownPoint = null;

            SelectionBoxSelectedEventArgs args = new SelectionBoxSelectedEventArgs();

            float left = (float)Math.Min(beginPoint.X, endPoint.X);
            float right = (float)Math.Max(beginPoint.X, endPoint.X);
            float top = (float)Math.Min(beginPoint.Y, endPoint.Y);
            float bottom = (float)Math.Max(beginPoint.Y, endPoint.Y);

            args.DrawingRect = new RawRectangleF(left, top, right, bottom);
            args.SrcRect = ImageHelper.ConvertUiRectToImageRect(renderInfo.Frame.Width, renderInfo.Frame.Height, renderInfo.DrawingRect, args.DrawingRect.ToRect()).ToRawRectangleF();

            this.Selected.Invoke(this, args);
        }

        /// <summary>
        /// 鼠标移动
        /// </summary>
        private void VideoRender_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (this.mouseLeftButtonDownPoint == null || !this.IsEnabled)
                return;

            Point beginPoint = this.mouseLeftButtonDownPoint.Value;
            Point endPoint = e.GetPosition(this.VideoRender);

            float left = (float)Math.Min(beginPoint.X, endPoint.X);
            float right = (float)Math.Max(beginPoint.X, endPoint.X);
            float top = (float)Math.Min(beginPoint.Y, endPoint.Y);
            float bottom = (float)Math.Max(beginPoint.Y, endPoint.Y);

            SelectionBoxInfo info = new SelectionBoxInfo();
            info.DrawingRect = new RawRectangleF(left, top, right, bottom);
            info.DrawingBorderColor = this.drawingColor;
            info.DrawingBorderWidth = this.drawingWidth;

            this.selectionBoxInfo = info;
        }
    }
}
