#include <jni.h>
#include "../../../c/android/fac.h"
#include <android/log.h>
#include "../../../c/issm.h"
#include <cstddef>
#include <stdio.h>

namespace com_example_issm
{
	/*Global variables{{{*/
	fac* f;
	FemModel *fm;
	/*}}}*/
	jint initialize(JNIEnv *env, jclass clazz, jstring jsolution_type, jstring jabsfile, jstring jrelfile) /*{{{*/
	{
		
		/*arguments to constructor: */
		int argc; //arguments to constructor.
		char** argv = NULL;
		COMM    communicator = 1; //fake communicator for constructor
		const char* issmname = "issm.exe";
		char *solution_type = NULL;
		char *absfile = NULL;
		char *relfile = NULL;

		/*retrieve from java machine: */
		solution_type = (char*)env->GetStringUTFChars(jsolution_type,0);
		absfile = (char*)env->GetStringUTFChars(jabsfile,0);
		relfile = (char*)env->GetStringUTFChars(jrelfile,0);

		/*creat arguments to call constructor for FemModel: */
		argc=4; 
		argv=(char**)malloc(argc*sizeof(char*));
		argv[0]=(char*)issmname;
		argv[1]=solution_type;
		argv[2]=absfile;
		argv[3]=relfile;

		f = new fac();

		/*call Model constructor passing in infile as File Descriptor parameter.*/
		fm  = new FemModel(argc,argv,communicator);

		/*release strings: */
		env->ReleaseStringUTFChars(jsolution_type, solution_type); //must realease the char*
		env->ReleaseStringUTFChars(jabsfile, absfile); //must realease the char*
		env->ReleaseStringUTFChars(jrelfile, relfile); //must realease the char*

		/*figure out size of solution: */
		//jint size = (jint) fm->bufferSize();
		jint size =8;
		
		return size;

	}
	/*}}}*/
	void solve(JNIEnv *env, jclass clazz , jint alpha, jobject buf) /*{{{*/
	{
		/*fill out the first two slots, extract the same way in java using get(int position)*/
		jdouble *dBuf = (jdouble *)env->GetDirectBufferAddress(buf);

		//pass bBuff to fem model to allocate data
		// fm -> solve(dBuf, alpha);

	}/*}}}*/
	jlong factorial(JNIEnv *env, jclass clazz, jlong n) /*{{{*/
	{
		if( f != NULL)
			return (jlong) (f->factorial(n));
		return 0;
	}
	/*}}}*/
	static JNINativeMethod method_table[] = /*{{{*/
	{
			{"fac"      	,     "(J)J" 	, (void *) factorial},
			{"createISSMModel"   ,"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I"  , (void *) initialize},
			{"processBuffer", "(ILjava/nio/DoubleBuffer;)V", (void *) solve}
	};
	/*}}}*/
}

using namespace com_example_issm;
extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) /*{{{*/
{
    JNIEnv* env;
    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
        return -1;
    }
    else
    {
    	jclass clazz = env->FindClass("com/example/issm/IssmJni");
    	if(clazz)
    	{
    		env->RegisterNatives(clazz, method_table, 3);
    		env->DeleteLocalRef(clazz);
    		return JNI_VERSION_1_6;
    	}
    	else return -1;
    }
}
/*}}}*/
