/***************************************************************************
                            QtSupport.cpp -  description
                             -------------------
    begin                : Fri Oct 20 13:46:55 2000
    copyright            : (C) 2000 Lost Highway Ltd
    email                : Richard_Dale@tipitina.demon.co.uk
    generated by         : duke@tipitina on Fri Oct 20 13:46:55 2000, using kdoc $.
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include <stdlib.h>
#include <stdio.h>

#include <tqmetaobject.h>

#include <qtjava/QtSupport.h>
#include <qtjava/TQObject.h>
#include <qtjava/JavaSlot.h>

static JavaVM *	_jvm;


jmethodID	QtSupport::MID_String_init;
jmethodID	QtSupport::MID_String_getBytes;
bool		QtSupport::_bigEndianUnicode;

void
QtSupport::registerJVM(JNIEnv * env)
{
	jstring	testString;
	const jchar * _jchar_str;

	env->GetJavaVM((JavaVM **) &_jvm);

	// Cache commonly used method id's and classes.
	MID_String_init = env->GetMethodID(env->FindClass("java/lang/String"), "<init>", "([B)V");
	MID_String_getBytes = env->GetMethodID(env->FindClass("java/lang/String"), "getBytes", "()[B");

	// Test for the endianess of the unicode string returned by GetStringChars()
	testString = env->NewStringUTF("A");
	_jchar_str = env->GetStringChars(testString, 0);
	TQString temp((TQChar*)_jchar_str, env->GetStringLength(testString));
	env->ReleaseStringChars(testString, _jchar_str);
	_bigEndianUnicode = strcmp((const char *) temp, "A") == 0;
	env->DeleteLocalRef(testString);

	return;
}

JNIEnv *
QtSupport::GetEnv()
{
	JNIEnv *	env;

	_jvm->GetEnv((void **) &env, JNI_VERSION_1_2);
	return env;
}

const char *
QtSupport::eventTypeToEventClassName(TQEvent::Type eventType)
{
	switch (eventType) {
	case TQEvent::ChildInserted:
	case TQEvent::ChildRemoved:
		 return "org.trinitydesktop.qt.TQChildEvent";
	case TQEvent::Close:
		 return "org.trinitydesktop.qt.TQCloseEvent";
	case TQEvent::ContextMenu:
		 return "org.trinitydesktop.qt.TQContextMenuEvent";
	case TQEvent::User:
		 return "org.trinitydesktop.qt.TQCustomEvent";
	case TQEvent::DragEnter:
		 return "org.trinitydesktop.qt.TQDragEnterEvent";
	case TQEvent::DragLeave:
		 return "org.trinitydesktop.qt.TQDragLeaveEvent";
	case TQEvent::DragMove:
		 return "org.trinitydesktop.qt.TQDragMoveEvent";
	case TQEvent::DragResponse:
		 return "org.trinitydesktop.qt.TQDragResponseEvent";
	case TQEvent::Drop:
		 return "org.trinitydesktop.qt.TQDropEvent";
	case TQEvent::FocusIn:
	case TQEvent::FocusOut:
		 return "org.trinitydesktop.qt.TQFocusEvent";
	case TQEvent::Hide:
		 return "org.trinitydesktop.qt.TQHideEvent";
	case TQEvent::KeyPress:
	case TQEvent::KeyRelease:
		 return "org.trinitydesktop.qt.TQKeyEvent";
	case TQEvent::IMStart:
	case TQEvent::IMCompose:
	case TQEvent::IMEnd:
		 return "org.trinitydesktop.qt.TQIMEvent";
	case TQEvent::MouseButtonPress:
	case TQEvent::MouseButtonRelease:
	case TQEvent::MouseButtonDblClick:
	case TQEvent::MouseMove:
		 return "org.trinitydesktop.qt.TQMouseEvent";
	case TQEvent::Move:
		 return "org.trinitydesktop.qt.TQMoveEvent";
	case TQEvent::Paint:
		 return "org.trinitydesktop.qt.TQPaintEvent";
	case TQEvent::Resize:
		 return "org.trinitydesktop.qt.TQResizeEvent";
	case TQEvent::Show:
		 return "org.trinitydesktop.qt.TQShowEvent";
//	case TQEvent::Tablet:
//		 return "org.trinitydesktop.qt.TQTabletEvent";
	case TQEvent::Timer:
		 return "org.trinitydesktop.qt.TQTimerEvent";
	case TQEvent::Wheel:
		 return "org.trinitydesktop.qt.TQWheelEvent";
	default:
		 return "org.trinitydesktop.qt.TQEvent";
	}
}

bool
QtSupport::eventFilterDelegate(TQObject * object, const char * objectType, TQObject * filteredObject, TQEvent * event)
{
	JNIEnv *	env;
	jclass		cls;
	jstring		objectTypeString;
	jstring		eventNameString;
	jstring		eventMethodString;
	jmethodID	mid;

    (void) objectType; // Not used at present, the event's Qt rtti is used instead
    
	env = QtSupport::GetEnv();
	if (env == 0) {
		return false;
	}
	
	cls = env->FindClass("org/trinitydesktop/qt/Invocation");
	if (cls == 0) {
		return false;
	}

	mid = env->GetStaticMethodID(cls, "invoke", "(JJLjava/lang/String;JLjava/lang/String;Ljava/lang/String;)Z");
	if (mid == 0) {
		return false;
	}

	objectTypeString = env->NewStringUTF("org.trinitydesktop.qt.TQObject");
	eventNameString = env->NewStringUTF(QtSupport::eventTypeToEventClassName(event->type()));
	eventMethodString = env->NewStringUTF("eventFilter");
	
	bool result = (bool) env->CallStaticBooleanMethod(	cls, mid,
														(jlong) object,
														(jlong) filteredObject,
														objectTypeString,
														(jlong) event,
														eventNameString,
														eventMethodString );
												
	env->DeleteLocalRef(cls);
	env->DeleteLocalRef(objectTypeString);
	env->DeleteLocalRef(eventNameString);
	env->DeleteLocalRef(eventMethodString);
	return result;
}

bool
QtSupport::eventDelegate(TQObject * object, const char * eventType, void * event, const char * eventName)
{
	JNIEnv *	env;
	jclass		cls;
	jstring		eventNameString;
	jstring		eventTypeString;
	jmethodID	mid;
	
	env = QtSupport::GetEnv();
	if (env == 0) {
		return false;
	}
	
	cls = env->FindClass("org/trinitydesktop/qt/Invocation");
	if (cls == 0) {
		return false;
	}

	mid = env->GetStaticMethodID(cls, "invoke", "(JJLjava/lang/String;Ljava/lang/String;)Z");
	if (mid == 0) {
		return false;
	}

	eventNameString = env->NewStringUTF(eventName);
	eventTypeString = env->NewStringUTF(eventType);
	
	bool result = (bool) env->CallStaticBooleanMethod(	cls, mid,
												(jlong) object,
												(jlong) event,
												eventNameString,
												eventTypeString );
	env->DeleteLocalRef(cls);
	env->DeleteLocalRef(eventNameString);
	env->DeleteLocalRef(eventTypeString);
	return result;
}

bool
QtSupport::voidDelegate(void * object, const char * className, const char * methodName)
{
	JNIEnv *	env;
	jclass		cls;
	jstring		classNameString;
	jstring		methodNameString;
	jmethodID	mid;
	env = QtSupport::GetEnv();
	if (env == 0) {
		return false;
	}
	
	cls = env->FindClass("org/trinitydesktop/qt/Invocation");
	if (cls == 0) {
		return false;
	}

	mid = env->GetStaticMethodID(cls, "invoke", "(JLjava/lang/String;Ljava/lang/String;)Z");
	if (mid == 0) {
		return false;
	}
	
	classNameString = env->NewStringUTF(className);
	methodNameString = env->NewStringUTF(methodName);
	bool result = (bool) env->CallStaticBooleanMethod(	cls, mid,
														(jlong) object,
														classNameString,
														methodNameString );
	env->DeleteLocalRef(cls);
	env->DeleteLocalRef(methodNameString);
	env->DeleteLocalRef(classNameString);
	return result;
}

bool
QtSupport::booleanDelegate(TQObject * object, const char * methodName)
{
	JNIEnv *	env;
	jclass		cls;
	jstring		methodNameString;
	jmethodID	mid;

	env = QtSupport::GetEnv();
	if (env == 0) {
		return false;
	}
	
	cls = env->FindClass("org/trinitydesktop/qt/Invocation");
	if (cls == 0) {
		return false;
	}

	mid = env->GetStaticMethodID(cls, "booleanInvoke", "(JLjava/lang/String;)Z");
	if (mid == 0) {
		return false;
	}

	methodNameString = env->NewStringUTF(methodName);
	bool result = (bool) env->CallStaticBooleanMethod(	cls, mid,
														(jlong) object,
														methodNameString );
	env->DeleteLocalRef(cls);
	env->DeleteLocalRef(methodNameString);
	return result;
}

int
QtSupport::validateDelegate(TQValidator * object, TQString & input, int & pos)
{
	JNIEnv *	env;
	jclass		cls;
	jmethodID	mid;
	jobject		validator;
	jstring		inputString;
	TQString *	inputPtr;
	jstring		resultString;
	jobject		buffer;
	jmethodID	bufferConstructor;
	jclass		bufferClass;
	jintArray	positionArray;
	int			result;
	jmethodID	bufferToString;

	env = QtSupport::GetEnv();
	env->PushLocalFrame(10);
	
	// Allocate a java StringBuffer to hold the input string
	inputString = QtSupport::fromTQString(env, (TQString *) &input);
	bufferClass = env->FindClass("java/lang/StringBuffer");
	bufferConstructor = env->GetMethodID(bufferClass, "<init>", "(Ljava/lang/String;)V");
	if (bufferConstructor == 0) {
		return 0;
	}
	buffer = env->NewObject(bufferClass, bufferConstructor, inputString);

	// Get the cursor position and convert to type 'int[]'
	positionArray = QtSupport::fromIntPtr(env, &pos);

	// Obtain the validate() method id, and call the method
	validator = (jobject) QtSupport::objectForQtKey(env, object, "org.trinitydesktop.qt.TQValidator");
    cls = env->GetObjectClass(validator);
    if (cls == 0) {
    	return 0;
    }

	mid = env->GetMethodID(cls, "validate", "(Ljava/lang/StringBuffer;[I)I");
	if (mid == 0) {
		return 0;
	}
	result = (int) env->CallIntMethod(validator, mid, buffer, positionArray);

	// Copy the java result string back into the 'input' TQString
	bufferToString = env->GetMethodID(bufferClass, "toString", "()Ljava/lang/String;");
	if (bufferToString == 0) {
		env->PopLocalFrame(0);
		return 0;
	}
	resultString = (jstring) env->CallObjectMethod(buffer, bufferToString);
	inputPtr = &input;
	QtSupport::toTQString(env, resultString, &inputPtr);

	pos = *(QtSupport::toIntPtr(env, positionArray));
	env->PopLocalFrame(0);

	return result;
}

void
QtSupport::fixupDelegate(TQValidator * object, TQString & input)
{
	JNIEnv *	env;
	jclass		cls;
	jmethodID	mid;
	jobject		fixer;
	jstring		inputString;
	TQString *	inputPtr;
	jstring		resultString;
	jobject		buffer;
	jmethodID	bufferConstructor;
	jclass		bufferClass;
	jmethodID	bufferToString;

	env = QtSupport::GetEnv();
	env->PushLocalFrame(10);

	// Allocate a java StringBuffer to hold the input string
	inputString = QtSupport::fromTQString(env, (TQString *) &input);
	bufferClass = env->FindClass("java/lang/StringBuffer");
	bufferConstructor = env->GetMethodID(bufferClass, "<init>", "(Ljava/lang/String;)V");
	if (bufferConstructor == 0) {
		return;
	}
	buffer = env->NewObject(bufferClass, bufferConstructor, inputString);

	// Obtain the fixup() method id and call the method
	fixer = (jobject) QtSupport::objectForQtKey(env, object, "org.trinitydesktop.qt.TQValidator");
    cls = env->GetObjectClass(fixer);
    if (cls == 0) {
    	return;
    }
	mid = env->GetMethodID(cls, "fixup", "(Ljava/lang/StringBuffer;)V");
	if (mid == 0) {
		return;
	}
	env->CallVoidMethod(fixer, mid, buffer);

	// Copy the java result string back into the 'input' TQString
	bufferToString = env->GetMethodID(bufferClass, "toString", "()Ljava/lang/String;");
	if (bufferToString == 0) {
		env->PopLocalFrame(0);
		return;
	}
	resultString = (jstring) env->CallObjectMethod(buffer, bufferToString);
	inputPtr = &input;
	QtSupport::toTQString(env, resultString, &inputPtr);
	env->PopLocalFrame(0);

	return;
}

bool
QtSupport::allocatedInJavaWorld(JNIEnv * env, jobject obj)
{
	if (obj == 0) {
		return false;
	}

	jclass cls = env->GetObjectClass(obj);
	bool result = (bool) env->GetBooleanField(obj, env->GetFieldID(cls, "_allocatedInJavaWorld", "Z"));
	env->DeleteLocalRef(cls);
	return result;
}

void
QtSupport::setAllocatedInJavaWorld(JNIEnv * env, jobject obj, bool yn)
{
	jclass cls = env->GetObjectClass(obj);
	env->SetBooleanField(obj, env->GetFieldID(cls, "_allocatedInJavaWorld", "Z"), (jboolean) yn);
	env->DeleteLocalRef(cls);
	return;
}

void *
QtSupport::getQt(JNIEnv * env, jobject obj)
{
	if (obj == 0) {
		return 0;
	}

	jclass cls = env->GetObjectClass(obj);
	void * result = (void *) env->GetLongField(obj, env->GetFieldID(cls, "_qt", "J"));
	env->DeleteLocalRef(cls);
	return result;
}

void
QtSupport::setQt(JNIEnv * env, jobject obj, void * qt)
{
	jclass cls = env->GetObjectClass(obj);
	env->SetLongField(obj, env->GetFieldID(cls, "_qt", "J"), (jlong) qt);
	env->DeleteLocalRef(cls);
	return;
}

void
QtSupport::setObjectForQtKey(JNIEnv * env, jobject obj, void * qt)
{
	jclass		cls;
	jmethodID	mid;

	cls = env->FindClass("org/trinitydesktop/qt/qtjava");
	if (cls == 0) {
		return;
	}

	mid = env->GetStaticMethodID(cls, "setObjectForQtKey", "(Ljava/lang/Object;J)V");
	if (mid == 0) {
		return;
	}

	env->CallStaticVoidMethod(cls, mid, obj, (jlong) qt);
	env->DeleteLocalRef(cls);
	return;
}

jobject
QtSupport::objectForQtKey(JNIEnv * env, void * qt, const char * className, const bool allocatedInJavaWorld)
{
	jclass		cls;
	jmethodID	mid;
	jstring		javaClassName;

	if (qt == 0) {
		return 0;
	}
	
	javaClassName = env->NewStringUTF(className);

	cls = env->FindClass("org/trinitydesktop/qt/qtjava");
	if (cls == 0) {
		return 0;
	}

	mid = env->GetStaticMethodID(cls, "objectForQtKey", "(JLjava/lang/String;Z)Ljava/lang/Object;");
	if (mid == 0) {
		return 0;
	}

	jobject result = env->CallStaticObjectMethod(cls, mid, (jlong) qt, javaClassName, (jboolean) allocatedInJavaWorld);
	env->DeleteLocalRef(cls);
	env->DeleteLocalRef(javaClassName);
	return result;
}
	
void
QtSupport::qtKeyDeleted(void * qt)
{
	JNIEnv *	env;
	jclass		cls;
	jmethodID	mid;

	env = QtSupport::GetEnv();
	if (env == 0) {
		return;
	}

	cls = env->FindClass("org/trinitydesktop/qt/qtjava");
	if (cls == 0) {
		return;
	}

	mid = env->GetStaticMethodID(cls, "qtKeyDeleted", "(J)V");
	if (mid == 0) {
		return;
	}

	env->CallStaticVoidMethod(cls, mid, (jlong) qt);
	env->DeleteLocalRef(cls);
	return;
}

jboolean
QtSupport::connect(JNIEnv * env, jobject sender, jstring signal, jobject receiver, jstring slot)
{
	JavaSlot *		javaSlot = QtSupport::slotForReceiver(env, receiver, slot);
	TQMetaObject *	smeta = ((TQObject *) QtSupport::getQt(env, sender))->metaObject();
	TQString			qtSignalName(javaSlot->javaToQtSignalName(env, signal, smeta));

	// Attempt to connect from the signal on the underlying C++ object first,
	// otherwise assume that the connection is for a Java signal.
	if (!qtSignalName.isEmpty()) {
		TQMetaObject *	smetaTarget = ((TQObject *) QtSupport::getQt(env, receiver))->metaObject();
		TQString	qtTargetSignalName(javaSlot->javaToQtSignalName(env, slot, smetaTarget));

		if (!qtTargetSignalName.isEmpty()) {
			// The sender is a C++ signal, and the target is also a C++ signal
			return (jboolean) TQObject::connect(	(TQObject*) QtSupport::getQt(env, sender),
												(const char *) qtSignalName,
												(TQObject*) QtSupport::getQt(env, receiver),
												(const char *) qtTargetSignalName );
		} else {
			// The sender is a C++ signal, and the target is a java slot
			return (jboolean) TQObject::connect(	(TQObject*) QtSupport::getQt(env, sender),
												(const char *) qtSignalName,
												javaSlot,
												javaSlot->javaToQtSlotName(env, slot, qtSignalName) );
		}
	} else {
		// The sender is a java signal, and the target is either a java slot or a java signal
		// Java signals are always of type jobjectArray
		return (jboolean) TQObject::connect(	QtSupport::signalForSender(env, QtSupport::getQt(env, sender), signal),
											"2signalJava(jobjectArray)",
											javaSlot,
											"1invoke(jobjectArray)" );
	}
}

jboolean
QtSupport::disconnect(JNIEnv * env, jobject sender, jstring signal, jobject receiver, jstring slot)
{
	JavaSlot *		javaSlot = QtSupport::slotForReceiver(env, receiver, slot);
	TQMetaObject *	smeta = ((TQObject *) QtSupport::getQt(env, sender))->metaObject();
	TQString			qtSignalName(javaSlot->javaToQtSignalName(env, signal, smeta));

	// Attempt to disconnect from the signal on the underlying C++ object first,
	// otherwise assume that the connection is for a Java signal.
	if (!qtSignalName.isEmpty()) {
		TQMetaObject *	smetaTarget = ((TQObject *) QtSupport::getQt(env, receiver))->metaObject();
		TQString	qtTargetSignalName(javaSlot->javaToQtSignalName(env, slot, smetaTarget));

		if (!qtTargetSignalName.isEmpty()) {
			// The sender is a C++ signal, and the target is also a C++ signal
			return (jboolean) TQObject::disconnect(	(TQObject*) QtSupport::getQt(env, sender),
													(const char *) qtSignalName,
													(TQObject*) QtSupport::getQt(env, receiver),
													(const char *) qtTargetSignalName );
		} else {
			// The sender is a C++ signal, and the target is a java slot
			return (jboolean) TQObject::disconnect(	(TQObject*) QtSupport::getQt(env, sender),
													(const char *) qtSignalName,
													javaSlot,
													javaSlot->javaToQtSlotName(env, slot, qtSignalName) );
		}
	} else {
		// The sender is a java signal, and the target is either a java slot or a java signal
		// Java signals are always of type jobjectArray
		return (jboolean) TQObject::disconnect(	QtSupport::signalForSender(env, QtSupport::getQt(env, sender), signal),
												"2signalJava(jobjectArray)",
												javaSlot,
												"1invoke(jobjectArray)" );
	}
}

void
QtSupport::emitJavaSignal(JNIEnv * env, jobject sender, jstring signal, jobjectArray args)
{
	JavaSignal * javaSignal = QtSupport::signalForSender(env, QtSupport::getQt(env, sender), signal);
	javaSignal->emitArgs(args);
}

JavaSignal *
QtSupport::signalForSender(JNIEnv * env, void * qt, jstring signal)
{
	jclass		cls;
	jmethodID	mid;

	cls = env->FindClass("org/trinitydesktop/qt/qtjava");
	mid = env->GetStaticMethodID(cls, "signalForSender", "(JLjava/lang/String;)J");
	if (mid == 0) {
		return 0;
	}

	JavaSignal * result = (JavaSignal *) env->CallStaticLongMethod(cls, mid, (jlong) qt, signal);
	env->DeleteLocalRef(cls);
	return result;
}

JavaSlot *
QtSupport::slotForReceiver(JNIEnv * env, jobject receiver, jstring slot)
{
	jclass		cls;
	jmethodID	mid;

	cls = env->FindClass("org/trinitydesktop/qt/qtjava");
	mid = env->GetStaticMethodID(cls, "slotForReceiver", "(JLorg/trinitydesktop/qt/TQObject;Ljava/lang/String;)J");
	if (mid == 0) {
		return 0;
	}

	JavaSlot * result = (JavaSlot *) env->CallStaticLongMethod(cls, mid, (jlong) QtSupport::getQt(env, receiver), receiver, slot);
	env->DeleteLocalRef(cls);
	return result;
}

TQPaintDevice *
QtSupport::paintDevice(JNIEnv * env, jobject obj)
{
	jclass		cls;
	jmethodID	mid;

	cls = env->GetObjectClass(obj);
	mid = env->GetMethodID(cls, "paintDevice", "()J");
	if (mid == 0) {
		return 0;
	}

	env->DeleteLocalRef(cls);
	return (TQPaintDevice *) env->CallLongMethod(obj, mid);
}

TQMimeSource *
QtSupport::mimeSource(JNIEnv * env, jobject obj)
{
	jclass		cls;
	jmethodID	mid;

	cls = env->GetObjectClass(obj);
	mid = env->GetMethodID(cls, "mimeSource", "()J");
	if (mid == 0) {
		return 0;
	}

	env->DeleteLocalRef(cls);
	return (TQMimeSource *) env->CallLongMethod(obj, mid);
}

bool
QtSupport::bigEndianUnicode()
{
	return _bigEndianUnicode;
}

bool *
QtSupport::toBooleanPtr(JNIEnv * env, jbooleanArray obj)
{
	bool *	result;
	int		length;

	length = env->GetArrayLength(obj);
	result = (bool *) calloc(length, sizeof(bool));
	env->GetBooleanArrayRegion(obj, 0, length, (jboolean *) result);
	return result;
}

int *
QtSupport::toIntPtr(JNIEnv * env, jintArray obj)
{
	int *	result;
	int		length;

	length = env->GetArrayLength(obj);
	result = (int *) calloc(length, sizeof(int));
	env->GetIntArrayRegion(obj, 0, length, (jint *) result);
	return result;
}

double *
QtSupport::toDoublePtr(JNIEnv * env, jdoubleArray obj)
{
	double *	result;
	int			length;

	length = env->GetArrayLength(obj);
	result = (double *) calloc(length, sizeof(double));
	env->GetDoubleArrayRegion(obj, 0, length, (jdouble *) result);
	return result;
}

short *
QtSupport::toShortPtr(JNIEnv * env, jshortArray obj)
{
	short *	result;
	int		length;

	length = env->GetArrayLength(obj);
	result = (short *) calloc(length, sizeof(short));
	env->GetShortArrayRegion(obj, 0, length, (jshort *) result);
	return result;
}

jbooleanArray
QtSupport::fromBooleanPtr(JNIEnv * env, bool * arg)
{
	jbooleanArray	result;

	result = env->NewBooleanArray(1);
	env->SetBooleanArrayRegion(result, 0, 1, (jboolean *) arg);
	return (jbooleanArray) result;
}

jintArray
QtSupport::fromIntPtr(JNIEnv * env, int * arg)
{
	jintArray	result;

	result = env->NewIntArray(1);
	env->SetIntArrayRegion(result, 0, 1, (jint *) arg);
	return (jintArray) result;
}

jdoubleArray
QtSupport::fromDoublePtr(JNIEnv * env, double * arg)
{
	jdoubleArray	result;

	result = env->NewDoubleArray(1);
	env->SetDoubleArrayRegion(result, 0, 1, (jdouble *) arg);
	return (jdoubleArray) result;
}

jshortArray
QtSupport::fromShortPtr(JNIEnv * env, short * arg)
{
	jshortArray	result;

	result = env->NewShortArray(1);
	env->SetShortArrayRegion(result, 0, 1, (jshort *) arg);
	return (jshortArray) result;
}


jobject QtSupport::fromTQDateTime(JNIEnv * env, TQDateTime* qdate)
{
	jclass 		cls;
	jmethodID	cid;
	jobject		date;

	cls = env->FindClass("java/util/GregorianCalendar");
	if (cls == 0) {
		return 0;
	}

	cid = env->GetMethodID(cls, "<init>", "(IIIIII)V");
	if (cid == 0) {
		return 0;
	}

	date = env->NewObject(	cls, cid,
							(jint) qdate->date().year(), (jint) qdate->date().month() - 1, (jint) qdate->date().day(),
							(jint) qdate->time().hour(), (jint) qdate->time().minute(), (jint) qdate->time().second() );
	QtSupport::setObjectForQtKey(env, date, qdate);

	env->DeleteLocalRef(cls);
	return (jobject) date;
}

jobject
QtSupport::fromTQDate(JNIEnv * env, TQDate* qdate)
{
	jclass 		cls;
	jmethodID	cid;
	jobject		date;

	cls = env->FindClass("java/util/GregorianCalendar");
	if (cls == 0) {
		return 0;
	}

	cid = env->GetMethodID(cls, "<init>", "(III)V");
	if (cid == 0) {
		return 0;
	}

	date = env->NewObject(cls, cid, (jint) qdate->year(), (jint) qdate->month() - 1, (jint) qdate->day());
	QtSupport::setObjectForQtKey(env, date, qdate);

	env->DeleteLocalRef(cls);
	return (jobject) date;
}

jobject
QtSupport::fromTQTime(JNIEnv * env, TQTime* qtime)
{
	jclass 		cls;
	jmethodID	cid;
	jobject		time;
	jmethodID	mid;

	cls = env->FindClass("java/util/Date");
	if (cls == 0) {
		return 0;
	}

	cid = env->GetMethodID(cls, "<init>", "()V");
	if (cid == 0) {
		return 0;
	}

	time = env->NewObject(cls, cid);
	QtSupport::setObjectForQtKey(env, time, qtime);

	mid = env->GetMethodID(cls, "setHours", "(I)V");
	if (mid == 0) {
		return 0;
	}

	env->CallVoidMethod(time, mid, qtime->hour());

	mid = env->GetMethodID(cls, "setMinutes", "(I)V");
	if (mid == 0) {
		return 0;
	}

	env->CallVoidMethod(time, mid, qtime->minute());

	mid = env->GetMethodID(cls, "setSeconds", "(I)V");
	if (mid == 0) {
		return 0;
	}

	env->CallVoidMethod(time, mid, qtime->second());

	env->DeleteLocalRef(cls);
	return (jobject) time;
}


TQDateTime *
QtSupport::toTQDateTime(JNIEnv * env, jobject jdate, TQDateTime** qdatetime)
{
static TQDate * qdate = 0;
static TQTime * qtime = 0;

	if (*qdatetime == 0) {
		*qdatetime = new TQDateTime();
		qdate = new TQDate();
		qtime = new TQTime();
	}

	QtSupport::toTQDate(env, jdate, &qdate);
	QtSupport::toTQTime(env, jdate, &qtime);
	(*qdatetime)->setDate(*qdate);
	(*qdatetime)->setTime(*qtime);

	return *qdatetime;
}


#define JAVA_YEAR 1
#define JAVA_MONTH 2
#define JAVA_DAY_OF_MONTH 5
TQDate *
QtSupport::toTQDate(JNIEnv * env, jobject jdate, TQDate** qdate)
{
	jclass 		cls;
	jmethodID	mid;
	jint		year;
	jint		month;
	jint		day;

	if (*qdate == 0) {
		*qdate = new TQDate();
	}

	cls = env->FindClass("java/util/Calendar");

	mid = env->GetMethodID(cls, "get", "(I)I");
	if (mid == 0) {
		return 0;
	}

	year = env->CallIntMethod(jdate, mid, JAVA_YEAR);
	month = env->CallIntMethod(jdate, mid, JAVA_MONTH);
	day = env->CallIntMethod(jdate, mid, JAVA_DAY_OF_MONTH);

	(*qdate)->setYMD((int) year, (int) month + 1, (int) day);

	env->DeleteLocalRef(cls);
	return *qdate;
}

TQTime *
QtSupport::toTQTime(JNIEnv * env, jobject jtime, TQTime** qtime)
{
	jclass 		cls;
	jmethodID	mid;
	jint		hour;
	jint		minute;
	jint		second;

	if (*qtime == 0) {
		*qtime = new TQTime();
	}

	cls = env->FindClass("java/util/Date");

	mid = env->GetMethodID(cls, "getHours", "()I");
	if (mid == 0) {
		return 0;
	}

	hour = env->CallIntMethod(jtime, mid);

	mid = env->GetMethodID(cls, "getMinutes", "()I");
	if (mid == 0) {
		return 0;
	}

	minute = env->CallIntMethod(jtime, mid);

	mid = env->GetMethodID(cls, "getSeconds", "()I");
	if (mid == 0) {
		return 0;
	}

	second = env->CallIntMethod(jtime, mid);

	(*qtime)->setHMS((int) hour, (int) minute, (int) second);

	env->DeleteLocalRef(cls);
	return *qtime;
}

jstring
QtSupport::fromTQString(JNIEnv * env, TQString * qstring)
{
	if (qstring == 0) {
		return 0;
	}
	
	if (_bigEndianUnicode) {
		return env->NewString((const jchar *) qstring->unicode(), (long) qstring->length());
	} else {
static TQString *	temp = 0L;

		if (temp == 0L) {
			temp = new TQString();
		}

		// Hack to change the big endian unicode in 'qstring' to little endian in 'temp'.
		temp->setUnicodeCodes((const ushort *) qstring->unicode(), (long) qstring->length());
		return env->NewString((const jchar *) temp->unicode(), (long) temp->length());
	}
}

jstring
QtSupport::fromTQCString(JNIEnv * env, TQCString * qcstring)
{
	jstring result = 0;
	jbyteArray bytes = 0;
	int len;
	jclass cls;

	if (qcstring == 0) {
		return 0;
	}
	
	len = qcstring->length();
	bytes = env->NewByteArray(len);
	env->SetByteArrayRegion(bytes, 0, len, (jbyte *) (const char *) *qcstring);
	cls = env->FindClass("java/lang/String");
	result = (jstring) env->NewObject(cls, QtSupport::MID_String_init, bytes);
	env->DeleteLocalRef(cls);
	env->DeleteLocalRef(bytes);
	return result;
}

jstring
QtSupport::fromCharString(JNIEnv * env, char * qcstring)
{
	jstring result = 0;
	jbyteArray bytes = 0;
	int len;

	if (qcstring == 0) {
		return 0;
	}
	
	len = strlen(qcstring);
	bytes = env->NewByteArray(len);
	env->SetByteArrayRegion(bytes, 0, len, (jbyte *) (const char *) qcstring);
	jclass stringClass = env->FindClass("java/lang/String");
	result = (jstring) env->NewObject(stringClass, QtSupport::MID_String_init, bytes);
	env->DeleteLocalRef(stringClass);
	env->DeleteLocalRef(bytes);
	return result;
}

TQString *
QtSupport::toTQString(JNIEnv * env, jstring str, TQString ** qstring)
{
	const jchar *	_jchar_str;

	if (str == 0L) {
		return (TQString*) &TQString::null;
	}

	if (*qstring == 0L) {
		*qstring = new TQString();
	}

	_jchar_str = env->GetStringChars(str, 0);

	if (_bigEndianUnicode) {
		(*qstring)->setUnicode((TQChar *) _jchar_str, env->GetStringLength(str));
	} else {
		(*qstring)->setUnicodeCodes((const ushort *) _jchar_str, env->GetStringLength(str));
	}

	env->ReleaseStringChars(str, _jchar_str);
	return *qstring;
}

TQCString *
QtSupport::toTQCString(JNIEnv * env, jstring str, TQCString ** qcstring)
{
	jbyteArray	bytes = 0;
	jthrowable	exc;
	jint		len = 0;
	char *		data;

	if (str == 0) {
		return 0;
	}

	bytes = (jbyteArray) env->CallObjectMethod(str, QtSupport::MID_String_getBytes);
	exc = env->ExceptionOccurred();

	if (exc) {
		env->DeleteLocalRef(exc);
		return 0;
	}

	len = env->GetArrayLength(bytes);

	if (*qcstring == 0) {
		*qcstring = new TQCString(len + 1);
	} else {
		(*qcstring)->resize(len + 1);
	}

	data = (*qcstring)->data();
	env->GetByteArrayRegion(bytes, 0, len, (jbyte *) data);
	data[len] = 0;
	env->DeleteLocalRef(bytes);
	return *qcstring;
}

char *
QtSupport::toCharString(JNIEnv * env, jstring str, TQCString ** qcstring)
{
	if (str == 0) {
		return 0;
	}

	(void) QtSupport::toTQCString(env, str, qcstring);
	return (*qcstring)->data();
}


void
QtSupport::fromTQStringToStringBuffer(JNIEnv * env, TQString * qstring, jobject buffer)
{
	jclass 		cls;
	jmethodID	mid;
	jmethodID	appendMid;

	if (buffer == 0) {
		return;
	}

	cls = env->FindClass("java/lang/StringBuffer");
	if (cls == 0) {
		return;
	}

	mid = env->GetMethodID(cls, "setLength", "(I)V");
	if (mid == 0) {
		return;
	}

	env->CallVoidMethod(buffer, mid, 0);

	appendMid = env->GetMethodID(cls, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
	if (appendMid == 0) {
		return;
	}
	
	(void) env->CallObjectMethod(buffer, appendMid, QtSupport::fromTQString(env, qstring));
	env->DeleteLocalRef(cls);
	return;
}

TQString *
QtSupport::toTQStringFromStringBuffer(JNIEnv * env, jobject buffer, TQString ** qstring)
{
	jclass 		cls;
	jmethodID	mid;
	jstring		str;
	
	if (buffer == 0) {
		return 0;
  	}

	cls = env->FindClass("java/lang/StringBuffer");
	if (cls == 0) {
		return 0;
	}

	mid = env->GetMethodID(cls, "toString", "()Ljava/lang/String;");
	if (mid == 0) {
		return 0;
	}

	str = (jstring) env->CallObjectMethod(buffer, mid);
	env->DeleteLocalRef(cls);
	return QtSupport::toTQString(env, str, qstring);
}
void
QtSupport::fromTQCStringToStringBuffer(JNIEnv * env, TQCString * qcstring, jobject buffer)
{
	jclass 		cls;
	jmethodID	mid;
	jmethodID	appendMid;

	if (buffer == 0) {
		return;
	}

	cls = env->FindClass("java/lang/StringBuffer");
	if (cls == 0) {
		return;
	}

	mid = env->GetMethodID(cls, "setLength", "(I)V");
	if (mid == 0) {
		return;
	}

	env->CallVoidMethod(buffer, mid, 0);

	appendMid = env->GetMethodID(cls, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
	if (appendMid == 0) {
		return;
	}
	
	(void) env->CallObjectMethod(buffer, appendMid, QtSupport::fromTQCString(env, qcstring));
	env->DeleteLocalRef(cls);
	return;
}

jchar
QtSupport::fromTQChar(JNIEnv * env, TQChar * qchar)
{
	(void) env;
	return (jchar) qchar->unicode();
}

TQChar *
QtSupport::toTQChar(JNIEnv * env, jchar unichar, TQChar ** qchar)
{
	(void) env;
	
	if (*qchar != 0L) {
		delete *qchar;
	}

	*qchar = new TQChar((ushort) unichar);
	return *qchar;
}

jbyteArray
QtSupport::fromTQByteArray(JNIEnv * env, TQByteArray * qbyteArray)
{
	jbyteArray result = 0;
	int len;

	len = qbyteArray->size();
	result = env->NewByteArray(len);
	env->SetByteArrayRegion(result, 0, len, (jbyte *) (const char *) qbyteArray->data());
	return result;
}

TQByteArray *
QtSupport::toTQByteArray(JNIEnv * env, jbyteArray bytes, TQByteArray ** qbyteArray)
{
	if (bytes == 0) {
		return 0;
	}

	jsize len = env->GetArrayLength(bytes);
	if (*qbyteArray == 0) {
		*qbyteArray = new TQByteArray(len);
	} else {
		(*qbyteArray)->resize(len);
	}

	jboolean isCopy;
	(*qbyteArray)->duplicate((const char *)env->GetByteArrayElements(bytes, &isCopy), len);
	return *qbyteArray;
}
	
uchar *
QtSupport::toUcharArray(JNIEnv * env, jcharArray bytes, TQByteArray ** qbyteArray)
{
	uchar *				data;
	unsigned short *	ptr;
	
	if (bytes == 0) {
		return 0;
	}

	jsize len = env->GetArrayLength(bytes);
	if (*qbyteArray == 0) {
		*qbyteArray = new TQByteArray(len*2);
	} else {
		(*qbyteArray)->resize(len*2);
	}

	jboolean isCopy;
	(*qbyteArray)->duplicate((const char *)env->GetCharArrayElements(bytes, &isCopy), len*2);
	data = (uchar *) (*qbyteArray)->data();
	ptr = (unsigned short *) data;
	
	/* Convert the array from 16 bit Java 'char[]' to 8 bit C++ 'char *' array */
	for (int index = 0; index < len; index++) {
		data[index] = (uchar) ptr[index];
	}
	
	(*qbyteArray)->resize(len);
	return (uchar*) (*qbyteArray)->data();
}

TQValueList<int>
QtSupport::toTQIntValueList(JNIEnv * env, jintArray ints, TQValueList<int> ** qintArray)
{
	int		len;
	jint *	carr;
	int		index;
	
	(*qintArray)->clear();
	len = env->GetArrayLength(ints);
	carr = env->GetIntArrayElements(ints, 0);
	
	for (index = 0; index < len; index++) {
		(*qintArray)->append((int) carr[index]);
	}
	
	env->ReleaseIntArrayElements(ints, carr, 0);
	return **qintArray;
}
	
jintArray
QtSupport::fromTQIntValueList(JNIEnv * env, TQValueList<int> * qintArray)
{
	jintArray result = 0;
	int len;
	int	index;

	len = qintArray->size();
	result = env->NewIntArray(len);
	for (index = 0; index < len; index++) {
		env->SetIntArrayRegion(result, index, 1, (jint *) &(*qintArray)[index]);
	}
	
	return result;
}

char **
QtSupport::toArgv(JNIEnv * env, jobjectArray stringList)
{
	char ** 		argv;
	int				length;
	int				index;
	jstring			jstr;
	const char *	str;

	if (stringList == NULL) {
		return NULL;
	}

	length = env->GetArrayLength(stringList);
	argv = (char **) calloc(length + 1, sizeof(char*));
	/* Add a dummy first argument of 'java [interpreter-options] <main class>' to appear
	   in usage messages, in place of the usual executable name from argv[0]. */
	argv[0] = strdup("java [interpreter-options] <main class>");

	for (index = 0; index < length; index++) {
		jstr = (jstring) env->GetObjectArrayElement(stringList, index);
		str = env->GetStringUTFChars(jstr, NULL);
		argv[index + 1] = strdup(str);
		env->ReleaseStringUTFChars(jstr, str);
		env->DeleteLocalRef(jstr);
	}

	return argv;
}

char **
QtSupport::toStringArray(JNIEnv * env, jobjectArray stringList)
{
	char ** 		argv;
	int				length;
	int				index;
	jstring			jstr;
	const char *	str;

	if (stringList == 0) {
		return 0;
	}

	length = env->GetArrayLength(stringList);
	argv = (char **) calloc(length, sizeof(char*));

	for (index = 0; index < length; index++) {
		jstr = (jstring) env->GetObjectArrayElement(stringList, index);
		str = env->GetStringUTFChars(jstr, 0);
		argv[index] = strdup(str);
		env->ReleaseStringUTFChars(jstr, str);
		env->DeleteLocalRef(jstr);
	}

	return argv;
}

TQStrList *
QtSupport::toTQStrList(JNIEnv * env, jobjectArray stringList, TQStrList ** qstringList)
{
	int				length;
	int				index;
	jstring			jstr;
static TQString * _qstring_temp = 0;

	if (*qstringList == 0) {
		*qstringList = new TQStrList();
	}

	(*qstringList)->clear();
	
	if (stringList == 0) {
		return *qstringList;
	}

	length = env->GetArrayLength(stringList);

	for (index = 0; index < length; index++) {
		jstr = (jstring) env->GetObjectArrayElement(stringList, index);
		(*qstringList)->append((TQString &) * (TQString *) QtSupport::toTQString(env, jstr, &_qstring_temp));		
		env->DeleteLocalRef(jstr);
	}

	return *qstringList;
}

TQStringList *
QtSupport::toTQStringList(JNIEnv * env, jobjectArray stringList, TQStringList ** qstringList)
{
	int				length;
	int				index;
	jstring			jstr;
static TQString * _qstring_temp = 0;

	if (*qstringList == 0) {
		*qstringList = new TQStringList();
	}
	
	(*qstringList)->clear();
	
	if (stringList == 0) {
		return *qstringList;
	}

	length = env->GetArrayLength(stringList);

	for (index = 0; index < length; index++) {
		jstr = (jstring) env->GetObjectArrayElement(stringList, index);
		(*qstringList)->append((TQString &) * (TQString *) QtSupport::toTQString(env, jstr, &_qstring_temp));
		env->DeleteLocalRef(jstr);
	}

	return *qstringList;
}


jobject
QtSupport::arrayWithTQStrList(JNIEnv * env, TQStrList * qstrList, jobject stringArray)
{
	jclass			cls;
	jmethodID		clearMid;
	jmethodID		addMid;
	
	if (stringArray == 0) {
		stringArray = (jobject) QtSupport::objectForQtKey(env, qstrList, "java.util.ArrayList");
	}

	cls = env->GetObjectClass(stringArray);
	clearMid = env->GetMethodID(cls, "clear", "()V");
	if (clearMid == 0) {
		return 0;
	}

	env->CallVoidMethod(stringArray, clearMid);

	addMid = env->GetMethodID(cls, "add", "(Ljava/lang/Object;)Z");
	if (addMid == 0) {
		return 0;
	}

	for (unsigned int index = 0; index < qstrList->count(); index++) {
		char * currentItem = (char *) qstrList->at(index);
		jstring currentString = env->NewStringUTF(currentItem);
		
		if (! env->CallBooleanMethod(stringArray, addMid, currentString)) {
			return 0;
		}
		env->DeleteLocalRef(currentString);
	}

	env->DeleteLocalRef(cls);
	return (jobject) stringArray;
}

jobject
QtSupport::arrayWithTQStringList(JNIEnv * env, TQStringList * qstringList, jobject stringArray)
{
	jclass			cls;
	jmethodID		clearMid;
	jmethodID		addMid;

	if (stringArray == 0) {
		stringArray = (jobject) QtSupport::objectForQtKey(env, qstringList, "java.util.ArrayList");
	}

	cls = env->GetObjectClass(stringArray);
	clearMid = env->GetMethodID(cls, "clear", "()V");
	if (clearMid == 0) {
		return 0;
	}

	env->CallVoidMethod(stringArray, clearMid);

	addMid = env->GetMethodID(cls, "add", "(Ljava/lang/Object;)Z");
	if (addMid == 0) {
		return 0;
	}

	for (TQStringList::Iterator it = qstringList->begin(); it != qstringList->end(); ++it) {
		if (! env->CallBooleanMethod(	stringArray,
										addMid,
										QtSupport::fromTQString(env, (TQString *) &(*it)) ) )
		{
			return 0;
		}
	}

	env->DeleteLocalRef(cls);
	return (jobject) stringArray;
}

jobject
QtSupport::arrayWithTQWidgetList(JNIEnv * env, TQWidgetList * widgetList, jobject widgetArray)
{
	jclass			cls;
	jmethodID		clearMid;
	jmethodID		addMid;

	if (widgetArray == 0) {
		widgetArray = (jobject) QtSupport::objectForQtKey(env, widgetList, "java.util.ArrayList");
	}

	cls = env->GetObjectClass(widgetArray);
	clearMid = env->GetMethodID(cls, "clear", "()V");
	if (clearMid == 0) {
		return 0;
	}

	env->CallVoidMethod(widgetArray, clearMid);

	addMid = env->GetMethodID(cls, "add", "(Ljava/lang/Object;)Z");
	if (addMid == 0) {
		return 0;
	}

	for (unsigned int index = 0; index < widgetList->count(); index++) {
		TQWidget * currentWidget = (TQWidget *) widgetList->at(index);
		if (! env->CallBooleanMethod(	widgetArray,
										addMid,
										QtSupport::objectForQtKey(env, currentWidget, "org.trinitydesktop.qt.TQWidget") ) )
		{
			return 0;
		}
	}

	env->DeleteLocalRef(cls);
	return (jobject) widgetArray;
}

jobject
QtSupport::arrayWithTQDomNodeList(JNIEnv * env, TQDomNodeList * domNodeList, jobject domNodeArray)
{
	jclass			cls;
	jmethodID		clearMid;
	jmethodID		addMid;

	if (domNodeArray == 0) {
		domNodeArray = (jobject) QtSupport::objectForQtKey(env, domNodeList, "java.util.ArrayList");
	}

	cls = env->GetObjectClass(domNodeArray);
	clearMid = env->GetMethodID(cls, "clear", "()V");
	if (clearMid == 0) {
		return 0;
	}

	env->CallVoidMethod(domNodeArray, clearMid);

	addMid = env->GetMethodID(cls, "add", "(Ljava/lang/Object;)Z");
	if (addMid == 0) {
		return 0;
	}

	for (unsigned int index = 0; index < domNodeList->count(); index++) {
		TQDomNode currentDomNode = (TQDomNode) domNodeList->item(index);

		if (! env->CallBooleanMethod(	domNodeArray,
										addMid,
										QtSupport::objectForQtKey(env, &currentDomNode, "org.trinitydesktop.qt.TQDomNode") ) )
		{
			return 0;
		}
	}

	env->DeleteLocalRef(cls);
	return (jobject) domNodeArray;
}

jobject
QtSupport::arrayWithTQObjectList(JNIEnv * env, TQObjectList * objectList, jobject objectArray)
{
	jclass			cls;
	jmethodID		clearMid;
	jmethodID		addMid;

	if (objectArray == 0) {
		objectArray = (jobject) QtSupport::objectForQtKey(env, objectList, "java.util.ArrayList");
	}

	cls = env->GetObjectClass(objectArray);
	clearMid = env->GetMethodID(cls, "clear", "()V");
	if (clearMid == 0) {
		return 0;
	}

	env->CallVoidMethod(objectArray, clearMid);

	addMid = env->GetMethodID(cls, "add", "(Ljava/lang/Object;)Z");
	if (addMid == 0) {
		return 0;
	}

	for (unsigned int index = 0; index < objectList->count(); index++) {
		TQObject * currentObject = (TQObject *) objectList->at(index);

		if (! env->CallBooleanMethod(	objectArray,
										addMid,
										QtSupport::objectForQtKey(env, currentObject, "org.trinitydesktop.qt.TQObject") ) )
		{
			return 0;
		}
	}

	env->DeleteLocalRef(cls);
	return (jobject) objectArray;
}

jobject
QtSupport::arrayWithTQCanvasItemList(JNIEnv * env, TQCanvasItemList * itemList, jobject objectArray)
{
	jclass			cls;
	jmethodID		clearMid;
	jmethodID		addMid;

	if (objectArray == 0) {
		objectArray = (jobject) QtSupport::objectForQtKey(env, itemList, "java.util.ArrayList");
	}

	cls = env->GetObjectClass(objectArray);
	clearMid = env->GetMethodID(cls, "clear", "()V");
	if (clearMid == 0) {
		return 0;
	}

	env->CallVoidMethod(objectArray, clearMid);

	addMid = env->GetMethodID(cls, "add", "(Ljava/lang/Object;)Z");
	if (addMid == 0) {
		return 0;
	}
	
	for (TQCanvasItemList::Iterator it = itemList->begin(); it != itemList->end(); ++it) {
		const char * classString;

		switch ((*it)->rtti()) {
		case TQCanvasItem::Rtti_Item:
			classString = "org.trinitydesktop.qt.TQCanvasItem";
			break;
		case TQCanvasItem::Rtti_Ellipse:
			classString = "org.trinitydesktop.qt.TQCanvasEllipse";
			break;
		case TQCanvasItem::Rtti_Line:
			classString = "org.trinitydesktop.qt.TQCanvasLine";
			break;
		case TQCanvasItem::Rtti_Polygon:
			classString = "org.trinitydesktop.qt.TQCanvasPolygon";
			break;
		case TQCanvasItem::Rtti_PolygonalItem:
			classString = "org.trinitydesktop.qt.TQCanvasPolygonalItem";
			break;
		case TQCanvasItem::Rtti_Rectangle:
			classString = "org.trinitydesktop.qt.TQCanvasRectangle";
			break;
		case TQCanvasItem::Rtti_Spline:
			classString = "org.trinitydesktop.qt.TQCanvasSpline";
			break;
		case TQCanvasItem::Rtti_Sprite:
			classString = "org.trinitydesktop.qt.TQCanvasSprite";
			break;
		case TQCanvasItem::Rtti_Text:
			classString = "org.trinitydesktop.qt.TQCanvasText";
			break;
		default:
			classString = "org.trinitydesktop.qt.TQCanvasItem";
			break;
		}

		if (! env->CallBooleanMethod(	objectArray,
										addMid,
										QtSupport::objectForQtKey(env, *it, classString) ) )
		{
			return 0;
		}
	}

	env->DeleteLocalRef(cls);
	return (jobject) objectArray;
}

jobject
QtSupport::arrayWithTQListViewItemList(JNIEnv * env, TQListViewItemIterator * iterator, jobject arrayList)
{
	jclass			cls;
	jmethodID		clearMid;
	jmethodID		addMid;
    const char *			className;

	if (arrayList == 0) {
		arrayList = (jobject) QtSupport::objectForQtKey(env, iterator, "java.util.ArrayList");
	}

	cls = env->GetObjectClass(arrayList);
	clearMid = env->GetMethodID(cls, "clear", "()V");
	if (clearMid == 0) {
		return 0;
	}

	env->CallVoidMethod(arrayList, clearMid);

	addMid = env->GetMethodID(cls, "add", "(Ljava/lang/Object;)Z");
	if (addMid == 0) {
		return 0;
	}
	
	for (	; iterator->current(); ++(*iterator)) {
		TQListViewItem * currentItem =  iterator->current();
		
		/* rtti() is: 0 = TQListViewItem, 1 = TQCheckListItem */
		className = (currentItem->rtti() == 1 ? "org.trinitydesktop.qt.TQCheckListItem" : "org.trinitydesktop.qt.TQListViewItem");
		if (! env->CallBooleanMethod(	arrayList,
										addMid,
										QtSupport::objectForQtKey(env, currentItem, className) ) )
		{
			return 0;
		}
	}

	env->DeleteLocalRef(cls);
	return (jobject) arrayList;
}

jobject
QtSupport::arrayWithTQRectList(JNIEnv * env, TQMemArray<TQRect> * rectList, jobject arrayList)
{
	jclass			cls;
	jmethodID		clearMid;
	jmethodID		addMid;

	if (arrayList == 0) {
		arrayList = (jobject) QtSupport::objectForQtKey(env, rectList, "java.util.ArrayList");
	}

	cls = env->GetObjectClass(arrayList);
	clearMid = env->GetMethodID(cls, "clear", "()V");
	if (clearMid == 0) {
		return 0;
	}

	env->CallVoidMethod(arrayList, clearMid);

	addMid = env->GetMethodID(cls, "add", "(Ljava/lang/Object;)Z");
	if (addMid == 0) {
		return 0;
	}

	for (unsigned int index = 0; index < rectList->count(); index++) {
		TQRect currentRect = (TQRect) rectList->at(index);
		if (! env->CallBooleanMethod(	arrayList,
										addMid,
										QtSupport::objectForQtKey(	env,
																	new TQRect(currentRect.topLeft(), currentRect.bottomRight()),
																	"org.trinitydesktop.qt.TQRect",
																	true ) ) )
		{
			return 0;
		}
	}

	env->DeleteLocalRef(cls);
	return (jobject) arrayList;
}

jobject
QtSupport::arrayWithTQIconDragItemList(JNIEnv * env, TQValueList<TQIconDragItem> * dragItemList, jobject arrayList)
{
	jclass			cls;
	jmethodID		clearMid;
	jmethodID		addMid;

	if (arrayList == 0) {
		arrayList = (jobject) QtSupport::objectForQtKey(env, dragItemList, "java.util.ArrayList");
	}

	cls = env->GetObjectClass(arrayList);
	clearMid = env->GetMethodID(cls, "clear", "()V");
	if (clearMid == 0) {
		return 0;
	}

	env->CallVoidMethod(arrayList, clearMid);

	addMid = env->GetMethodID(cls, "add", "(Ljava/lang/Object;)Z");
	if (addMid == 0) {
		return 0;
	}

	for (TQValueList<TQIconDragItem>::Iterator it = dragItemList->begin(); it != dragItemList->end(); ++it) {
		TQIconDragItem currentItem = (TQIconDragItem) *it;
		if (! env->CallBooleanMethod(	arrayList,
										addMid,
										QtSupport::objectForQtKey(env, &currentItem, "org.trinitydesktop.qt.TQIconDragItem") ) )
		{
			return 0;
		}
	}

	env->DeleteLocalRef(cls);
	return (jobject) arrayList;
}

jobject
QtSupport::arrayWithTQUrlInfoList(JNIEnv * env, TQValueList<TQUrlInfo> * infoList, jobject arrayList)
{
	jclass			cls;
	jmethodID		clearMid;
	jmethodID		addMid;

	if (arrayList == 0) {
		arrayList = (jobject) QtSupport::objectForQtKey(env, infoList, "java.util.ArrayList");
	}

	cls = env->GetObjectClass(arrayList);
	clearMid = env->GetMethodID(cls, "clear", "()V");
	if (clearMid == 0) {
		return 0;
	}

	env->CallVoidMethod(arrayList, clearMid);

	addMid = env->GetMethodID(cls, "add", "(Ljava/lang/Object;)Z");
	if (addMid == 0) {
		return 0;
	}

	for (TQValueList<TQUrlInfo>::Iterator it = infoList->begin(); it != infoList->end(); ++it) {
		TQUrlInfo currentItem = (TQUrlInfo) *it;
		if (! env->CallBooleanMethod(	arrayList,
										addMid,
										QtSupport::objectForQtKey(env, &currentItem, "org.trinitydesktop.qt.TQUrlInfo") ) )
		{
			return 0;
		}
	}

	env->DeleteLocalRef(cls);
	return (jobject) arrayList;
}
