     [ <inet> latin1 <client> ] irc-client boa ;
 
 TUPLE: irc-listener in-messages out-messages ;
-: <irc-listener> ( -- irc-listener )
-    <mailbox> <mailbox> irc-listener boa ;
+TUPLE: irc-server-listener < irc-listener ;
+TUPLE: irc-channel-listener < irc-listener name password timeout ;
+TUPLE: irc-nick-listener < irc-listener name ;
+UNION: irc-named-listener irc-nick-listener irc-channel-listener ;
+
+: <irc-listener> ( -- irc-listener ) <mailbox> <mailbox> irc-listener boa ;
+
+: <irc-server-listener> ( -- irc-server-listener )
+     <mailbox> <mailbox> irc-server-listener boa ;
+
+: <irc-channel-listener> ( name -- irc-channel-listener )
+     <mailbox> <mailbox> rot f 60 seconds irc-channel-listener boa ;
+
+: <irc-nick-listener> ( name -- irc-nick-listener )
+     <mailbox> <mailbox> rot irc-nick-listener boa ;
 
 ! ======================================
 ! Message objects
 ! ======================================
 
-SINGLETON: irc-end ! Message used when the client isn't running anymore
+SINGLETON: irc-end  ! Message sent when the client isn't running anymore
+SINGLETON: irc-lost ! Message sent when connection was lost
+SINGLETON: irc-restore ! Message sent when connection was restored
+UNION: irc-broadcasted-message irc-end irc-lost irc-restore ;
 
 TUPLE: irc-message line prefix command parameters trailing timestamp ;
 TUPLE: logged-in < irc-message name ;

M: join handle-incoming-irc ( join -- )
    irc-client> join-messages>> mailbox-put ;

M: irc-end handle-incoming-irc ( irc-end -- )
    irc-client> listeners>> values [ in-messages>> mailbox-put ] with each ;

! ======================================
! Client message handling

        spawn-irc
    ] with-variable ;

GENERIC: add-listener ( irc-client irc-listener -- )
M: irc-listener add-listener ( irc-client irc-listener -- )
    current-irc-client swap [ (add-listener) ] curry with-variable ;
