import asynchat

class Protocol(asynchat.async_chat):
    def __init__(self, connection, multiplexer):
        asynchat.async_chat.__init__(self, connection)
        # we are doing input buffering
        self.buffer = ""
        # we have a newline-terminated protocol
        self.set_terminator("\n")
        
        (peerhost, peerport) = connection.getpeername()
        # some kind of identification
        self.source = peerhost + ":" + peerport.__str__()
        
        self.multiplexer = multiplexer
        
        self.multiplexer.connect(self)
        self.on_connect()
        self.multiplexer.castmsg(("_notice_place_enter",
                                  {"_nick" : self.source }))
    def handle_close(self):
        # called if the socket gets closed
        self.multiplexer.disconnect(self)
        self.multiplexer.castmsg(("_notice_place_leave", 
                                  {"_nick" : self.source}))
        self.close()    
    def collect_incoming_data(self, data):
        # called whenever data arrives on the socket
        self.buffer = self.buffer + data
    def getsource(self):
        # little helper
        return self.source
    def on_connect(self):
        pass
    def found_terminator(self):
        pass
    def render(self, (event, vars)):
        pass


class TelnetProtocol(Protocol):
    def on_connect(self):
        self.push("You are now known as " + self.source + "\n")
    def found_terminator(self):
        # this will do the protocol parsing
        line = self.buffer
        self.buffer = ""
        if line.startswith("/quit"):            
            self.multiplexer.disconnect(self)
            self.multiplexer.castmsg(("_notice_place_leave",
                                      {"_nick" : self.source}))
            self.close_when_done()
            return
        self.multiplexer.castmsg(("_message_public",
                                  {"_nick" : self.source,
                                   "_text" : line }))

    def render(self, (event, vars)):
        line = ""
        if event == "_message_public":
            line += vars["_nick"] + " says: " + vars["_text"]
        elif event == "_notice_place_enter":
            line += vars["_nick"] + " enters the world"
        elif event == "_notice_place_leave":
            line += vars["_nick"] + " leaves the world"
        if line:
            self.push(line + "\n")

