using System;
using System.Runtime.InteropServices;

using Accord.Video;
using Accord.Video.FFMPEG;

namespace XHWK.WKTool.Utils
{
    public class ZVideoRecordHelper
    {
        public enum RecordState
        {
            stop = 0,
            start = 1,
            pause = 2
        }

        private RecordState _state = RecordState.stop;

        private string _filePath = "";
        private int _width = 0;
        private int _height = 0;

        //录制帧率
        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;
        }
    }
}