import pcop

def registeredApplications():
        """Return a list of current DCOP registered applications."""
        return pcop.app_list()

def apps():
        """Return a list of current DCOP registered applications."""
        return pcop.app_list()

def anyAppCalled(appName):
        """Return any application instance called appName, or None if none currently registered."""
        for app in apps():
                if appName==app or appName+'-'==app[:len(appName)+1]:
                        return DCOPApplication(app)
        return None

def registerAs(appid, addpid=1):
        """Register the application with DCOP and return the ID. This is needed in order to receive DCOP requests."""
        return pcop.register_as(appid,addpid)

def processEvents():
        """Process any waiting QT events, then return."""
        pcop.process_events()

def connectDCOPSignal(sender,senderObj,signal,receiverObj,slot,vol=1):
        """Connect a dcop signal"""
        return pcop.connect_dcop_signal(sender,senderObj,signal,receiverObj,slot,vol)

def disconnectDCOPSignal(sender,senderObj,signal,receiverObj,slot):
        """Connect a dcop signal"""
        return pcop.disconnect_dcop_signal(sender,senderObj,signal,receiverObj,slot)

class DCOPApplication(object):
        def __init__( self, name ):
                self.name = name

        def __getattr__( self, item ):
                if item == "__repr__":
                        return object.__repr__
                if item == "__str__":
                        return object.__str__
                if item == "__call__":
                        return object.__call__
                if item == "_objects_":
                        return pcop.obj_list(self.name)
                return DCOPObject( self.name, item )

        def _object_(self, object):
                return DCOPObject( self.name, object )

class DCOPObject(object):
        def __init__( self, appname, name ):
                self.appname = appname
                self.name = name

        def __repr__( self ):
                return "DCOPObject(%s,%s)" % ( self.appname, self.name )

        def __str__( self ):
                return "DCOPObject(%s,%s)" % ( self.appname, self.name )

        def __getattr__( self, item ):
                if item == "__repr__":
                        return object.__repr__
                if item == "__str__":
                        return object.__str__
                if item == "__call__":
                        return object.__call__
                if item == "_methods_":
                        return pcop.method_list( self.appname, self.name )
                return DCOPMethod( self.appname, self.name, item )

        def _method_(self, method):
                return DCOPMethod( self.appname, self.name, method )

class DCOPMethod(object):
        def __init__( self, appname, objname, name ):
                self.appname = appname
                self.objname = objname
                self.name = name

        def __repr__( self ):
                return "DCOPMethod(%s,%s,%s)" % ( self.appname, self.objname, self.name )

        def __str__( self ):
                return "DCOPMethod(%s,%s,%s)" % ( self.appname, self.objname, self.name )

        def __call__( self, *args ):
                return pcop.dcop_call( self.appname, self.objname, self.name, args )

class DCOPServer(object):
        def __init__( self, appid, addpid = 1):
                self.app_id = pcop.register_as(appid, addpid)


class DCOPServerObject:
        """Inherit from this class to DCOP enabled your object.

        Remember to call the base class constructor, and in your own constructor
        you should called setMethods to set the methods to DCOP enable.
        """

        def __init__(self, objName=None):
                """objName is the name of the object. If omitted, it will default to a hex
                address. It is best to supply it."""
                if objName:
                        self.dcop_obj = pcop.create_dcop_object(self, objName)
                else:
                        self.dcop_obj = pcop.create_dcop_object(self)

        def setMethods(self, methods):
                """Set the method list for this object.

                methods is a list of tuple pairs. Each pair consists of the
                method signature and the Python method that handles it.

                For example, setMethods([ ('TQString cheeseType()', self.cheese_type),
                ('void setGreatWines(bool perthPink, bool hobartMuddy, bool chateauChunder)')
                """
                pcop.set_method_list(self.dcop_obj, methods)

