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

namespace VIZ.Framework.Common
{
    /// <summary>
    /// 裁剪框插件
    /// </summary>
    public class ClipBoxPlugin : VideoPluginBase
    {
        /// <summary>
        /// 日志
        /// </summary>
        private static readonly ILog log = LogManager.GetLogger(typeof(ClipBoxPlugin));

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

        }

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

        /// <summary>
        /// 跟踪框信息
        /// </summary>
        private volatile ClipBoxInfo clipBoxInfo;

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

        /// <summary>
        /// 更新颜色
        /// </summary>
        /// <param name="color">更新边框颜色</param>
        public void UpdateBorderColor(RawColor4 color)
        {
            ClipBoxInfo info = this.clipBoxInfo;
            if (info == null)
                return;

            info.DrawingBorderColor = color;
        }

        /// <summary>
        /// 渲染
        /// </summary>
        /// <param name="context">渲染上下文</param>
        public override void Render(VideoRenderContext context)
        {
            // 画面渲染区域
            ClipBoxInfo info = this.clipBoxInfo;
            if (info == null)
                return;

            float half = info.DrawingBorderWidth / 2f;
            RawRectangleF drawRect;
            RawRectangleF fillRect;
            if (context.Mode == VideoRenderMode.UI)
            {
                drawRect = ImageHelper.ConvertImageRectToUiRect(context.VideoRenderInfo.Frame.Width, context.VideoRenderInfo.Frame.Height, context.VideoRenderInfo.DrawingRect, info.SrcRect.ToRect()).ToRawRectangleF();
                fillRect = context.VideoRenderInfo.ControlRect.ToRawRectangleF();
            }
            else
            {
                drawRect = info.SrcRect;
                fillRect = new RawRectangleF(0, 0, context.VideoRenderInfo.Frame.Width, context.VideoRenderInfo.Frame.Height);
            }

            drawRect = new RawRectangleF(drawRect.Left + half, drawRect.Top + half, drawRect.Right - half, drawRect.Bottom - half);

            List<RawRectangleF> maskList = new List<RawRectangleF>();

            // left
            if (drawRect.Left > context.VideoRenderInfo.DrawingRect.Left + half)
            {
                maskList.Add(new RawRectangleF(
                    (float)context.VideoRenderInfo.DrawingRect.Left, (float)context.VideoRenderInfo.DrawingRect.Top,
                    drawRect.Left - half, (float)context.VideoRenderInfo.DrawingRect.Bottom));
            }

            // right
            if (drawRect.Right < fillRect.Right - half)
            {
                maskList.Add(new RawRectangleF(
                    drawRect.Right + half, (float)context.VideoRenderInfo.DrawingRect.Top,
                    (float)context.VideoRenderInfo.DrawingRect.Right, (float)context.VideoRenderInfo.DrawingRect.Bottom));
            }

            // top
            if (drawRect.Top > half)
            {
                maskList.Add(new RawRectangleF(
                    drawRect.Left - half, (float)context.VideoRenderInfo.DrawingRect.Top,
                    drawRect.Right + half, drawRect.Top - half));
            }

            // bottom
            if (drawRect.Bottom < fillRect.Bottom - half)
            {
                maskList.Add(new RawRectangleF(
                    drawRect.Left - half, drawRect.Bottom + half,
                    drawRect.Right + half, (float)context.VideoRenderInfo.DrawingRect.Bottom));
            }

            // 绘制
            SolidColorBrush maskBrush = new SolidColorBrush(context.Target, info.MaskColor);
            foreach (RawRectangleF mask in maskList)
            {
                context.Target.FillRectangle(mask, maskBrush);
            }

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

            // 中心轴
            if (!info.IsCenterAxisEnabled)
                return;

            SolidColorBrush centerAxisBrush = new SolidColorBrush(context.Target, info.CenterAxisColor);
            RawVector2 centerAxisPoint0 = new RawVector2(drawRect.Left + (drawRect.Right - drawRect.Left) / 2, drawRect.Top);
            RawVector2 centerAxisPoint1 = new RawVector2(drawRect.Left + (drawRect.Right - drawRect.Left) / 2, drawRect.Bottom);
            context.Target.DrawLine(centerAxisPoint0, centerAxisPoint1, centerAxisBrush, info.CenterAxisWidth);
        }
    }
}
