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

namespace VIZ.Framework.Common
{
    /// <summary>
    /// 边线检测多边形插件
    /// </summary>
    public class SideCheckPolygonPlugin : VideoPluginBase
    {

        /// <summary>
        /// 框选框插件
        /// </summary>
        /// <param name="videoControl">视频控件</param>
        public SideCheckPolygonPlugin(VideoControl videoControl) : base(videoControl)
        {

        }

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

        /// <summary>
        /// 鼠标点击时触发
        /// </summary>
        public event EventHandler<SideCheckPolygonClickEventArgs> Click;

        /// <summary>
        /// 边线检测框信息
        /// </summary>
        private volatile List<SideCheckPolygonInfo> sideCheckPolygonInfos;

        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="sideCheckPolygonInfos">边线检测框信息</param>
        public void Update(List<SideCheckPolygonInfo> sideCheckPolygonInfos)
        {
            this.sideCheckPolygonInfos = sideCheckPolygonInfos;
        }

        /// <summary>
        /// 渲染
        /// </summary>
        /// <param name="context">渲染上下文</param>
        public override void Render(VideoRenderContext context)
        {
            List<SideCheckPolygonInfo> sideCheckPolygonInfos = this.sideCheckPolygonInfos;
            if (sideCheckPolygonInfos == null || sideCheckPolygonInfos.Count == 0)
                return;

            foreach (SideCheckPolygonInfo info in sideCheckPolygonInfos)
            {
                if (info.SrcPoints == null || info.SrcPoints.Count <= 1)
                    continue;

                SolidColorBrush brush = new SolidColorBrush(context.Target, info.FillColor);
                PathGeometry geometry = new PathGeometry(context.Target.Factory);

                GeometrySink sink = geometry.Open();
                if (context.Mode == VideoRenderMode.UI)
                {
                    RawVector2 first_point = ImageHelper.ConvertImagePointToUiPoint(context.VideoRenderInfo.Frame.Width, context.VideoRenderInfo.Frame.Height, context.VideoRenderInfo.DrawingRect, info.SrcPoints[0]);
                    sink.BeginFigure(first_point, FigureBegin.Filled);
                    for (int i = 1; i < info.SrcPoints.Count; ++i)
                    {
                        RawVector2 point = ImageHelper.ConvertImagePointToUiPoint(context.VideoRenderInfo.Frame.Width, context.VideoRenderInfo.Frame.Height, context.VideoRenderInfo.DrawingRect, info.SrcPoints[i]);
                        sink.AddLine(point);
                    }
                    sink.EndFigure(FigureEnd.Closed);
                }
                else
                {
                    sink.BeginFigure(info.SrcPoints[0], FigureBegin.Filled);
                    for (int i = 1; i < info.SrcPoints.Count - 1; ++i)
                    {
                        sink.AddLine(info.SrcPoints[i]);
                    }
                    sink.EndFigure(FigureEnd.Closed);
                }
                sink.Close();

                context.Target.FillGeometry(geometry, brush);
            }
        }

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

        /// <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 || this.Click == null)
                return;

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

            SideCheckPolygonClickEventArgs args = new SideCheckPolygonClickEventArgs();
            args.MousePoint = e.GetPosition(this.VideoRender);
            args.SrcPoint = ImageHelper.ConvertUiPointToImagePoint(renderInfo.Frame.Width, renderInfo.Frame.Height, renderInfo.DrawingRect, args.MousePoint);

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