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

    public static class CameraHelper
    {
        private static List<FilterInfo> _cameraDevices;
        private static VideoCaptureDevice _div;
        private static readonly VideoSourcePlayer SourcePlayer = new VideoSourcePlayer();

        //指示_isDisplay设置为true后，是否设置了其他的sourcePlayer，若未设置则_isDisplay重设为false

        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;
            }
            // 设定初始视频设备
            _div = new VideoCaptureDevice(_cameraDevices[index].MonikerString);
            _div.NewFrame += _div_NewFrame;
            SourcePlayer.VideoSource = _div;
            _div.Start();
            SourcePlayer.Start();
            return true;
        }

        private static void _div_NewFrame(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>
        /// <param name="filePath">图像保存路径</param>
        /// <param name="fileName">保存的图像文件名</param>
        /// <returns>如果保存成功，则返回完整路径，否则为 null</returns>
        public static string CaptureImage(string filePath, string fileName = null)
        {
            if (SourcePlayer.VideoSource == null)
            {
                return null;
            }
            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }
            try
            {
                Image bitmap = SourcePlayer.GetCurrentVideoFrame();
                if (bitmap != null)
                {
                    if (fileName == null)
                    {
                        fileName = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss");
                    }
                    string fullPath = Path.Combine(filePath, fileName + "-cap.jpg");
                    Bitmap objNewPic = new Bitmap
                    (
                        bitmap,
                        172,
                        124
                    ); //图片保存的大小尺寸  
                    objNewPic.Save(fullPath, ImageFormat.Jpeg);
                    //bitmap.Save(fullPath, ImageFormat.Jpeg);
                    bitmap.Dispose();
                    objNewPic.Dispose();
                    return fullPath;
                }
                return null;
            }
            catch (Exception)
            {
                return null;
            }
        }

        /// <summary>
        /// 关闭摄像头设备
        /// </summary>
        public static void CloseDevice()
        {
            if (_div != null)
            {
                _div.NewFrame -= _div_NewFrame;
                if (SourcePlayer.IsRunning)
                {
                    SourcePlayer.Stop();
                }
                if (_div.IsRunning)
                {
                    _div.SignalToStop();
                }
                _div = null;
            }
        }
    }
}
