#include <jni.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <syslog.h>
#include <ctype.h>

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM * jvm, void * reserved);
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM * jvm, void * reserved);
JNIEXPORT jboolean JNICALL Java_kindle_test_jni_jni_JniLibrary_isGreaterThan100(JNIEnv * env, jclass cls, jstring number);
JNIEXPORT jstring JNICALL Java_kindle_test_jni_JniLibrary_converCase(JNIEnv * env, jclass cls, jboolean b, jstring txt);
JNIEXPORT jstring JNICALL Java_kindle_test_jni_JniLibrary_add5Numbers(JNIEnv * env, jclass cls, jint b1, jint b2, jint b3, jint b4, jint b5);

JavaVM * cached_jvm = NULL;

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM * jvm, void * reserved)
{
	JNIEnv * env;
	cached_jvm = jvm;

	if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) {
		syslog(LOG_ERR, "JNI version not supported.");
		return JNI_ERR; /* JNI version not supported */
	}
	syslog(LOG_ERR, "JNI Loaded.");
	return JNI_VERSION_1_4;
}

JNIEXPORT void JNICALL JNI_OnUnload(JavaVM * jvm, void * reserved)
{
	JNIEnv * env;

	if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) {
		syslog(LOG_ERR, "JNI version not supported.");
		return;
	}
	syslog(LOG_ERR, "JNI Unloaded.");
	return;
}

JNIEXPORT jboolean JNICALL Java_kindle_test_jni_JniLibrary_isGreaterThan100(JNIEnv * env, jclass cls, jstring number)
{
    const char* str;
    str = (*env)->GetStringUTFChars(env, number, NULL);

    if (str == NULL) {
        return 0; /* OutOfMemoryError already thrown */
    }

    syslog(LOG_ERR, "isGreaterThan100: %s." , str);

    int n = atoi(str);

    (*env)->ReleaseStringUTFChars(env, number, str);

    return n>100 ? 1 : 0;
}

JNIEXPORT jstring JNICALL Java_kindle_test_jni_JniLibrary_converCase(JNIEnv * env, jclass cls, jboolean c, jstring txt)
{
    const char *str;
    str = (*env)->GetStringUTFChars(env, txt, NULL);

    if (str == NULL) {
        return 0; /* OutOfMemoryError already thrown */
    }

    char* dup = strdup(str);
    char* r = dup;

    if(c == 0)
    {
        for(;*r != '\0'; r++)
            *r = tolower((unsigned char)*r);
    }
    else
    {
        for(;*r != '\0'; r++)
            *r = toupper((unsigned char)*r);
    }

    syslog(LOG_ERR, "converCase: %d %s => %s." , c, str, dup);

    jstring ret = (*env)->NewStringUTF(env, dup);

    (*env)->ReleaseStringUTFChars(env, txt, str);
    free(dup);

    return ret;
}

JNIEXPORT jstring JNICALL Java_kindle_test_jni_JniLibrary_add5Numbers(JNIEnv * env, jclass cls, jint b1, jint b2, jint b3, jint b4, jint b5)
{
    char buf[80];
    snprintf(buf, 80, "%d + %d + %d + %d + %d = %lld.", b1,b2,b3,b4,b5, (long long)b1+b2+b3+b4+b5);
    syslog(LOG_ERR, "add5Numbers: %s.", buf);

    return (*env)->NewStringUTF(env, buf);
}
