using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace Assets.scripts.utils
{    
    public class VideoHelp
    {
        private class VideoInfo
        {
            public int width;
            public int height;
            public int cid;
            public string path;
            public int fps;
            public Byte[] bytes;
            public IntPtr intPtr;
        }
        //extern "C" DLL_EXPORT_IMPORT int CreateVideo(char* path, int width, int height, int fps);
        //extern "C" DLL_EXPORT_IMPORT bool pushFrameData(int id, char* data, int dataLen);
        //extern "C" DLL_EXPORT_IMPORT void closeVideo(int id);
        //extern "C" DLL_EXPORT_IMPORT void imagesToVideo_Test(const char* imageFolderPath, const char* outputVideoPath, int width, int height, int fps);

        static Dictionary<string,VideoInfo> videoPools = new Dictionary<string, VideoInfo>();
        // 导入FFmpeg的C/C++库
        [DllImport("videoTestLib", CallingConvention = CallingConvention.Cdecl)]
        private static extern int CreateVideo(string path,int width,int height,int fps);

        [DllImport("videoTestLib", CallingConvention = CallingConvention.Cdecl)]
        private static extern bool pushFrameData(int id,IntPtr intPtr,int len);

        [DllImport("videoTestLib", CallingConvention = CallingConvention.Cdecl)]
        private static extern void closeVideo(int id);
        //[DllImport("libavcodec.so", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
        //public static extern int avcodec_encode_video2(IntPtr avctx, IntPtr avpkt, IntPtr frame, out int got_packet_ptr);


        public static bool Open(string id,string path, int width, int height, int fps)
        {
            if(videoPools.ContainsKey(id) == false)
            {
                //暂时不清楚为啥close崩溃 ，而且好像并未实际写入数据
                int kid = -1;// CreateVideo(path,width,height,fps);
                if (kid < 0) return false;
                VideoInfo videoInfo = new VideoInfo();
                videoInfo.width = width;
                videoInfo.height = height;
                videoInfo.fps = fps;
                videoInfo.path = path;
                videoInfo.cid = kid;
                videoInfo.bytes = new byte[(int)(width * height * 2.5)];
                videoInfo.intPtr = Marshal.AllocHGlobal(videoInfo.bytes.Length);
                videoPools.Add(id, videoInfo);
            }
            return false;
        }
        public static IntPtr ConvertToIntPtr(byte[] data)
        {
            IntPtr intPtr = Marshal.AllocHGlobal(data.Length);
            Marshal.Copy(data, 0, intPtr, data.Length);
            return intPtr;
        }

        public static bool PushColors(string id, Color[] colors)
        {
            if (videoPools.ContainsKey(id) == false) return false;
            var temp = videoPools[id];
            int width = temp.width;
            int height = temp.height;
            utilsTools.RGBtoYUV(colors, temp.bytes, width, height);
            Marshal.Copy(temp.bytes, 0, temp.intPtr, temp.bytes.Length);
            //IntPtr data = ConvertToIntPtr(bytes);
            pushFrameData(temp.cid, temp.intPtr, temp.bytes.Length);
            //Marshal.FreeHGlobal(data);
            return true;
        }
        public static bool Close(string id)
        {
            if (videoPools.ContainsKey(id) == false) return false;
            var temp = videoPools[id];
            closeVideo(temp.cid);
            Marshal.FreeHGlobal(temp.intPtr);
            temp.bytes = null;
            videoPools.Remove(id);
            return false;
        }
    }
}