//
// Created by Allen on 24/08/29.
//

#include "JsiDce.h"
#define JSI_FUNC [](Runtime &runtime, const Value &thisValue, const Value *arguments, size_t count) -> Value

jobject jImageEditorViewModule = nullptr;


void install_editorView_methods(Runtime &jsiRuntime) {
    jsi_install::dce::install_editorView_setOriginalImage(jsiRuntime);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_dynamsoft_reactnativelib_dce_ImageEditorViewModuleImpl_nativeInstall(JNIEnv *env, jobject thiz, jlong jsiPtr) {
    if (!env->IsSameObject(jImageEditorViewModule, thiz)) {
        jImageEditorViewModule = env->NewWeakGlobalRef(thiz);
    }
    auto rt = reinterpret_cast<Runtime *>(jsiPtr);
    install_editorView_methods(*rt);
}


namespace jsi_install::dce {
void install_editorView_setOriginalImage(Runtime &jsiRuntime) {
    auto nameID = PropNameID::forAscii(jsiRuntime, "editorView_setOriginalImage");
    if(!jsiRuntime.global().hasProperty(jsiRuntime, nameID)) {
        auto setOriginalImageFcn = Function::createFromHostFunction(jsiRuntime, nameID, 2, JSI_FUNC {
            auto imageDataObj = arguments[1].asObject(runtime);
            auto imageDataHostObject = ImageDataHostObject::getHOFromObject(runtime, std::move(imageDataObj));
            setOriginalImageDataHOToEditorView(runtime, imageDataHostObject, (int) arguments[0].asNumber());
            return {};
        });
        jsiRuntime.global().setProperty(jsiRuntime, nameID, std::move(setOriginalImageFcn));
    }
}
}//namespace jsi_install::dce

void setOriginalImageDataHOToEditorView(Runtime &rt, ImageDataHostObject &imageDataHO, int viewTag) {
    JNIEnv *env;
    bool needDetach = false;
    int state = gJvm->GetEnv((void **) &env, JNI_VERSION_1_6);
    if (state == JNI_EDETACHED || env == nullptr) {
        gJvm->AttachCurrentThread(&env, nullptr);
        needDetach = true;
    }
    auto clzImageEditorViewModule = env->GetObjectClass(jImageEditorViewModule);
    auto setOriginalImageCalledInJSI =
            env->GetMethodID(clzImageEditorViewModule, "setOriginalImageCalledInJSI", "(Lcom/dynamsoft/core/basic_structures/ImageData;I)V");
    auto jImageData = jsiConversion::core::getJImageDataFromHO(env, imageDataHO);
    env->CallVoidMethod(jImageEditorViewModule, setOriginalImageCalledInJSI, jImageData, viewTag);
    env->DeleteLocalRef(clzImageEditorViewModule);
    env->DeleteLocalRef(jImageData);
    if (needDetach) {
        gJvm->DetachCurrentThread();
    }
}
