# -*- coding: utf-8 -*-

# Copyright (c) 2000 Phil Thompson <phil@river-bank.demon.co.uk>
# Copyright (c) 2002 - 2006 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing an asynchronous interface for the debugger.
"""

from qt import SIGNAL, QObject, QSocketNotifier

from AsyncFile import AsyncPendingWrite
from AsyncIOBase import AsyncIOBase


class AsyncIO(AsyncIOBase, QObject):
    """
    Class implementing asynchronous reading and writing.
    
    It implements asynchronous reading and writing using the Qt event
    loop.  
    """
    def __init__(self,parent=None):
        """
        Constructor
        
        @param parent the optional parent of this object (QObject)
        """
        QObject.__init__(self,parent)
        AsyncIOBase.__init__(self)

    def disconnect(self):
        """
        Public method to disconnect any current connection.
        """
        AsyncIOBase.disconnect(self)
        self.readsn = None
        self.writesn = None

    def setNotifiers(self):
        """
        Public method to set up the socket notifiers for the Qt event loop.
        """
        self.readsn = QSocketNotifier(self.readfd.fileno(),QSocketNotifier.Read)
        self.readsn.connect(self.readsn,SIGNAL('activated(int)'),self.readReady)

        self.writesn = QSocketNotifier(self.writefd.fileno(),QSocketNotifier.Write)
        self.writesn.connect(self.writesn,SIGNAL('activated(int)'),self.writeReady)
        self.setWriteNotifier()

    def writeReady(self,fd):
        """
        Protected method called when we are ready to write data.
        
        @param fd file descriptor of the file that has data to be written (int)
        """
        AsyncIOBase.writeReady(self, fd)
        
        if self.writesn is not None:
            self.setWriteNotifier()

    def setWriteNotifier(self):
        """
        Private method called to disable the write notifier.

        If there is no data to be written, the write notifier
        will be diabled.
        """
        if not AsyncPendingWrite(self.writefd):
            self.writesn.setEnabled(0)

    def write(self,s):
        """
        Public method to write a string.
        
        @param s the data to be written (string)
        """
        # Make sure any write notifier is enabled.
        if self.writesn is not None:
            self.writesn.setEnabled(1)

        AsyncIOBase.write(self, s)
