#ifndef _REFLECT_H_
#define _REFLECT_H_

#include <jni.h>
#include <jni_md.h> // This one contains all the neccessary type mapping (had i known this earlier...)

namespace JClass {
  extern jobjectArray getMethods(JNIEnv*, jclass, jboolean);
  extern jobjectArray getConstructors(JNIEnv*, jclass, jboolean);
  extern jobjectArray getFields(JNIEnv*, jclass, jboolean);
  extern char* toString(JNIEnv*, jclass);
  extern char* getSignature(JNIEnv*, jclass);
};

namespace JMethod {
  extern char* toString(JNIEnv* env, jobject method);
  extern jobjectArray getParameterTypes(JNIEnv*, jobject);
  extern jclass getSpecialParameter(JNIEnv*, jobject, jint);
  extern jint getParameterNumber(JNIEnv*, jobject);
  extern char* getName(JNIEnv*, jobject);
  extern jint getModifiers(JNIEnv*, jobject); 
  extern jclass getReturnType(JNIEnv*, jobject); 
  extern char* getSignature(JNIEnv*, jobject, jint*);
  extern jboolean isaNumber(JNIEnv*, jobject);
};

namespace JModifier {
  extern jboolean isStatic(JNIEnv*, jint);
  extern jboolean isPublic(JNIEnv*, jint);
  extern jboolean isPrivate(JNIEnv*, jint);
  extern jboolean isProtected(JNIEnv*, jint);
  extern jboolean matchModifier(JNIEnv*, jint, jint);
};

namespace JHelper {
  extern char* GetNativeChars(JNIEnv*, jstring);
  extern char* jlong2text(JNIEnv*, jlong);
  extern jlong text2jlong(JNIEnv*, char*);
  extern char* object2text(JNIEnv*, jobject);
  extern jobject text2object(JNIEnv*, char*, char*);
  extern jboolean createSingleMuPADList(JNIEnv*, jobjectArray, MTcell*, jint);
  extern jboolean createDoubleMuPADList(JNIEnv*, jobjectArray, MTcell*, jint);
  extern jboolean createTripleMuPADList(JNIEnv*, jobjectArray, MTcell*, jint);
  extern jboolean createQuadMuPADList(JNIEnv*, jobjectArray, MTcell*, jint);
  extern jboolean createQuintMuPADList(JNIEnv*, jobjectArray, MTcell*, jint);
  extern MTcell   createMultiMuPADList(JNIEnv*, jobjectArray, jint);
  extern jboolean createSingleJNIArray(JNIEnv*, MTcell, jint, jobjectArray*);
  extern jboolean createDoubleJNIArray(JNIEnv*, MTcell, jint, jobjectArray*);
  extern jboolean createTripleJNIArray(JNIEnv*, MTcell, jint, jobjectArray*);
  extern jboolean createQuadJNIArray(JNIEnv*, MTcell, jint, jobjectArray*);
  extern jboolean createQuintJNIArray(JNIEnv*, MTcell, jint, jobjectArray*);
  extern jboolean createMultiJNIArray(JNIEnv*, MTcell, jint, jobjectArray*);
  extern jboolean hasNativeMethod(JNIEnv*, jclass);
  extern jboolean matchMethod(JNIEnv*, jclass, MTcell, MTcell, jint*, jint*);
//  extern jboolean matchMethod(JNIEnv*, char*, MTcell, jint*, jint*);
};

namespace JSystem {
  extern jboolean addMuPADSecurityListener(JNIEnv*);
  extern jobject startList(JNIEnv*);
  extern jboolean addToList(JNIEnv*, char*, jobject);
  extern void HO_replaceObject(JNIEnv*, char*, jobject);
  extern char*  HO_getSignature(JNIEnv*, char*);
  extern char*  HO_getClassname(JNIEnv*, char*);
  extern jobject HO_getObject(JNIEnv *, char *);
  extern MTcell HO_getList(JNIEnv *, jboolean);
  extern void HO_removeObject(JNIEnv*, char*);
  extern void HO_clearList(JNIEnv*);
  extern void checkForException(JNIEnv*);
  extern void InitEncodingFlag(JNIEnv*);
  extern void runFinalization(JNIEnv*);
  extern void garbageCollect(JNIEnv*);
  extern jstring NewPlatformString(JNIEnv*, char*);
};
#endif
