/***************************************************************************
                            QtSupport.h -  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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef _QT_SUPPORT_H_
#define _QT_SUPPORT_H_

#include <jni.h>

#ifndef JNIEXPORT
#define JNIEXPORT
#endif

#ifndef JNIIMPORT
#define JNIIMPORT
#endif

#ifndef JNICALL
#define JNICALL
#endif

#include <qstrlist.h>
#include <qstringlist.h>
#include <qwidgetlist.h>
#include <qdom.h>
#include <qobjectlist.h>
#include <qdatetime.h>
#include <qevent.h>
#include <qvalidator.h>
#include <qcanvas.h>
#include <qlistview.h>
#include <qiconview.h>
#include <qurlinfo.h>

class JavaSlot;
class JavaSignal;


/** A class with various static utility methods to run the C++ side
	of the Qt Java library. The functions cooperate with the Java
	methods in 'qtjava.java' and 'Invocation.java'.

	@author Richard Dale */
class QtSupport
{
public:
	QtSupport() {}
	~QtSupport() {}

	/** Save the current JavaVM pointer to make it easy to obtain the current environment later */
	static void registerJVM(JNIEnv * env);
	/** Obtain the current JNIEnv */
	static JNIEnv * GetEnv();

	/** Converts from the enum QEvent::Type to the Java class name of the corresponding event */
	static const char * eventTypeToEventClassName(QEvent::Type eventType);
	/** Event filter handling callback function */
	static bool eventFilterDelegate(QObject * object, const char * objectType, QObject * filterTarget, QEvent * event);
	/** Event handling callback function */
	static bool eventDelegate(QObject * object, const char * eventType, void * event, const char * eventName);
	/** Void method with no parameters. FALSE if method is implemented in Java,
	    and returns TRUE if method is not implemented in Java */
	static bool voidDelegate(void * object, const char * className, const char * methodName);
	/** Boolean method with no parameters. FALSE iff method is implemented in Java
	    and also returns FALSE. Returns TRUE if method is not implemented in Java */
	static bool booleanDelegate(QObject * object, const char * methodName);

	/** QValidator callbacks for validate() and fixup() */
	static int validateDelegate(QValidator * object, QString & input, int & pos);
	static void fixupDelegate(QValidator * object, QString & input);

	/** C++ instances are deleted in a finalize method iff 'allocatedInJavaWorld' is true. */
	static bool allocatedInJavaWorld(JNIEnv * env, jobject obj);
	static void setAllocatedInJavaWorld(JNIEnv * env, jobject obj, bool yn);

	/** Obtain the wrapped C++ instance for a given Java instance */
	static void * getQt(JNIEnv * env, jobject obj);
	/** Set the wrapped C++ instance for a given Java instance */
	static void setQt(JNIEnv * env, jobject obj, void * qt);

	/** Add a 'C++ instance key/Java instance value' pair to the qtKeyToJavaMap */
	static void setObjectForQtKey(JNIEnv * env, jobject obj, void * qt);
	
	/** Obtain the Jave instance for the given C++ instance, instantiating a new
		instance of the given class name if needed */
	static jobject objectForQtKey(JNIEnv * env, void * qt, const char * className, const bool allocatedInJavaWorld = FALSE);

	/** A 'C++ instance has been deleted. Set '_allocatedInJavaWorld' to false in the corresponding java instance */
	static void qtKeyDeleted(void * qt);

	/** Connect a C++ or Java sender to a Java receiver */
	static jboolean connect(JNIEnv * env, jobject sender, jstring signal, jobject receiver, jstring slot);

	/** Disconnect a C++ or Java sender from a Java receiver */
	static jboolean disconnect(JNIEnv * env, jobject sender, jstring signal, jobject receiver, jstring slot);

	/** Invoke a Java slot with arguments 'args'. */
	static void emitJavaSignal(JNIEnv * env, jobject sender, jstring signal, jobjectArray args);

	/** Return a JavaSignal proxy instance for a Java signal. Creates a new one if needed. */
	static JavaSignal * signalForSender(JNIEnv * env, void * qt, jstring signal);
	/** Return a JavaSlot proxy instance for a Java slot. Creates a new one if needed. */
	static JavaSlot * slotForReceiver(JNIEnv * env, jobject receiver, jstring slot);

	/** Casts a 'QWidget *', 'QPixmap *' or subclass of QPaintDevice correctly to a 'QPaintDevice *'.
	 	Needed because of C++ multiple inheritance complications. */
	static QPaintDevice * paintDevice(JNIEnv * env, jobject obj);
	/** Casts a 'QDragObject *', 'QDropEvent *' or subclass of QDropEvent correctly to a 'QMimeSource *'.
	 	Needed because of C++ multiple inheritance complications. */
	static QMimeSource * mimeSource(JNIEnv * env, jobject obj);

	/** Which byte order are Java strings */
	static bool bigEndianUnicode();

	/** Convert from Java primitive array types to C++ primitive array */
	static bool * toBooleanPtr(JNIEnv * env, jbooleanArray obj);
	static int * toIntPtr(JNIEnv * env, jintArray obj);
	static double * toDoublePtr(JNIEnv * env, jdoubleArray obj);
	static short * toShortPtr(JNIEnv * env, jshortArray obj);

	/** Convert from C++ primitive array types to Java primitive arrays */
	static jbooleanArray fromBooleanPtr(JNIEnv * env, bool * arg);
	static jintArray fromIntPtr(JNIEnv * env, int * arg);
	static jdoubleArray fromDoublePtr(JNIEnv * env, double * arg);
	static jshortArray fromShortPtr(JNIEnv * env, short * arg);

	/** Convert from Qt dates and times to Java Date and Time */
	static jobject fromQDateTime(JNIEnv * env, QDateTime* qdate);
	static jobject fromQDate(JNIEnv * env, QDate* qdate);
	static jobject fromQTime(JNIEnv * env, QTime* qtime);

	/** Convert from Java Date and Time to Qt dates and times */
	static QDateTime * toQDateTime(JNIEnv * env, jobject jdate, QDateTime** qdate);
	static QDate * toQDate(JNIEnv * env, jobject jdate, QDate** qdate);
	static QTime * toQTime(JNIEnv * env, jobject jtime, QTime** qtime);

	/** Convert from QString to Java String */
	static jstring fromQString(JNIEnv * env, QString * qstring);
	/** Convert from QCString to Java String */
	static jstring fromQCString(JNIEnv * env, QCString * qcstring);
	/** Convert from a char * to Java String */
	static jstring fromCharString(JNIEnv * env, char * qcstring);

	/** Convert from Java String to QString */
	static QString * toQString(JNIEnv * env, jstring str, QString ** qstring);
	/** Convert from Java String to QCString */
	static QCString * toQCString(JNIEnv * env, jstring str, QCString ** qcstring);
	/** Convert from Java String to a char * */
	static char * toCharString(JNIEnv * env, jstring str, QCString ** qcstring);

	/** Convert from QString to Java StringBuffer */
	static void fromQStringToStringBuffer(JNIEnv * env, QString * qstring, jobject buffer);
	/** Convert from Java StringBuffer to QString */
	static QString * toQStringFromStringBuffer(JNIEnv * env, jobject buffer, QString ** qstring);
	/** Convert from QCString to Java StringBuffer */
	static void fromQCStringToStringBuffer(JNIEnv * env, QCString * qcstring, jobject buffer);
	
	/** Convert from QChar to Java char */
	static jchar fromQChar(JNIEnv * env, QChar * qchar);
	/** Convert from Java char to QChar */
	static QChar * toQChar(JNIEnv * env, jchar unichar, QChar ** qchar);

	/** Convert from QByteArray to Java byte array */
	static jbyteArray fromQByteArray(JNIEnv * env, QByteArray * qbyteArray);
	/** Convert from Java byte array to QByteArray */
	static QByteArray * toQByteArray(JNIEnv * env, jbyteArray bytes, QByteArray ** qbyteArray);
	/** Convert from Java 'char[]' to 'uchar *' */
	static uchar * toUcharArray(JNIEnv * env, jcharArray bytes, QByteArray ** qbyteArray);

	/** Convert from Java 'int[]' to QValueList<int> */
	static QValueList<int> toQIntValueList(JNIEnv * env, jintArray ints, QValueList<int> ** qintArray);
	/** Convert from QValueList<int> to Java 'int[]' */
	static jintArray fromQIntValueList(JNIEnv * env, QValueList<int> * qintArray);
	
	/** Convert from a String[] to char * argv[], adding a dummy argv[0] argument */
	static char ** toArgv(JNIEnv * env, jobjectArray stringList);
	/** Convert from a String[] to char * argv[] */
	static char ** toStringArray(JNIEnv * env, jobjectArray stringList);
	/** Convert from String[] to QStrList */
	static QStrList * toQStrList(JNIEnv * env, jobjectArray stringList, QStrList ** qstringList);
	/** Convert from String[] to QStringList */
	static QStringList * toQStringList(JNIEnv * env, jobjectArray stringList, QStringList ** qstringList);

	/** Returns a Java ArrayList for the various types of Qt List */
	static jobject arrayWithQStrList(JNIEnv * env, QStrList * strList, jobject arrayList = 0);
	static jobject arrayWithQStringList(JNIEnv * env, QStringList * stringList, jobject arrayList = 0);
	static jobject arrayWithQWidgetList(JNIEnv * env, QWidgetList * widgetList, jobject arrayList = 0);
	static jobject arrayWithQDomNodeList(JNIEnv * env, QDomNodeList * domNodeList, jobject arrayList = 0);
	static jobject arrayWithQObjectList(JNIEnv * env, QObjectList * objectList, jobject arrayList = 0);
	static jobject arrayWithQCanvasItemList(JNIEnv * env, QCanvasItemList * itemList, jobject arrayList = 0);
	static jobject arrayWithQListViewItemList(JNIEnv * env, QListViewItemIterator * iterator, jobject arrayList = 0);
	static jobject arrayWithQRectList(JNIEnv * env, QMemArray<QRect> * rectList, jobject arrayList = 0);
	static jobject arrayWithQIconDragItemList(JNIEnv * env, QValueList<QIconDragItem> * dragItemList, jobject arrayList = 0);
	static jobject arrayWithQUrlInfoList(JNIEnv * env, QValueList<QUrlInfo> * infoList, jobject arrayList = 0);

protected:
	/** Cache String constructor from bytes, and getBytes() method info */
	static jmethodID MID_String_init;
	static jmethodID MID_String_getBytes;

	/** Result of the test for the endianess of the unicode string returned by GetStringChars() */
	static bool _bigEndianUnicode;
};

#endif

