
#include "JavaEnv.h"
#include "JavaClass.h"

@implementation JavaClass

+ new:  (char *)name env: (id)_env  {
  self = [JavaClass alloc];

  fprintf(stderr, "creating... java class\n");
  return [self init: name env: _env];
}

- init: (char *)name env: (id)_env  {
  [super init];
  fprintf(stderr, "JavaClass %s in init\n", name);
  /* save a copy of our environment pointer */
  env = [_env getEnv];
  /* extract and save our java class id */
  clsid = [_env findClass: name];
  if (clsid == 0) {
    fprintf(stderr, "Couldn't find Java class %s\n", name);
    exit(1);
  }
  fprintf(stderr, "JavaClass leaving init\n");
  return self;
}

- (JNIEnv *)getEnv {
  return env;
}

//  various flavors of constructor

- (jobject) construct: (int) a : (int) b {
  jobject lobj, obj;

  // look up this flavor of constructor
  jmethodID constrID = [self findMethod: "<init>" signature: "(II)V"];

  if (constrID == 0)
    return 0;

  // call the constructor
  lobj = (*env)->NewObject(env, clsid, constrID, (jint)a, (jint)b);

  // turn this into a global reference
  obj = (*env)->NewGlobalRef(env, lobj);
  (*env)->DeleteLocalRef(env, lobj);

  // return the object id
  return obj;
}

/* get the method id for a particular java method */
- (jmethodID) findMethod: (char *)method signature: (char *)sig {

  jmethodID mid = (*env)->GetMethodID(env, clsid, method, sig);
  if (mid == 0) {
    fprintf(stderr, "warning: can't find method %s\n", method);
    exit(1);
  }

  return mid;
}

/* get the method id for a particular java method */
- (jmethodID) findStaticMethod: (char *)method signature: (char *)sig {

  jmethodID mid = (*env)->GetStaticMethodID(env, clsid, method, sig);
  if (mid == 0) {
    fprintf(stderr, "warning: can't find static method %s\n", method);
    exit(1);
  }

  return mid;
}

/* call a static java method; no args, returns object */
- (jobject) callObjectStaticMethod: (jmethodID) mid {

  if (mid == 0) {
    fprintf(stderr, "callObjectStaticMethod: illegal method id\n");
    exit(1);
  }
    
  return (*env)->CallStaticObjectMethod(env, clsid, mid);
}

@end

