/*
 * Copyright (c) 1995-1997 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for NON-COMMERCIAL purposes and without
 * fee is hereby granted provided that this copyright notice
 * appears in all copies. Please refer to the file "copyright.html"
 * for further important copyright and licensing information.
 *
 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 */
/* Note: This program only works on Win32.
*/
#include <windows.h>
#include <jni.h>

JavaVM *jvm;

void thread_fun(void *arg)
{
    jint res;
    jclass cls;
    jmethodID mid;
    jstring jstr;
    jobjectArray args;
    JNIEnv *env;
    char buf[100];
    int threadNum = (int)arg;

    JDK1_1AttachArgs targs;

    res = (*jvm)->AttachCurrentThread(jvm, &env, &targs);
    if (res < 0) {
       fprintf(stderr, "Thread %d: attach failed\n", threadNum);
       return;
    }

    cls = (*env)->FindClass(env, "Prog");
    if (cls == 0) {
        fprintf(stderr, "Thread %d: Can't find Prog class\n", threadNum);
        return;
    }

    mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V");
    if (mid == 0) {
        fprintf(stderr, "Thread %d: Can't find Prog.main\n", threadNum);
	return;
    }

    sprintf(buf, " from Thread %d", threadNum);
    jstr = (*env)->NewStringUTF(env, buf);
    if (jstr == 0) {
        fprintf(stderr, "Thread %d: Out of memory\n", threadNum);
        return;
    }
    args = (*env)->NewObjectArray(env, 1,
                        (*env)->FindClass(env, "java/lang/String"), jstr);
    if (args == 0) {
        fprintf(stderr, "Thread %d: Out of memory\n", threadNum);
        return;
    }
    args = (*env)->NewObjectArray(env, 1,
                        (*env)->FindClass(env, "java/lang/String"), jstr);
    if (args == 0) {
        fprintf(stderr, "Thread %d: Out of memory\n", threadNum);
        return;
    }
    (*env)->CallStaticVoidMethod(env, cls, mid, args);
    (*jvm)->DetachCurrentThread(jvm);
}

main() {
    JNIEnv *env;
    JDK1_1InitArgs vm_args;
    int i;
    jint res;

    /* IMPORTANT: specify vm_args version # if you use JDK1.1.2 and beyond */
    vm_args.version = 0x00010001;

    JNI_GetDefaultJavaVMInitArgs(&vm_args);
    res = JNI_CreateJavaVM(&jvm, &env, &vm_args);
    if (res < 0) {
        fprintf(stderr, "Can't create Java VM\n");
        exit(1);
    }

    for (i=0; i<5; i++)
        /* We pass the thread number as the argument to every thread */
        _beginthread(thread_fun,0,(void *)i);

    Sleep(5000); /* wait for threads to finish */

    (*jvm)->DestroyJavaVM(jvm);
}

