using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using VIZ.Framework.Core;

namespace VIZ.Framework.Common
{
    /// <summary>
    /// VideoControl.xaml 的交互逻辑
    /// </summary>
    public partial class VideoControl : UserControl
    {
        public VideoControl()
        {
            InitializeComponent();

            this.videoRender.OwnerVideoControl = this;
        }

        // ===========================================================================================================
        // === Property ===
        // ===========================================================================================================

        #region IsShowFPS -- 是否显示FPS

        /// <summary>
        /// 是否显示FPS
        /// </summary>
        public bool IsShowFPS
        {
            get { return (bool)GetValue(IsShowFPSProperty); }
            set { SetValue(IsShowFPSProperty, value); }
        }

        /// <summary>
        /// Using a DependencyProperty as the backing store for IsShowFPS.  This enables animation, styling, binding, etc...
        /// </summary>
        public static readonly DependencyProperty IsShowFPSProperty =
            DependencyProperty.Register("IsShowFPS", typeof(bool), typeof(VideoControl), new PropertyMetadata(false));

        #endregion

        // ===========================================================================================================
        // === Public Function ===
        // ===========================================================================================================

        /// <summary>
        /// 更新视频帧
        /// </summary>
        public void UpdateVideoFrame(IVideoFrame videoFrame)
        {
            this.videoRender?.UpdateVideoFrame(videoFrame);
        }

        /// <summary>
        /// 清理视频帧
        /// </summary>
        public void ClearVideoFrame()
        {
            this.videoRender.UpdateVideoFrame(null);
        }

        /// <summary>
        /// 渲染帧至图片
        /// </summary>
        /// <param name="plugins">需要处理渲染的插件名称<see cref="VideoControlPluginNames"/></param>
        /// <returns>图片</returns>
        public Mat RenderVideoToMat(List<string> plugins = null)
        {
            VideoRenderInfo renderInfo = this.videoRender.RenderInfo;
            if (renderInfo == null)
                return null;

            return this.RenderVideoToMat(renderInfo.Frame.Width, renderInfo.Frame.Height, plugins);
        }

        /// <summary>
        /// 渲染帧至图片
        /// </summary>
        /// <param name="width">图片宽度</param>
        /// <param name="height">图片高度</param>
        /// <param name="format">渲染格式</param>
        /// <param name="plugins">需要处理渲染的插件名称<see cref="VideoControlPluginNames"/></param>
        /// <returns>图片</returns>
        public Mat RenderVideoToMat(int width, int height, List<string> plugins = null)
        {
            SharpDX.WIC.Bitmap bmp = WicBitmapHelper.RenderToBitmap(width, height, this.videoRender.Render, plugins);

            Mat mat = new Mat(height, width, MatType.CV_8UC4);
            unsafe
            {
                bmp.CopyPixels(width * 4, new IntPtr(mat.DataPointer), width * height * 4);
            }

            return mat;
        }

        /// <summary>
        /// 附加插件
        /// </summary>
        /// <param name="plugin">插件</param>
        public void AttachPlugin(IVideoPlugin plugin)
        {
            lock (this.videoRender.Plugins)
            {
                this.videoRender.Plugins.Add(plugin);
                plugin.Attach();
            }
        }

        /// <summary>
        /// 卸载
        /// </summary>
        /// <param name="name">插件名称</param>
        public void DetachPlugin(string name)
        {
            IVideoPlugin plugin = this.videoRender.Plugins.FirstOrDefault(p => p.Name == name);
            if (plugin == null)
                return;

            lock (this.videoRender.Plugins)
            {
                this.videoRender.Plugins.Remove(plugin);
                plugin.Detach();
            }
        }

        /// <summary>
        /// 卸载所有插件
        /// </summary>
        public void DetachPluginAll()
        {
            lock (this.videoRender.Plugins)
            {
                foreach (IVideoPlugin plugin in this.videoRender.Plugins)
                {
                    plugin.Detach();
                }

                this.videoRender.Plugins.Clear();
            }
        }

        /// <summary>
        /// 获取插件
        /// </summary>
        /// <typeparam name="T">插件类型</typeparam>
        /// <param name="name">插件名称</param>
        /// <returns>插件</returns>
        public T GetPlugin<T>(string name) where T : class, IVideoPlugin
        {
            return this.videoRender.Plugins.FirstOrDefault(p => p.Name == name) as T;
        }

        /// <summary>
        /// 获取渲染信息
        /// </summary>
        public VideoRenderInfo GetRenderInfo()
        {
            return this.videoRender.RenderInfo;
        }
    }
}
