/***************************************************************************
                            DCOPObject.cpp -  description
                             -------------------
    begin                : Fri Nov 15 11:45:52 2002
    copyright            : (C) 2000-2002 Lost Highway Ltd.
    email                : Richard_Dale@tipitina.demon.co.uk
    generated by         : duke@tipitina on Fri Nov 15 11:45:52 2002, using kalyptus 0.9.
 ***************************************************************************/

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

#define _BOOL_H_
#include <dcopobject.h>
#include <qstring.h>
#include <qcstring.h>

#include <qtjava/QtSupport.h>
#include <kdejava/KDESupport.h>
#include <kdejava/DCOPObject.h>

class DCOPObjectJBridge : public DCOPObject
{
public:
	DCOPObjectJBridge() : DCOPObject() {}
	DCOPObjectJBridge(QObject* obj) : DCOPObject(obj) {}
	DCOPObjectJBridge(const QCString& objId) : DCOPObject(objId) {}
	~DCOPObjectJBridge() {QtSupport::qtKeyDeleted(this);}
	void protected_virtual_hook(int id, void* data) {
		DCOPObject::virtual_hook(id, data);
		return;
	}
	virtual QCStringList interfaces()  {
		QCStringList interfaces = DCOPObject::interfaces();    
		jobject javaInterfaces = this->invokeInterfaces();
		if(javaInterfaces != NULL) {
			this->convertArrayListToQCStingList(javaInterfaces, &interfaces);
			QtSupport::GetEnv()->DeleteLocalRef(javaInterfaces);
		}
		return interfaces;
	}
	
	virtual QCStringList functions() {
		QCStringList funcs = DCOPObject::functions();
		jobject javaFunctions = this->invokeFunctions();
		if(javaFunctions != NULL) {
			this->convertArrayListToQCStingList(javaFunctions, &funcs);
			QtSupport::GetEnv()->DeleteLocalRef(javaFunctions);
		}
		return funcs;
	}
  
  virtual bool process(const QCString &fun, const QByteArray &data, QCString& replyType, QByteArray &replyData)
  {
     if(fun == "interfaces()" || fun =="functions()"){
       return DCOPObject::process(fun, data, replyType, replyData);
     }else{
       replyType = "" ;
       JNIEnv *env = QtSupport::GetEnv();
       jclass cls = env->FindClass("org/kde/koala/Invocation");

       static jmethodID mid = 0;
       if(mid == 0)
         mid = env->GetStaticMethodID(cls, "invokeProcess", "(JLjava/lang/String;[B)Lorg/kde/koala/DCOPAnswer;");
       jstring javaFun = QtSupport::fromQCString(env, (QCString *) &fun);
       
       jbyteArray javaData = 0;
       if(((QByteArray *) &data) != 0){
         javaData = QtSupport::fromQByteArray(env, (QByteArray*) &data);
       }else{
         QByteArray* dummyData = new QByteArray();
         javaData = QtSupport::fromQByteArray(env, dummyData);         
       }

       if(mid != 0){
           static jmethodID midSucces = 0;
           static jmethodID midReplyData = 0;
           static jmethodID midReplyType = 0;
           jobject answer = env->CallStaticObjectMethod(cls, mid,
                                                     (jlong) this,
                                                     (jstring)javaFun,
                                                     (jbyteArray)javaData);
           jclass answerCls = env->FindClass("org/kde/koala/DCOPAnswer");
           if(midSucces == 0)
             midSucces = env->GetMethodID(answerCls, "getSucces", "()Z");
           if(midReplyData == 0)
             midReplyData = env->GetMethodID(answerCls, "getReplyData", "()[B");
           if(midReplyType == 0)
             midReplyType = env->GetMethodID(answerCls, "getType", "()Ljava/lang/String;");
           jboolean success = env->CallBooleanMethod(answer, midSucces);
           jbyteArray javaReplyData = (jbyteArray)env->CallObjectMethod(answer, midReplyData);
           jstring javaReplyType = (jstring) env->CallObjectMethod(answer, midReplyType);
           
          //QtSupport::toQCString(env, javaFun, (QCString*)(QCString*) &replyType);
           QByteArray * temp = &replyData;
           QtSupport::toQByteArray(env, javaReplyData, &temp);
           QCString *tempType = &replyType;
           QtSupport::toQCString(env, javaReplyType,&tempType);
           env->DeleteLocalRef(javaReplyData);
           env->DeleteLocalRef(javaReplyType);
          return (bool) success;
       }else{
         return FALSE;
       }
       env->DeleteLocalRef(javaFun);
       env->DeleteLocalRef(javaData);
       env->DeleteLocalRef(cls);
     }
  }
  bool processSuper(const QCString &fun, const QByteArray &data, QCString& replyType, QByteArray &replyData){
    return DCOPObject::process(fun, data, replyType, replyData);
  }
private:
  jobject invokeFunctions(){

     JNIEnv *env;
     jclass  cls;
     jmethodID	mid;
     env = QtSupport::GetEnv();

     cls = env->FindClass("org/kde/koala/Invocation");
     if (cls == 0) {
       return NULL;
     }

     mid = env->GetStaticMethodID(cls, "invokeFunctions", "(J)Ljava/util/ArrayList;");
     if (mid == 0) {
       return NULL;
     }

     jobject result = env->CallStaticObjectMethod(cls, mid, (jlong) this);
     env->DeleteLocalRef(cls);
     return result;
  }
  jobject invokeInterfaces(){

     JNIEnv *env;
     jclass  cls;
     jmethodID	mid;
     env = QtSupport::GetEnv();

     cls = env->FindClass("org/kde/koala/Invocation");
     if (cls == 0) {
       return NULL;
     }

     mid = env->GetStaticMethodID(cls, "invokeInterfaces", "(J)Ljava/util/ArrayList;");
     if (mid == 0) {
       return NULL;
     }
     jobject result = env->CallStaticObjectMethod(cls, mid, (jlong) this);
     env->DeleteLocalRef(cls);
     return result;
  }
  void convertArrayListToQCStingList(jobject arrayList, QCStringList* qList){
     JNIEnv *env = NULL;
     jclass  listCls = NULL;
     static jmethodID	midToArray = NULL;
     env = QtSupport::GetEnv();
     static QCString * _qstring_temp = 0;

     // get array from the java List
     listCls = env->FindClass("java/util/ArrayList");
     if(midToArray == 0)
       midToArray = env->GetMethodID(listCls, "toArray","()[Ljava/lang/Object;");
     if (midToArray == 0) {
       return;
     }
     jobjectArray array = (jobjectArray) env->CallObjectMethod(arrayList, midToArray);

     
     // fill qList with contents of the java List
     int length = env->GetArrayLength(array);     
     for(int i = 0; i < length; i++){
       jstring element = (jstring) env->GetObjectArrayElement(array, i);  
       qList->append(QtSupport::toCharString(env, element, &_qstring_temp));
       env->DeleteLocalRef(element);
     }
     env->DeleteLocalRef(array);
     env->DeleteLocalRef(listCls);
  }
};


JNIEXPORT void JNICALL
Java_org_kde_koala_DCOPObject_newDCOPObject__(JNIEnv *env, jobject obj)
{
	if (QtSupport::getQt(env, obj) == 0) {
		QtSupport::setQt(env, obj, new DCOPObjectJBridge());
		QtSupport::setObjectForQtKey(env, obj, QtSupport::getQt(env, obj));
	}
	return;
}

//JNIEXPORT void JNICALL
//Java_org_kde_koala_DCOPObject_newDCOPObject__Lorg_kde_qt_QObject_2(JNIEnv *env, jobject obj, jobject obj)
//{
//	if (QtSupport::getQt(env, obj) == 0) {
//		QtSupport::setQt(env, obj, new DCOPObjectJBridge((QObject*) QtSupport::getQt(env, obj)));
//		QtSupport::setObjectForQtKey(env, obj, QtSupport::getQt(env, obj));
//	}
//	return;
//}

JNIEXPORT void JNICALL
Java_org_kde_koala_DCOPObject_newDCOPObject__Ljava_lang_String_2(JNIEnv *env, jobject obj, jstring objId)
{
static QCString * _qcstring_objId = 0;
	if (QtSupport::getQt(env, obj) == 0) {
		QtSupport::setQt(env, obj, new DCOPObjectJBridge((QCString&) * (QCString *) QtSupport::toQCString(env, objId, &_qcstring_objId)));
		QtSupport::setObjectForQtKey(env, obj, QtSupport::getQt(env, obj));
	}
	return;
}

JNIEXPORT void JNICALL
Java_org_kde_koala_DCOPObject_finalize(JNIEnv *env, jobject obj)
{
	if (QtSupport::allocatedInJavaWorld(env, obj)) {
		delete (DCOPObject*)QtSupport::getQt(env, obj);
		QtSupport::setQt(env, obj, 0);
	}
	return;
}

JNIEXPORT void JNICALL
Java_org_kde_koala_DCOPObject_dispose(JNIEnv *env, jobject obj)
{
	Java_org_kde_koala_DCOPObject_finalize(env, obj);
	return;
}

JNIEXPORT jboolean JNICALL
Java_org_kde_koala_DCOPObject_isDisposed(JNIEnv *env, jobject obj)
{
	return (QtSupport::getQt(env, obj) == 0);
}

JNIEXPORT jstring JNICALL
Java_org_kde_koala_DCOPObject_objId(JNIEnv *env, jobject obj)
{
	QCString  _qcstring;
	_qcstring = ((DCOPObject*) QtSupport::getQt(env, obj))->objId();
	return QtSupport::fromQCString(env, &_qcstring);
}

JNIEXPORT jboolean JNICALL
Java_org_kde_koala_DCOPObject_setObjId(JNIEnv *env, jobject obj, jstring objId)
{
static QCString * _qcstring_objId = 0;
	return (jboolean) ((DCOPObject*) QtSupport::getQt(env, obj))->setObjId((QCString&) * (QCString *) QtSupport::toQCString(env, objId, &_qcstring_objId));
}

JNIEXPORT jboolean JNICALL
Java_org_kde_koala_DCOPObject_process(JNIEnv *env, jobject obj, jstring fun, jbyteArray data, jstring replyType, jbyteArray replyData)
{
static QByteArray * _qbyteArray_replyData = 0;
static QCString * _qcstring_replyType = 0;
static QByteArray * _qbyteArray_data = 0;
static QCString * _qcstring_fun = 0;
	return (jboolean) ((DCOPObject*) QtSupport::getQt(env, obj))->process((QCString&) * (QCString *) QtSupport::toQCString(env, fun, &_qcstring_fun), (QByteArray&) * (QByteArray *) QtSupport::toQByteArray(env, data, &_qbyteArray_data), (QCString&) * (QCString *) QtSupport::toQCString(env, replyType, &_qcstring_replyType), (QByteArray&) * (QByteArray *) QtSupport::toQByteArray(env, replyData, &_qbyteArray_replyData));
}

JNIEXPORT jboolean JNICALL
Java_org_kde_koala_DCOPObject_processDynamic(JNIEnv *env, jobject obj, jstring fun, jbyteArray data, jstring replyType, jbyteArray replyData)
{
static QByteArray * _qbyteArray_replyData = 0;
static QCString * _qcstring_replyType = 0;
static QByteArray * _qbyteArray_data = 0;
static QCString * _qcstring_fun = 0;
	return (jboolean) ((DCOPObject*) QtSupport::getQt(env, obj))->processDynamic((QCString&) * (QCString *) QtSupport::toQCString(env, fun, &_qcstring_fun), (QByteArray&) * (QByteArray *) QtSupport::toQByteArray(env, data, &_qbyteArray_data), (QCString&) * (QCString *) QtSupport::toQCString(env, replyType, &_qcstring_replyType), (QByteArray&) * (QByteArray *) QtSupport::toQByteArray(env, replyData, &_qbyteArray_replyData));
}

JNIEXPORT jobject JNICALL
Java_org_kde_koala_DCOPObject_functionsDynamic(JNIEnv *env, jobject obj)
{
	QCStringList  _qlist;
	_qlist = ((DCOPObject*) QtSupport::getQt(env, obj))->functionsDynamic();
	return (jobject) KDESupport::arrayWithQCStringList(env, (QCStringList *) &_qlist);
}

JNIEXPORT jobject JNICALL
Java_org_kde_koala_DCOPObject_interfacesDynamic(JNIEnv *env, jobject obj)
{
	QCStringList  _qlist;
	_qlist = ((DCOPObject*) QtSupport::getQt(env, obj))->interfacesDynamic();
	return (jobject) KDESupport::arrayWithQCStringList(env, (QCStringList *) &_qlist);
}

JNIEXPORT jobject JNICALL
Java_org_kde_koala_DCOPObject_interfaces(JNIEnv *env, jobject obj)
{
	QCStringList  _qlist;
	_qlist = ((DCOPObject*) QtSupport::getQt(env, obj))->interfaces();
	return (jobject) KDESupport::arrayWithQCStringList(env, (QCStringList *) &_qlist);
}

JNIEXPORT jobject JNICALL
Java_org_kde_koala_DCOPObject_functions(JNIEnv *env, jobject obj)
{
	QCStringList  _qlist;
	_qlist = ((DCOPObject*) QtSupport::getQt(env, obj))->functions();
	return (jobject) KDESupport::arrayWithQCStringList(env, (QCStringList *) &_qlist);
}

JNIEXPORT void JNICALL
Java_org_kde_koala_DCOPObject_emitDCOPSignal(JNIEnv *env, jobject obj, jstring signal, jbyteArray data)
{
static QByteArray * _qbyteArray_data = 0;
static QCString * _qcstring_signal = 0;
	((DCOPObject*) QtSupport::getQt(env, obj))->emitDCOPSignal((QCString&) * (QCString *) QtSupport::toQCString(env, signal, &_qcstring_signal), (QByteArray&) * (QByteArray *) QtSupport::toQByteArray(env, data, &_qbyteArray_data));
	return;
}

JNIEXPORT jboolean JNICALL
Java_org_kde_koala_DCOPObject_connectDCOPSignal(JNIEnv *env, jobject obj, jstring sender, jstring senderObj, jstring signal, jstring slot, jboolean Volatile)
{
static QCString * _qcstring_slot = 0;
static QCString * _qcstring_signal = 0;
static QCString * _qcstring_senderObj = 0;
static QCString * _qcstring_sender = 0;
	return (jboolean) ((DCOPObject*) QtSupport::getQt(env, obj))->connectDCOPSignal((QCString&) * (QCString *) QtSupport::toQCString(env, sender, &_qcstring_sender), (QCString&) * (QCString *) QtSupport::toQCString(env, senderObj, &_qcstring_senderObj), (QCString&) * (QCString *) QtSupport::toQCString(env, signal, &_qcstring_signal), (QCString&) * (QCString *) QtSupport::toQCString(env, slot, &_qcstring_slot), (bool) Volatile);
}

JNIEXPORT jboolean JNICALL
Java_org_kde_koala_DCOPObject_disconnectDCOPSignal(JNIEnv *env, jobject obj, jstring sender, jstring senderObj, jstring signal, jstring slot)
{
static QCString * _qcstring_slot = 0;
static QCString * _qcstring_signal = 0;
static QCString * _qcstring_senderObj = 0;
static QCString * _qcstring_sender = 0;
	return (jboolean) ((DCOPObject*) QtSupport::getQt(env, obj))->disconnectDCOPSignal((QCString&) * (QCString *) QtSupport::toQCString(env, sender, &_qcstring_sender), (QCString&) * (QCString *) QtSupport::toQCString(env, senderObj, &_qcstring_senderObj), (QCString&) * (QCString *) QtSupport::toQCString(env, signal, &_qcstring_signal), (QCString&) * (QCString *) QtSupport::toQCString(env, slot, &_qcstring_slot));
}

JNIEXPORT jobject JNICALL
Java_org_kde_koala_DCOPObject_callingDcopClient(JNIEnv *env, jobject obj)
{
	return (jobject) QtSupport::objectForQtKey(env, (void *)((DCOPObject*) QtSupport::getQt(env, obj))->callingDcopClient(), "org.kde.koala.DCOPClient");
}

JNIEXPORT void JNICALL
Java_org_kde_koala_DCOPObject_setCallingDcopClient(JNIEnv *env, jobject obj, jobject arg1)
{
	((DCOPObject*) QtSupport::getQt(env, obj))->setCallingDcopClient((DCOPClient*) QtSupport::getQt(env, arg1));
	return;
}

JNIEXPORT jboolean JNICALL
Java_org_kde_koala_DCOPObject_hasObject(JNIEnv *env, jclass obj, jstring objId)
{
static QCString * _qcstring_objId = 0;
	return (jboolean) DCOPObjectJBridge::hasObject((QCString&) * (QCString *) QtSupport::toQCString(env, objId, &_qcstring_objId));
}

JNIEXPORT jobject JNICALL
Java_org_kde_koala_DCOPObject_find(JNIEnv *env, jclass obj, jstring objId)
{
static QCString * _qcstring_objId = 0;
	return (jobject) QtSupport::objectForQtKey(env, (void *)DCOPObjectJBridge::find((QCString&) * (QCString *) QtSupport::toQCString(env, objId, &_qcstring_objId)), "org.kde.koala.DCOPObjectInterface");
}

//JNIEXPORT  JNICALL
//Java_org_kde_koala_DCOPObject_match(JNIEnv *env, jclass obj, jstring partialId)
//{
//static QCString * _qcstring_partialId = 0;
//	return () DCOPObjectJBridge::match((QCString&) * (QCString *) QtSupport::toQCString(env, partialId, &_qcstring_partialId));
//}

//JNIEXPORT jstring JNICALL
//Java_org_kde_koala_DCOPObject_objectName(JNIEnv *env, jclass obj, jobject obj)
//{
//	QCString  _qcstring;
//	_qcstring = DCOPObjectJBridge::objectName((QObject*) QtSupport::getQt(env, obj));
//	return QtSupport::fromQCString(env, &_qcstring);
//}

JNIEXPORT void JNICALL
Java_org_kde_koala_DCOPObject_virtual_1hook(JNIEnv *env, jobject obj, jint identifier, jint data)
{
	((DCOPObjectJBridge*) QtSupport::getQt(env, obj))->protected_virtual_hook((int) identifier, (void*) data);
	return;
}

