------------------------------------------------------------------------
Internet Relay Chat Protocol Library -- Constants

  $Author: igarashi $
------------------------------------------------------------------------



module IRC

  module Constants
    # module in which IRC constants are defined

    ERR_NOSUCHNICK = "401"
    ERR_NOSUCHSERVE = "402"
    ERR_NOSUCHCHANNEL = "403"
    ERR_CANNOTSENDTOCHAN = "404"
    ERR_TOOMANYCHANNELS = "405"
    ERR_WASNOSUCHNICK = "406"
    ERR_TOOMANYTARGETS = "407"
    ERR_NOORIGIN = "409"
    ERR_NORECIPIENT = "411"
    ERR_NOTEXTTOSEND = "412"
    ERR_NOTOPLEVE = "413"
    ERR_WILDTOPLEVEL = "414"
    ERR_UNKNOWNCOMMAND = "421"
    ERR_NOMOTD = "422"
    ERR_NOADMININFO = "423"
    ERR_FILEERROR = "424"
    ERR_NONICKNAMEGIVEN = "431"
    ERR_ERRONEUSNICKNAME = "432"
    ERR_NICKNAMEINUSE = "433"
    ERR_NICKCOLLISION = "436"
    ERR_USERNOTINCHANNEL = "441"
    ERR_NOTONCHANNE = "442"
    ERR_USERONCHANNEL = "443"
    ERR_NOLOGIN = "444"
    ERR_SUMMONDISABLED = "445"
    ERR_USERSDISABLED = "446"
    ERR_NOTREGISTERED = "451"
    ERR_NEEDMOREPARAM = "461"
    ERR_ALREADYREGISTRE = "462"
    ERR_NOPERMFORHOST = "463"
    ERR_PASSWDMISMATCH = "464"
    ERR_YOUREBANNEDCREEP = "465"
    ERR_KEYSET = "467"
    ERR_CHANNELISFULL = "471"
    ERR_UNKNOWNMODE = "472"
    ERR_INVITEONLYCHAN = "473"
    ERR_BANNEDFROMCHAN = "474"
    ERR_BADCHANNELKEY = "475"
    ERR_NOPRIVILEGES = "481"
    ERR_CHANOPRIVSNEEDED = "482"
    ERR_CANTKILLSERVER = "483"
    ERR_NOOPERHOST = "491"
    ERR_UMODEUNKNOWNFLAG = "501"
    ERR_USERSDONTMATCH = "502"
      # Error Replies

    RPL_NONE = "300"
    RPL_USERHOST = "302"
    RPL_ISON = "303"
    RPL_AWAY = "301"
    RPL_UNAWAY = "305"
    RPL_NOWAWAY = "306"
    RPL_WHOISUSER = "311"
    RPL_WHOISSERVER = "312"
    RPL_WHOISOPERATOR = "313"
    RPL_WHOISIDLE = "317"
    RPL_ENDOFWHOIS = "318"
    RPL_WHOISCHANNELS = "319"
    RPL_WHOWASUSER = "314"
    RPL_ENDOFWHOWAS = "369"
    RPL_LISTSTART = "321"
    RPL_LIST = "322"
    RPL_LISTEND = "323"
    RPL_CHANNELMODEIS = "324"
    RPL_NOTOPIC = "331"
    RPL_TOPIC = "332"
    RPL_INVITING = "341"
    RPL_SUMMONING = "342"
    RPL_VERSION = "351"
    RPL_WHOREPLY = "352"
    RPL_ENDOFWHO = "315"
    RPL_NAMREPLY = "353"
    RPL_ENDOFNAME = "366"
    RPL_LINKS = "364"
    RPL_ENDOFLINKS = "365"
    RPL_BANLIST = "367"
    RPL_ENDOFBANLIST = "368"
    RPL_INFO = "371"
    RPL_ENDOFINFO = "374"
    RPL_MOTDSTART = "375"
    RPL_MOTD = "372"
    RPL_ENDOFMOTD = "376"
    RPL_YOUREOPER = "381"
    RPL_REHASHING = "382"
    RPL_TIME = "391"
    RPL_USERSSTART = "392"
    RPL_USERS = "393"
    RPL_ENDOFUSERS = "394"
    RPL_NOUSERS = "395"
    RPL_TRACELINK = "200"
    RPL_TRACECONNECTING = "201"
    RPL_TRACEHANDSHAKE = "202"
    RPL_TRACEUNKNOWN = "203"
    RPL_TRACEOPERATOR = "204"
    RPL_TRACEUSER = "205"
    RPL_TRACESERVER = "206"
    RPL_TRACENEWTYPE = "208"
    RPL_TRACELOG = "261"
    RPL_STATSLINKINF = "211"
    RPL_STATSCOMMANDS = "212"
    RPL_STATSCLINE = "213"
    RPL_STATSNLINE = "214"
    RPL_STATSILINE = "215"
    RPL_STATSKLINE = "216"
    RPL_STATSYLINE = "218"
    RPL_ENDOFSTATS = "219"
    RPL_STATSLLINE = "241"
    RPL_STATSUPTIME = "242"
    RPL_STATSOLINE = "243"
    RPL_STATSHLINE = "244"
    RPL_UMODEIS = "221"
    RPL_LUSERCLIENT = "251"
    RPL_LUSEROP = "252"
    RPL_LUSERUNKNOWN = "253"
    RPL_LUSERCHANNELS = "254"
    RPL_LUSERME = "255"
    RPL_ADMINME = "256"
    RPL_ADMINLOC1 = "257"
    RPL_ADMINLOC2 = "258"
    RPL_ADMINEMAIL = "259"
      # Message Replies

    NAME_TABLE = table
      # Mapping "XXX" -> <error name>

    CMD_PASS = "PASS"
    CMD_NICK = "NICK"
    CMD_USER = "USER"
    CMD_SERVER = "SERVER"
    CMD_OPER = "OPER"
    CMD_QUIT = "QUIT"
    CMD_SQUIT = "SQUIT"
      # Connection messages

    CMD_JOIN = "JOIN"
    CMD_PART = "PART"
    CMD_MODE = "MODE"
    CMD_TOPIC = "TOPIC"
    CMD_NAMES = "NAMES"
    CMD_LIST = "LIST"
    CMD_INVITE = "INVITE"
    CMD_KICK = "KICK"
      # Channel control messages

    CMD_VERSION = "VERSION"
    CMD_STATS = "STATS"
    CMD_LINK = "LINK"
    CMD_TIME = "TIME"
    CMD_CONNECT = "CONNECT"
    CMD_TRACE = "TRACE"
    CMD_ADMIN = "ADMIN"
    CMD_INFO = "INFO"
      # Query and messages for server

    CMD_PRIVMSG = "PRIVMSG"
    CMD_NOTICE = "NOTICE"
      # Message sending

    CMD_WHO = "WHO"
    CMD_WHOIS = "WHOIS"
    CMD_WHOWAS = "WHOWAS"
      # Request for user information

    CMD_KILL = "KILL"
    CMD_PING = "PING"
    CMD_PONG = "PONG"
    CMD_ERROR = "ERROR"
      # Others

    CMD_AWAY = "AWAY"
    CMD_REHASH = "REHASH"
    CMD_RESTART = "RESTART"
    CMD_SUMMON = "SUMMON"
    CMD_USERS = "USERS"
    CMD_WALLOPS = "WALLOPS"
    CMD_USERHOST = "USERHOST"
    CMD_ISON = "ISON"
      # Optional

    CRLF = "\r\n"
      # Message separator

    DEFAULT_PORT = 6667
      # Default TCP Port

------------------------------------------------------------------------
Internet Relay Chat Protocol Library -- Main Part

  $Author: igarashi $
------------------------------------------------------------------------


require 'socket'
require 'thread'
require 'kconv'
require 'localize'
require 'irc/const'

module IRC

  class Message
    # IRC$B%W%m%H%3%k$GMQ$$$i$l$k%a%C%;!<%8$rI=8=$9$k%/%i%9(B

    include Constants
    attr_accessor(:prefix)
    attr_accessor(:command)
    attr_accessor(:params)
    attr_accessor(:trailing)
    attr_accessor(:str) # for debug

    def initialize(command, trailing=nil, prefix=nil, *params)
      # Message$B$N=i4|2=$r9T$&!#(B
      #   command:String
      #   trailing=nil:String
      #   prefix=nil:String
      #   *params:String

    def to_s 
      # $BAw?.$KE,$7$?J8;zNsI=8=$rJV$9!#(B

      # to_s$B$N:FDj5A$KHw$($?(Balias


  class << Message
    def parse(str)
      # IRC$B%a%C%;!<%8$r2r@O$7!"$=$N7k2L$r(BIRC::Message$B%*%V%8%'%/%H$H$7$FJV$9!#(B


  class User
    # $B%f!<%6$rI=$9%/%i%9(B

    attr_reader(:nick)
    attr_reader(:user)
    attr_reader(:host)
    def initialize(nick, user=nil, host=nil)
    def to_s

  class << User
    def parse(str)

  class LogMessage
    # class which represents log message

    attr_reader(:timestamp)
      # :Time the time when this object was sent

    attr_reader(:sender)
      # :Object the object which sent object

    attr_reader(:ident)
      # :String identifier for message type

    attr_reader(:message)
      # :String log message string

    def initialize(sender, ident, message)
      # initialization
      #   sender:Object the object which sent object
      #   ident:String identifier for message type
      #   message:String string as message
      #   message:Message message object

    def to_s 
      # string in standard output form


  class Connection
    # IRC$B$N@\B3$H%W%m%H%3%k$N%5%]!<%H$r$9$k%/%i%9(B

    include Constants
    def Message(command, trailing=nil, prefix=nil, *params)
      # IRC::Message::new$B$N(Balias

    def initialize(log_queue=nil)
      # Connection$B$N=i4|2=!#(B
      #   log_queue:Queue -- $B%m%0$rF~$l$k%-%e!<(B

    def connect(server, port=DEFAULT_PORT)
      # Connect to server which has hostname given by argument server.
      # If sub-class of BasicSocket is given, it will be used.
      # server$B0z?t$GM?$($i$l$?L>A0$r;}$D%5!<%P$X@\B3$9$k!#(B
      # BasicSocket$B$N%5%V%/%i%9$,M?$($i$l$l$P$=$l$r$=$N$^$^;HMQ$9$k!#(B
      #   server:String -- server name.
      #   server:BasicSocket -- socket already connected to server.
      #   port=DEFAULT_PORT:Fixnum -- TCP port number. 6667 will be used when omitted.

    def disconnect

    def send(*args)
      # IRC$B%a%C%;!<%8$rAw?.$9$k!#(B
      # send(message)
      #   message:Message $BAw?.$9$k(BIRC$B%a%C%;!<%8(B
      # send(command, trailing, prefix, *params)
      #   $BM?$($i$l$?0z?t$+$i9=@.$5$l$k(BIRC$B%a%C%;!<%8$rAw?.$9$k!#(B
      #   $B0z?t$N0UL#$K$D$$$F$O(BMessage#initialize$B$r;2>H!#(B

    def recv 
      # IRC$B%a%C%;!<%8$r<u?.$7(BMessage$B%*%V%8%'%/%H$H$7$FJV$9!#(B
      # $B$3$N%a%=%C%I$r8F$S=P$7$?%9%l%C%I$O!"%a%C%;!<%8$,Mh$k$^$G%V%m%C%/$9$k!#(B

    def sendPASS(password)
    def sendNICK(nick)
    def sendUSER(nick, username, hostname, servername, realname)
    def sendQUIT(nick, quit_message)
      # $B@\B3$K4X$9$k%a%C%;!<%8$NAw?.(B

    def sendPING(nick, servers)
    def sendPONG(nick, daemon)
      # PING/PONG$B%a%C%;!<%8$NAw?.(B

