namespace XHWK.WKTool.system
{
    using System;
    using System.Collections.Generic;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Windows.Media.Imaging;
    using System.Windows.Threading;
    using AForge.Video.DirectShow;

    public static class CameraHelper
    {
        private static List<FilterInfo> _cameraDevices;
        private static VideoCaptureDevice _vedioCapture;

        private static Dispatcher _dispatcher;
        public static Action<BitmapImage> imageCallback;

        /// <summary>
        /// 获取或设置摄像头设备，无设备为null
        /// </summary>
        public static List<FilterInfo> CameraDevices
        {
            get => _cameraDevices;
            set => _cameraDevices = value;
        }

        /// <summary>
        /// 更新摄像头设备信息
        /// </summary>
        public static void UpdateCameraDevices()
        {
            // ReSharper disable once CollectionNeverUpdated.Local
            var devs = new FilterInfoCollection(FilterCategory.VideoInputDevice); //获取摄像头列表
            List<FilterInfo> allCamera = new List<FilterInfo>();
            foreach (FilterInfo dev in devs)
            {
                if (dev.Name != "screen-capture-recorder" && dev.Name != "OBS Virtual Camera")
                {
                    allCamera.Add(dev);
                }
            }
            _cameraDevices = allCamera;
        }

        /// <summary>
        /// 设置使用的摄像头设备
        /// </summary>
        /// <param name="index">设备在CameraDevices中的索引</param>
        /// <param name="dispatcher"></param>
        /// <returns><see cref="bool"/></returns>
        public static bool StartCameraDevice(int index, Dispatcher dispatcher)
        {
            _dispatcher = dispatcher;

            //无设备，返回false
            if (_cameraDevices.Count <= 0 || index < 0)
            {
                return false;
            }
            if (index > _cameraDevices.Count - 1)
            {
                return false;
            }
            // 设定初始视频设备
            _vedioCapture = new VideoCaptureDevice(_cameraDevices[index].MonikerString);
            _vedioCapture.NewFrame += VedioCaptureNewFrame;
            _vedioCapture.Start();
            return true;
        }

        private static void VedioCaptureNewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs)
        {
            _dispatcher?.Invoke
            (
                () =>
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        eventArgs.Frame.Save(ms, ImageFormat.Bmp);
                        BitmapImage image = new BitmapImage { CacheOption = BitmapCacheOption.OnLoad };
                        image.BeginInit();
                        image.StreamSource = new MemoryStream(ms.GetBuffer());
                        image.EndInit();
                        imageCallback?.Invoke(image);
                    }
                }
            );
        }

        /// <summary>
        /// 关闭摄像头设备
        /// </summary>
        public static void CloseDevice()
        {
            try
            {
                if (_vedioCapture != null)
                {
                    _vedioCapture.NewFrame -= VedioCaptureNewFrame;
                    if (_vedioCapture.IsRunning)
                    {
                        _vedioCapture.SignalToStop();
                    }
                    _vedioCapture = null;
                }
            }
            catch (Exception)
            {
                // ignored
            }
        }
    }
}
