
from zope.interface import implements, Interface

from twisted.internet.protocol import Protocol

class INMEAReceiver(Interface):
    """
    An object that can receive NMEA data.
    """

    def sentenceReceived(sentence):
        """
        An NMEA sentence was received.
        """


class IPositioningProvider(Interface):
    """
    An object that can receive changes to GPS coordinates.
    """

    def positionReceived(position):
        """
        A position was received.
        """



class NMEA(Protocol):
    """
    A protocol that parses NMEA and delegates to a receiver.
    """

    def __init__(self, receiver):
        """
        Connect this NMEA protocol to a receiver.

        @param receiver: a thing that can do something useful with NMEA
            sentences.

        @type receiver: L{INMEAReceiver}
        """
        self.receiver = receiver


    def dataReceived(self, data):
        """
        Some NMEA data was received.  Turn it into some useful method calls.
        """
        sentences, self.buf = self._parseNMEA(self.buf+data)
        for sentence in sentences:
            self.receiver.sentenceReceived(sentence)



class NMEA2Positioning(object):
    """
    Convert NMEA input to positioning data.
    """

    implements(INMEAReceiver)

    def __init__(self, provider):
        """
        @param provider: The provider to tell about position data represented
            by NMEA sentences.

        @type provider: L{IPositioningProvider}
        """
        self.provider = provider


    def sentenceReceived(self, sentence):
        """
        An NMEA sentence was received.  Notify our provider of what changes, if
        any, were represented by this sentence.
        """
        handler = getattr(self, "nmea_" + sentence.type)
        handler(sentence)


    def nmea_GPGGTFPSWTF(self, sentence):
        """
        Handle some terrible thing.
        """
        self.provider.positionReceived(self._somehowDeterminePosition(sentence))


class YourApplication(object):
    """
    This class is the thing that would live outside of Twisted, that would actually do stuff.
    """

    implements(IPositioningProvider)

    def positionReceived(self, position):
        """
        A position was received.  Do something useful
        """
        # ...
