// GLCanvas.h
#ifndef GLCANVAS_H
#define GLCANVAS_H

//#include <mutex>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <native_window/external_window.h> // HarmonyOS 原生窗口头文件
#include <set>
#include <string>
#include "RNGLContext/RNGLContext.h"
#include "GLData/GLData.h"
#include "GLShader/GLShader.h"
#include "GLFBO/GLFBO.h"
#include "GLRenderData/GLRenderData.h"
#include "GLImage/GLImage.h"
#include "GLTexture/GLTexture.h"

class GLCanvas
{
public:
    GLCanvas(std::shared_ptr<RNGLContext> rnglContext); // 构造函数，接收环境和配置
    ~GLCanvas();

    bool OnSurfaceCreated(OHNativeWindow* window); // Surface 创建方法
    void OnSurfaceChanged(int width, int height);
    void DrawFrame(); // 绘制帧
    
    void UpdateSize(int width, int height);
    void SetRNGLContext(std::shared_ptr<RNGLContext> rnglContext);
    void SetData(const std::string& data); // 设置数据
    std::shared_ptr<GLData> DealData(const std::string& jsonData);
    void AddImageData(const std::string& src, std::shared_ptr<ImageData>& data);
    void CaptureFrame(const std::string& filePath);
    void resizeUniformContentTextures (int n);
    
    std::shared_ptr<GLFBO> GetFBO(int& id);
    std::shared_ptr<GLShader> GetShader(int& id);
    bool InitEGL(void* window); // 初始化 EGL
    void DestroyEGL(); // 销毁 EGL 资源
    
    int CountPreloaded();
    std::shared_ptr<OnProgressData> GetOnProgressData();
    EGLContext GetEGLContext();

private:
    bool CreateEnvironment();
    
    bool haveRemainingToPreload();
    void onImageLoad(const std::string& loaded);
    std::shared_ptr<GLRenderData> recSyncData(const std::shared_ptr<GLData> data, std::unordered_map<std::string, std::shared_ptr<GLImage>>& newImages);
    bool syncData();
    void recRender (const std::shared_ptr<GLRenderData>& renderData);
    void render();
    void capture(const std::string& filePath);
    int arraySizeForType(int type);
    
    std::shared_ptr<GLData> data;

    std::vector<std::string> imagesToPreload;
    std::vector<std::string> preloaded;
    std::unordered_map<std::string, std::shared_ptr<ImageData>> imagesData;

    std::unordered_map<std::string, std::shared_ptr<GLImage>> images;
    std::vector<std::shared_ptr<GLTexture>> contentTextures;
    std::unordered_map<int, std::shared_ptr<GLShader>> shaders;
    std::unordered_map<int, std::shared_ptr<GLFBO>> fbos;
    std::shared_ptr<GLRenderData> renderData;

    std::mutex renderMutex_; // 互斥锁，保护渲染操作
    EGLNativeWindowType m_eglWindow;
    EGLDisplay m_eglDisplay = EGL_NO_DISPLAY;     // EGL 显示设备
    EGLConfig m_eglConfig = EGL_NO_CONFIG_KHR;
    EGLSurface m_eglSurface = EGL_NO_SURFACE;     // EGL 渲染表面
    EGLContext m_eglContext = EGL_NO_CONTEXT;     // EGL 上下文

    int m_width;
    int m_height;
    int defaultFBO_;
    float pixelRatio_;
    float displayDensity_;
    bool autoRedraw_;
    bool dirtyOnLoad = true;
    bool neverRendered = true;
    bool deferredRendering = false;

    // 其他可能的成员变量
    std::shared_ptr<RNGLContext> rnglContext;
};

template<typename A>
std::set<A> diff(const std::set<A>& a, const std::set<A>& b) {
    std::set<A> d;
    // 遍历集合 a 中的每个元素
    for (const auto& element : a) {
        // 检查元素是否不在集合 b 中
        if (b.find(element) == b.end()) {
            // 如果不在，将其插入到结果集合 d 中
            d.insert(element);
        }
    }
    return d;
}

#endif // GLCANVAS_H