// JavaStarter.cpp : Defines the entry point for the application.
//

#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include <tchar.h>
#include <jni.h>

typedef jint (JNICALL *JNI_CreateJavaVM_t)(JavaVM **pvm, void **env, void *args);

int APIENTRY _tWinMain(HINSTANCE hInstance,
					   HINSTANCE hPrevInstance,
					   LPTSTR    lpCmdLine,
					   int       nCmdShow)
{
	// create Java virtual machine
	JavaVMInitArgs vm_args;
	JavaVMOption options[1];
	options[0].optionString = "-Djava.library.path=c:\\testpath";  /* here you can set your native library path */
	vm_args.version = JNI_VERSION_1_2;
	vm_args.options = options;
	vm_args.nOptions = 1;
	vm_args.ignoreUnrecognized = TRUE;
	JNIEnv *env;
	JavaVM *jvm;
	// TODO: read path from registry
	HINSTANCE handle = LoadLibrary("C:\\j2sdk\\jre\\bin\\client\\jvm.dll");
	if (handle == 0) return FALSE;
	JNI_CreateJavaVM_t CreateJavaVM = (JNI_CreateJavaVM_t) GetProcAddress(handle, "JNI_CreateJavaVM");
	if (JNI_CreateJavaVM == NULL) return FALSE;
	if (CreateJavaVM(&jvm, (void **)&env, &vm_args) < 0) return FALSE;

	// start main method in the class MyTest
	jclass cls = env->FindClass("MyTest");
	if (cls == 0) return FALSE;
	jmethodID  mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");
	if (mid == 0) return FALSE;
	jstring jstr = env->NewStringUTF(" from C!");
	if (jstr == 0) return FALSE;
	// TODO: fill with parsed lpCmdLine
	jobjectArray args = env->NewObjectArray(1, env->FindClass("java/lang/String"), jstr);
	if (args == 0) return FALSE;
	env->CallStaticVoidMethod(cls, mid, args);

	// end Java virtual machine
	// note: DestroyJavaVM waits for all Java threads until they end and calls exit()
	jvm->DetachCurrentThread();
	jvm->DestroyJavaVM();

	// is never reached
	return TRUE;
}
