/***************************************************************************
                            kde_DCOPRef.h -  description
                             -------------------
    begin                : Sun Nov 24 16:54:36 2002
    copyright            : (C) 2000-2001 Lost Highway Ltd. All rights reserved.
    email                : Lost_Highway@tipitina.demon.co.uk
    generated by         : duke@tipitina on Sun Nov 24 16:54:36 2002, using kalyptus 0.9.
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This library 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.                       *
 *                                                                         *
 ***************************************************************************/

#ifndef KDE_DCOPREF
#define KDE_DCOPREF

#include <qtc/qtc_types.h>

#include <kdec/kde_types.h>

/**
*
 A DCOPRef(erence) encapsulates a remote DCOP object as a triple
 <app,obj,type> where type is optional. It allows for calling and
 passing DCOP objects.

 A DCOP reference makes it possible to return references to other DCOP
 objects in a DCOP interface, for example in the method
 giveMeAnotherObject() in an interface like this:

 <pre>
	class Example : public DCOPObject
	{
	   K_DCOP
	...
	k_dcop:
	   DCOPRef giveMeAnotherObject();
	   int doSomething( QString, float, bool );
	   ASYNC pingMe( QCString message );
	   UserType userFunction( UserType );
	};
 </pre>

 In addition, the reference can operate as a comfortable generic
 stub to call remote DCOP objects in cases where no DCOPStub is
 available. The advantage of using DCOPRef instead of the low-level
 functions DCOPClient::call() and DCOPClient::send() are the nicer
 syntax and the implicit runtime error checking.

 Say you want to call the method "doSomething" from the above
 interface on an object called "example" that lives in application
 "foo". Using DCOPRef, you would write

 <pre>
	DCOPRef example( "foo", "example" );
	int result = example.call( "doSomething", "Hello World", (float)2.5, true );
 </pre>

 If it is important for you to know whether the call succeeded or
 not, you can use the slightly more elaborate pattern:

 <pre>
	DCOPRef example( "foo", "example" );
	DCOPReply reply = example.call( "doSomething", "Hello World", (float)2.5, true );
	if ( reply.isValid() ) {
	    int result = reply;
	    // ...
	}
 </pre>

 For curiosity, here is how you would achieve the exactly same
 functionality by using DCOPClient::call() directly:

 <pre>
    QByteArray data, replyData;
    QCString replyType;
    QDataStream arg( data, IO_WriteOnly );
    arg << QString("hello world" ), (float) 2.5 << true;
    if ( DCOPClient::mainClient()->call( app, obj,
			     "doSomething(QString,float,bool)",
			     data, replyType, replyData ) ) {
	if ( replyType == "int" ) {
	    int result;
	    QDataStream reply( replyData, IO_ReadOnly );
	    reply >> result;
	    // ...
	}
    }
 </pre>

 As you might see from the code snippet, the DCOPRef has to "guess"
 the names of the datatypes of the arguments to construct a dcop
 call. This is done through global inline overloads of the
 dcopTypeName function, for example

 <pre>
	inline const char* dcopTypeName( const QString& ) { return "QString"; }
 </pre>

 If you use custom data types that do support QDataStream but have
 no corrsponding dcopTypeName overload, you can either provide such
 an overload or use a DCOPArg wrapper that allows you to specify the type.

 <pre>
	UserType userType;
	DCOPReply reply = example.call( "userFunction", DCOPArg( userType, "UserType" ) );
 </pre>

 Similar, when you retrieve such a data type, you can use an
 explicit call to DCOPReply::get():

 <pre>
	UserType userType;
	reply.get( userType, "UserType" );
 </pre>

 The function send() works very similar to call(), only that it
 returns a simple bool on whether the signal could be sent or not:

 <pre>
	if ( example.pingMe( "message" ) == false )
	   qWarning("could not ping example" );
 </pre>

 A DCOP reference operates on DCOPClient::mainClient(), unless you
 explicitely specify another client with setDCOPClient().

 @author Matthias Ettrich <ettrich@kde.org>, Torben Weis <weis@kde.org>
 
 @short *
 A DCOPRef(erence) encapsulates a remote DCOP object as a triple
 <app,obj,type> where type is optional.
*/

/** *
 Creates a null reference.
     
*/
kde_DCOPRef * kde_new_DCOPRef();

/** *
 Copy constructor.
     
*/
kde_DCOPRef * kde_new_DCOPRef1(kde_DCOPRef* ref);

/** *
  Creates a reference for application @p app and object @p obj

*/
kde_DCOPRef * kde_new_DCOPRef2(qt_QCString* app, qt_QCString* obj);

/** *
 Creates a reference to an existing dcop object

*/
kde_DCOPRef * kde_new_DCOPRef3(kde_DCOPObject* object);

/** *
  Creates a reference for application @p app and object @p obj
 with a specified type @p type.

*/
kde_DCOPRef * kde_new_DCOPRef4(qt_QCString* app, qt_QCString* obj, qt_QCString* type);

/** *
 Tests wether it is a null reference.

*/
int kde_DCOPRef_isNull(kde_DCOPRef* instPointer);

/** *
 Name of the application in which the object resides.

*/
qt_QCString* kde_DCOPRef_app(kde_DCOPRef* instPointer);

/** *
 Object ID of the referenced object.

*/
qt_QCString* kde_DCOPRef_obj(kde_DCOPRef* instPointer);

/** *
 @obsolete
     
*/
qt_QCString* kde_DCOPRef_object(kde_DCOPRef* instPointer);

/** *
 Type of the referenced object. May be null (i.e. unknown).

*/
qt_QCString* kde_DCOPRef_type(kde_DCOPRef* instPointer);

/** *
 Changes the referenced object. Resets the type to unknown (null).

*/
void kde_DCOPRef_setRef(kde_DCOPRef* instPointer,qt_QCString* app, qt_QCString* obj);

/** *
 Changes the referenced object.

*/
void kde_DCOPRef_setRef1(kde_DCOPRef* instPointer,qt_QCString* app, qt_QCString* obj, qt_QCString* type);

/** *
 Makes this a null reference.
     
*/
void kde_DCOPRef_clear(kde_DCOPRef* instPointer);

/** *
 Returns the dcop client the reference operates on. If no client
 has been set, this is the DCOPClient::mainClient().

*/
kde_DCOPClient* kde_DCOPRef_dcopClient(kde_DCOPRef* instPointer);

/** *
 Sets a specific dcop client for this reference. Otherwise
 DCOPClient::mainClient() is used.

*/
void kde_DCOPRef_setDCOPClient(kde_DCOPRef* instPointer,kde_DCOPClient* client);

/** *
 Calls the function @p fun on the object referenced by this reference. 

*/
//DCOPReply kde_DCOPRef_call(kde_DCOPRef* instPointer,qt_QCString* fun);

/** *
 Calls the function @p fun on the object referenced by this reference. 
 Unlike @ref call() this method does not expect a return value.

*/
int kde_DCOPRef_send(kde_DCOPRef* instPointer,qt_QCString* fun);

#endif
