//
// Created by Fear1ess on 2021/4/1.
//

#ifndef REYUNSDK_JNI_HELPER_H
#define REYUNSDK_JNI_HELPER_H

#include <jni.h>

void wdCheckException(JNIEnv* env);
char wdGetMethodRetType(const char* sig);
char wdGetFieldType(const char* sig) { return *sig; }
jvalue wdGetStaticField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig);
jvalue wdGetField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig);
void wdSetStaticField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig, jvalue value);
void wdSetField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig, jvalue value);
jobject wdNewObject(JNIEnv* env, const char* clsName, const char* methodSig, ...);
jvalue wdCallStaticMethod(JNIEnv* env, const char* clsName, const char* methodName, const char* methodSig, va_list args);
jvalue wdCallMethod(JNIEnv* env, jobject obj, const char* methodName, const char* methodSig, va_list args);
jboolean wdCallStaticBooleanMethod(JNIEnv* env, const char* clsName, const char* methodName, const char* methodSig, ...);
jbyte wdCallStaticByteMethod(JNIEnv* env, const char* clsName, const char* methodName, const char* methodSig, ...);
jchar wdCallStaticCharMethod(JNIEnv* env, const char* clsName, const char* methodName, const char* methodSig, ...);
jshort wdCallStaticShortMethod(JNIEnv* env, const char* clsName, const char* methodName, const char* methodSig, ...);
jint wdCallStaticIntMethod(JNIEnv* env, const char* clsName, const char* methodName, const char* methodSig, ...);
jlong wdCallStaticLongMethod(JNIEnv* env, const char* clsName, const char* methodName, const char* methodSig, ...);
jfloat wdCallStaticFloatMethod(JNIEnv* env, const char* clsName, const char* methodName, const char* methodSig, ...);
jdouble wdCallStaticDoubleMethod(JNIEnv* env, const char* clsName, const char* methodName, const char* methodSig, ...);
void wdCallStaticVoidMethod(JNIEnv* env, const char* clsName, const char* methodName, const char* methodSig, ...);
jboolean wdCallBooleanMethod(JNIEnv* env, jobject obj, const char* methodName, const char* methodSig, ...);
jbyte wdCallByteMethod(JNIEnv* env, jobject obj, const char* methodName, const char* methodSig, ...);
jchar wdCallCharMethod(JNIEnv* env, jobject obj, const char* methodName, const char* methodSig, ...);
jshort wdCallShortMethod(JNIEnv* env, jobject obj, const char* methodName, const char* methodSig, ...);
jint wdCallIntMethod(JNIEnv* env, jobject obj, const char* methodName, const char* methodSig, ...);
jlong wdCallLongMethod(JNIEnv* env, jobject obj, const char* methodName, const char* methodSig, ...);
jfloat wdCallFloatMethod(JNIEnv* env, jobject obj, const char* methodName, const char* methodSig, ...);
jdouble wdCallDoubleMethod(JNIEnv* env, jobject obj, const char* methodName, const char* methodSig, ...);
void wdCallVoidMethod(JNIEnv* env, jobject obj, const char* methodName, const char* methodSig, ...);

inline jboolean wdGetStaticBooleanField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig) {
    return wdGetStaticField(env, clsName, fieldName, fieldSig).z;
}
inline jbyte wdGetStaticByteField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig) {
    return wdGetStaticField(env, clsName, fieldName, fieldSig).b;
}
inline jchar wdGetStaticCharField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig) {
    return wdGetStaticField(env, clsName, fieldName, fieldSig).c;
}
inline jshort wdGetStaticShortField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig) {
    return wdGetStaticField(env, clsName, fieldName, fieldSig).s;
}
inline jint wdGetStaticIntField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig) {
    return wdGetStaticField(env, clsName, fieldName, fieldSig).i;
}
inline jlong wdGetStaticLongField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig) {
    return wdGetStaticField(env, clsName, fieldName, fieldSig).j;
}
inline jfloat wdGetStaticFloatField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig) {
    return wdGetStaticField(env, clsName, fieldName, fieldSig).f;
}
inline jdouble wdGetStaticDoubleField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig) {
    return wdGetStaticField(env, clsName, fieldName, fieldSig).d;
}
inline jobject wdGetStaticObjectField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig) {
    return wdGetStaticField(env, clsName, fieldName, fieldSig).l;
}


inline jboolean wdGetBooleanField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig) {
    return wdGetField(env, obj, fieldName, fieldSig).z;
}
inline jbyte wdGetByteField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig) {
    return wdGetField(env, obj, fieldName, fieldSig).b;
}
inline jchar wdGetCharField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig) {
    return wdGetField(env, obj, fieldName, fieldSig).c;
}
inline jshort wdGetShortField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig) {
    return wdGetField(env, obj, fieldName, fieldSig).s;
}
inline jint wdGetIntField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig) {
    return wdGetField(env, obj, fieldName, fieldSig).i;
}
inline jlong wdGetLongField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig) {
    return wdGetField(env, obj, fieldName, fieldSig).j;
}
inline jfloat wdGetFloatField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig) {
    return wdGetField(env, obj, fieldName, fieldSig).f;
}
inline jdouble wdGetDoubleField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig) {
    return wdGetField(env, obj, fieldName, fieldSig).d;
}
inline jobject wdGetObjectField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig) {
    return wdGetField(env, obj, fieldName, fieldSig).l;
}


inline void wdSetStaticBooleanField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig, jboolean value) {
    jvalue j = {.z = value};
    wdSetStaticField(env, clsName, fieldName, fieldSig, j);
}
inline void wdSetStaticByteField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig, jbyte value) {
    jvalue j = {.b = value};
    wdSetStaticField(env, clsName, fieldName, fieldSig, j);
}
inline void wdSetStaticCharField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig, jchar value) {
    jvalue j = {.c = value};
    wdSetStaticField(env, clsName, fieldName, fieldSig, j);
}
inline void wdSetStaticShortField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig, jshort value) {
    jvalue j = {.s = value};
    wdSetStaticField(env, clsName, fieldName, fieldSig, j);
}
inline void wdSetStaticIntField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig, jint value) {
    jvalue j = {.i = value};
    wdSetStaticField(env, clsName, fieldName, fieldSig, j);
}
inline void wdSetStaticLongField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig, jlong value) {
    jvalue j = {.j = value};
    wdSetStaticField(env, clsName, fieldName, fieldSig, j);
}
inline void wdSetStaticFloatField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig, jfloat value) {
    jvalue j = {.f = value};
    wdSetStaticField(env, clsName, fieldName, fieldSig, j);
}
inline void wdSetStaticDoubleField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig, jdouble value) {
    jvalue j = {.d = value};
    wdSetStaticField(env, clsName, fieldName, fieldSig, j);
}
inline void wdSetStaticObjectField(JNIEnv* env, const char* clsName, const char* fieldName, const char* fieldSig, jobject value) {
    jvalue j = {.l = value};
    wdSetStaticField(env, clsName, fieldName, fieldSig, j);
}

inline void wdSetBooleanField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig, jboolean value) {
    jvalue j = {.z = value};
    wdSetField(env, obj, fieldName, fieldSig, j);
}
inline void wdSetByteField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig, jbyte value) {
    jvalue j = {.b = value};
    wdSetField(env, obj, fieldName, fieldSig, j);
}
inline void wdSetCharField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig, jchar value) {
    jvalue j = {.c = value};
    wdSetField(env, obj, fieldName, fieldSig, j);
}
inline void wdSetShortField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig, jshort value) {
    jvalue j = {.s = value};
    wdSetField(env, obj, fieldName, fieldSig, j);
}
inline void wdSetIntField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig, jint value) {
    jvalue j = {.i = value};
    wdSetField(env, obj, fieldName, fieldSig, j);
}
inline void wdSetLongField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig, jlong value) {
    jvalue j = {.j = value};
    wdSetField(env, obj, fieldName, fieldSig, j);
}
inline void wdSetFloatField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig, jfloat value) {
    jvalue j = {.f = value};
    wdSetField(env, obj, fieldName, fieldSig, j);
}
inline void wdSetDoubleField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig, jdouble value) {
    jvalue j = {.d = value};
    wdSetField(env, obj, fieldName, fieldSig, j);
}
inline void wdSetObjectField(JNIEnv* env, jobject obj, const char* fieldName, const char* fieldSig, jobject value) {
    jvalue j = {.l = value};
    wdSetField(env, obj, fieldName, fieldSig, j);
}




#endif //REYUNSDK_JNI_HELPER_H