using System;
using System.Drawing.Imaging;
using System.Drawing;
using System.Runtime.InteropServices;
using Accord.Video;
using Accord.Video.FFMPEG;

namespace XHWK.WKTool.Utils
{
    using System.Linq;

    public class ZVideoRecordHelper
    {
        public enum RecordState
        {
            Stop = 0,
            Start = 1,
            Pause = 2
        }

        private RecordState _state = RecordState.Stop;

        private string _filePath;
        private int _width;
        private int _height;

        //录制帧率
        private int _rate = 5;

        //录制质量
        private int _quality = 8;

        private bool _captureMouse = false;

        private VideoFileWriter videoWriter = new VideoFileWriter();//视频写入
        private ScreenCaptureStream videoStreamer;//视频捕获

        public ZVideoRecordHelper(string filePath, int width, int height, int rate = 5, int quality = 8, bool captureMouse = false)
        {
            _filePath = filePath;
            _width = width / 2 * 2;
            _height = height / 2 * 2;
            _rate = rate;
            _quality = quality;
            _captureMouse = captureMouse;
            _state = RecordState.Pause;
            try
            {
                // 打开写入
                lock (this)
                {
                    videoWriter.Open(
                        _filePath,
                        _width,
                        _height,
                        _rate,
                        VideoCodec.MPEG4,
                        _width * _height * _quality
                    );
                }

                System.Drawing.Rectangle rec = new System.Drawing.Rectangle(0, 0, _width, _height);
                videoStreamer = new ScreenCaptureStream(rec, 1000 / _rate); //帧间隔需要和帧率关联，不然录的10秒视频文件不是10s
                videoStreamer.NewFrame += VideoNewFrame;
                videoStreamer.Start();
            }
            catch (Exception)
            {
            }
        }

        /// <summary>
        /// 开始录制
        /// </summary>
        public bool StartRecordVideo()
        {
            _state = RecordState.Start;
            return true;
        }

        [DllImport("user32.dll")]
        private static extern bool GetCursorInfo(out CURSORINFO pci);

        [StructLayout(LayoutKind.Sequential)]
        private struct POINT
        {
            public Int32 x;
            public Int32 y;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct CURSORINFO
        {
            public Int32 cbSize;
            public Int32 flags;
            public IntPtr hCursor;
            public POINT ptScreenPos;
        }

        // 帧返回时绘制上鼠标
        private void VideoNewFrame(object sender, NewFrameEventArgs e)
        {
            if (_state == RecordState.Start)
            {
                if (_captureMouse)
                {
                    var g = System.Drawing.Graphics.FromImage(e.Frame);
                    CURSORINFO pci;
                    pci.cbSize = Marshal.SizeOf(typeof(CURSORINFO));
                    GetCursorInfo(out pci);
                    try
                    {
                        System.Windows.Forms.Cursor cur = new System.Windows.Forms.Cursor(pci.hCursor);
                        cur.Draw
                        (
                            g,
                            new System.Drawing.Rectangle
                            (
                                System.Windows.Forms.Cursor.Position.X - 10,
                                System.Windows.Forms.Cursor.Position.Y - 10,
                                cur.Size.Width,
                                cur.Size.Height
                            )
                        );
                    }
                    catch { } //打开任务管理器时会导致异常
                }
                videoWriter.WriteVideoFrame(e.Frame);
            }
        }

        /// <summary>
        /// 结束录制
        /// </summary>
        public void StopRecordVideo()
        {
            _state = RecordState.Stop;
            // 停止
            videoStreamer.Stop();

            //结束写入
            videoWriter.Close();
            videoWriter.Dispose();
        }

        /// <summary>
        /// 暂停录制
        /// </summary>
        public void PauseRecordVideo()
        {
            _state = RecordState.Pause;
        }

        /// <summary>
        /// 恢复录制
        /// </summary>
        public void ResumeRecordVideo()
        {
            _state = RecordState.Start;
        }

        /// <summary>
        /// 生成缩略图
        /// </summary>
        /// <param name="mp4Path"></param>
        /// <param name="picPath"></param>
        public static void GetVideoPic(string mp4Path, string picPath)
        {
            using (var video = new VideoFileReader())
            {
                video.Open(mp4Path);
                int frameNum = video.FrameCount > 3 ? 3 : 0;
                using (var bmp = video.ReadVideoFrame(frameNum))
                {
                    SaveAsJpeg
                    (
                        bmp,
                        picPath,
                        90
                    );
                }
                video.Close();
            }
        }

        // 保存为jpeg格式，quality为图像质量（0-100）
        public static void SaveAsJpeg
        (
            Bitmap bitmap,
            string fileName,
            int quality
        )
        {
            var jpegEncoder = ImageCodecInfo.GetImageEncoders().First(codec => codec.FormatID == ImageFormat.Jpeg.Guid);
            var encoderParameters = new EncoderParameters(1);
            encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);
            bitmap.Save
            (
                fileName,
                jpegEncoder,
                encoderParameters
            );
        }
    }
}
