;;; liece-300.el --- Handler routines for 300 numeric reply.
;; Copyright (C) 1998-2000 Daiki Ueno

;; Author: Daiki Ueno <ueno@unixuser.org>
;; Created: 1998-09-28
;; Revised: 1998-11-25
;; Keywords: IRC, liece

;; This file is part of Liece.

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.


;;; Commentary:
;; 

;;; Code:

(eval-when-compile
  (require 'liece-inlines)
  (require 'liece-intl)
  (require 'liece-misc)
  (require 'liece-commands))

(eval-and-compile
  (autoload 'liece-dcc-compare-hostnames "liece-dcc"))

(defvar liece-recursing-whois nil)
(defvar liece-recursing-whowas nil)

(defun* liece-handle-300-messages (number prefix rest)
  "300 replies"
  (or (string-match "[^ ]* \\([^ ]*\\) *\\([^ ]*\\) *:\\(.*\\)" rest)
      (return-from liece-handle-300-messages))
  (let ((target1 (liece-channel-virtual (match-string 1 rest)))
	(target2 (liece-channel-virtual (match-string 2 rest)))
	(msg (match-string 3 rest)))
    (cond ((string= target1 "")
	   (liece-insert-info liece-300-buffer (concat msg "\n")))
	  ((string= target2 "")
	   (liece-insert-info liece-300-buffer
			       (format "%s (%s)\n" msg target1)))
	  (t
	   (liece-insert-info liece-300-buffer
			       (format "%s %s (%s)\n" target1 msg target2))))))

(defun liece-handle-301-message (prefix rest)
  "RPL_AWAY \"<nickname> :<away message>\"."
  (if (string-match "^[^ ]+ \\([^ ]+\\) +:\\(.*\\)" rest)
      (let ((who (match-string 1 rest)) (iswhat (match-string 2 rest)))
	(or liece-recursing-whois
	    (liece-insert-info liece-300-buffer
				(concat who " is marked as being away, "
					"but left the message:\n"
					iswhat "\n"))))))

(defun liece-handle-302-message (prefix rest)
  "RPL_USERHOST	\":[<reply>{<space><reply>}]\"."
  (while (string-match
	  "^[^ ]* :[ ]*\\([^*=]+\\)\\([*]*\\)=\\([+-]\\)\\([^ ]+\\)" rest)
    (let ((nick (match-string 1 rest)) (oper (match-string 2 rest))
	  (away (match-string 3 rest)) (who (match-string 4 rest))
	  (end (match-end 4)))
      (if (liece-nick-equal nick liece-real-nickname)
	  (setq liece-my-userhost who))
      (liece-insert-info liece-300-buffer
			  (format "Nick %s is %s [%s%s, %s%s]\n"
				  nick who
				  (if (string= oper "") "Not ") "operator"
				  (if (string= away "+") "Not ") "away"))
      (setq rest (concat " :" (substring rest end nil))))))

(defun liece-303-display-friends (nicks)
  (let ((on (filter-elements nick nicks
	      (not (string-list-member-ignore-case nick liece-friends-last))))
	(off (filter-elements nick liece-friends-last
	       (not (string-list-member-ignore-case nick nicks)))))
    (setq liece-friends-last nicks)
    (if on
      (liece-insert-info liece-300-buffer
			  (format (_ "Following people are now on: %s\n")
				  (mapconcat 'identity on " "))))
    (if off
	(liece-insert-info liece-300-buffer
			    (format (_ "Following people are now off: %s\n")
				    (mapconcat 'identity off " "))))))

(defun* liece-handle-303-message (prefix rest)
  "RPL_ISON \":[<nickname> {<space><nickname>}]\""
  (or (string-match "[^ ]+ :\\(.*\\)" rest)
      (return-from liece-handle-303-message))
  (setq rest (match-string 1 rest))
  (or (string= rest "")
      (setq rest (substring rest 0 -1)))
  (let ((nicks (split-string rest)))
    (when (and (null nicks) (null liece-friends))
      (liece-insert-info liece-300-buffer
			  (_ "No one you requested is on now.\n"))
      (return-from liece-handle-303-message))
    (dolist (nick nicks)
      (when (and (string-list-member-ignore-case
		  nick liece-current-chat-partners)
		 (get (intern nick liece-obarray) 'part))
	(liece-insert-change (liece-pick-buffer nick)
			      (format (_ "%s has come back\n") nick))
	(put (intern nick liece-obarray) 'part nil)))
    (unless liece-friends
      (liece-insert-info liece-300-buffer
			  (format (_ "Following people are on: %s\n") rest))
      (return-from liece-handle-303-message))
    (if (fboundp liece-display-friends-function)
	(funcall liece-display-friends-function nicks))))
	
(defun* liece-handle-305-message (prefix rest)
  "RPL_UNAWAY \":You are no longer marked as being away\""
  (or (string-equal liece-away-indicator "A")
      (return-from liece-handle-305-message))
  (setq liece-away-indicator "-")
  (liece-maybe-poll)
  (when (string-match "[^:]:\\(.*\\)" rest)
    (setq rest (match-string 1 rest))
    (liece-insert-info liece-300-buffer
			(format "%s (%s)\n"
				rest (funcall liece-format-time-function
					      (current-time))))))

(defun liece-handle-306-message (prefix rest)
  "RPL_NOWAWAY \":You have been marked as being away\"."
  (setq liece-away-indicator "A")
  (if (string-match "[^:]:\\(.*\\)" rest)
      (liece-insert-info liece-300-buffer
			  (format "%s (%s)\n"
				  (match-string 1 rest)
				  (funcall liece-format-time-function
					   (current-time))))))

(defun liece-handle-311-message (prefix rest)
  "RPL_WHOISUSER \"<nickname> <user> <host> * :<real name>\"."
  (and (string-match "[^ ]+ \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) :\\(.*\\)" rest)
       (not liece-recursing-whois)
       (liece-insert-info liece-300-buffer
			   (format "%s is %s (%s@%s)\n"
				   (match-string 1 rest) ; nick
				   (match-string 5 rest) ; realname
				   (match-string 2 rest) ; username
				   (match-string 3 rest) ; machine
				   ))))

(defun* liece-handle-312-message (prefix rest)
  "RPL_WHOISSERVER \"<nickname> <server> :<server info>\""
  (or (string-match "^[^ ]+ \\(\\([^ ]+\\) \\)?\\([^ ]+\\) :\\(.*\\)" rest)
      (return-from liece-handle-312-message))
  (let ((who (match-string 2 rest))
	(server (match-string 3 rest))
	(real (match-string 4 rest)))
    (if (and liece-dcc-resolve-server
	     (not (liece-dcc-compare-hostnames server (liece-server-host)))
	     (not liece-recursing-whois)
	     (not liece-recursing-whowas))
	(progn
	  (setq liece-recursing-whois t)
	  (liece-send "WHOIS %s %s" server who))
      (setq liece-recursing-whois nil)
      (liece-insert-info liece-300-buffer
			  (format "on via server %s (%s)\n" server real)))))

(defun liece-handle-313-message (prefix rest)
  "RPL_WHOISOPERATOR \"<nickname> :is an IRC operator\"."
  (if (string-match "^[^ ]+ \\([^ ]+\\) :\\(.*\\)" rest)
      (or liece-recursing-whois
	  (liece-insert-info liece-300-buffer
			      (concat (match-string 2 rest)
				      " is an IRC operator\n")))))

(defun liece-handle-316-message (prefix rest)
  "RPL_WHOISCHANOP."
  (cond ((string-match "^\\([^ ]+\\) :\\(.*\\)" rest)
	 (if (not liece-recursing-whois)
	     (liece-insert-info liece-300-buffer
				 (concat "Status: "
					 (match-string 2 rest) "\n"))))
	((string-match "^\\([^ ]+\\) \\([^ ]+\\) :\\(.*\\)" rest)
	 (if (not liece-recursing-whois)
	     (liece-insert-info liece-300-buffer
				 (concat "Status: "
					 (match-string 3 rest) "\n"))))))

(defun* liece-handle-319-message (prefix rest)
  "RPL_WHOISCHANNELS \"<nickname> :{[@|+]<channel><space>}\""
  (or (string-match "^\\([^ ]+\\) \\([^ ]+\\) :\\(.*\\)" rest)
      (return-from liece-handle-319-message))
  (let ((chnls (split-string (match-string 3 rest)))
	isonchnls flag)
    (dolist (chnl chnls)
      (if (and (or (eq ?@ (string-to-char chnl))
		   (eq ?+ (string-to-char chnl)))
	       (liece-channel-p (substring chnl 1)))
	  (progn
	    (setq flag (substring chnl 0 1)
		  chnl (substring chnl 1)))
	(setq flag ""))
      (push (concat flag (liece-channel-virtual chnl)) isonchnls))
    (if (not liece-recursing-whois)
	(liece-insert-info liece-300-buffer
			    (format (_ "Channels: %s\n")
				    (mapconcat (function identity)
					       (nreverse isonchnls) " "))))))

(defun liece-handle-314-message (prefix rest)
  "RPL_WHOWASUSER \"<nickname> <user> <host> * :<real name>\"."
  (if (string-match
       "[^ ]+ \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) :\\(.*\\)"
       rest)
      (let ((nick (match-string 1 rest)) (username (match-string 2 rest))
	    (machine (match-string 3 rest)) (chnl (match-string 4 rest))
	    (realname (match-string 5 rest)))
	(setq liece-recursing-whowas t)
	(liece-insert-info liece-300-buffer
			    (format "%s [%s] was %s (%s@%s)\n"
				    nick
				    (if (string= chnl "*") "Private" chnl)
				    realname username machine)))))

(defun liece-handle-315-message (prefix rest)
  "RPL_ENDOFWHO."
  (if (zerop liece-long-reply-count)
      (liece-insert-info liece-300-buffer
			  (concat "No matches found"
				  (if liece-who-expression
				      (concat ": " liece-who-expression)
				    "")
				  "\n")))
  (setq liece-who-expression nil)
  (liece-reset-long-reply-count))

(defun liece-handle-317-message (prefix rest)
  "RPL_WHOISIDLE \"<nickname> <integer> :seconds idle\"."
  (cond ((string-match "^[^ ]+ [^ ]+ \\([0-9]*\\) :\\(.*\\)" rest)
	 (liece-insert-info liece-300-buffer
			     (concat "Idle for "
				     (liece-convert-seconds
				      (match-string 1 rest))
				     "\n")))
	((string-match "^[^ ]+ \\([0-9]*\\) :\\(.*\\)" rest)
	 (liece-insert-info liece-300-buffer
			     (concat "Idle for "
				     (liece-convert-seconds
				      (match-string 1 rest))
				     "\n")))))

(defun liece-handle-318-message (prefix rest)
  "RPL_ENDOFWHOIS \"<nickname> :End of /WHOIS list\"."
  nil)

(defun liece-handle-321-message (prefix rest)
  "RPL_LISTSTART \"Channel :Users  Name\"."
  (liece-insert-info liece-300-buffer
		      (format "%-10s%6s  %s\n"
			      (_ "Channel") (_ "Users")  (_ "Topic"))))

(defun* liece-handle-322-message (prefix rest)
  "RPL_LIST \"<channel> <# visible> :<topic>\""
  (or (string-match "^\\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) :\\(.*\\)" rest)
      (return-from liece-handle-322-message))
  (liece-increment-long-reply-count)
  (liece-check-long-reply-count)
  (let ((chnl (match-string 2 rest))
	(users (match-string 3 rest))
	(topic (match-string 4 rest)))
    (when (or (string= liece-channel-filter (downcase chnl))
	      (string= liece-channel-filter "")
	      (and (string= liece-channel-filter "0")
		   (string= chnl "*")))
      (setq chnl (liece-channel-virtual chnl))
      (put (intern chnl liece-obarray) 'topic topic)
      (liece-insert-info (append (liece-pick-buffer chnl) liece-300-buffer)
			  (format "%-10s%6s user%s%s%s\n"
				  (if (string= chnl "*") "Priv" chnl)
				  users
				  (if (> (string-to-int users) 1) "s" "")
				  (if (string= "" topic) "" ": ")
				  topic)))))

(defun liece-handle-323-message (prefix rest)
  "RPL_LISTEND \":End of /LIST\"."
  (liece-reset-long-reply-count))

(defun liece-handle-324-message (prefix rest)
  "RPL_CHANNELMODEIS \"<channel> <mode> <mode params>\"."
  (if (string-match "[^ ]* \\([^ ]*\\) +\\+\\([^ ]*\\)\\( *[^ ]*\\)" rest)
      (let ((chnl (match-string 1 rest))
	    (mode (match-string 2 rest))
	    (param (match-string 3 rest)))
	(setq chnl (liece-channel-virtual chnl))
	(put (intern chnl liece-obarray) 'mode mode)
	(liece-insert-info (append (liece-pick-buffer chnl)
				    liece-300-buffer)
			    (format (_ "Mode for %s is %s%s\n")
				    chnl mode param))
	(liece-set-channel-indicator))))

(defun liece-handle-331-message (prefix rest)
  "RPL_NOTOPIC \"<channel> :No topic is set\"."
  (if (string-match "[^ ]* \\([^ ]*\\) \\(.*\\)" rest)
      (let ((chnl (match-string 1 rest)))
	(setq chnl (liece-channel-virtual chnl))
	(put (intern chnl liece-obarray) 'topic nil)
	(liece-insert-info (append (liece-pick-buffer chnl)
				    liece-300-buffer)
			    (_ "No topic is set\n"))
	(liece-set-channel-indicator))))

(defun liece-handle-332-message (prefix rest)
  "RPL_TOPIC \"<channel> :<topic>\"."
  (if (string-match "[^ ]* \\([^ ]*\\) +:\\(.*\\)" rest)
      (let ((chnl (liece-channel-virtual (match-string 1 rest)))
	    (topic (match-string 2 rest)))
 	(liece-channel-set-topic topic chnl)
 	(liece-insert-info (liece-pick-buffer chnl)
			    (format (_ "Topic: %s\n") topic))
	(liece-insert-info liece-300-buffer
			    (format (_ "Topic for %s: %s\n") chnl topic))
	(liece-set-channel-indicator))))

(defun liece-handle-333-message (prefix rest)
  "RPL_TOPICWHOTIME <channel> <nickname> <time>."
  (if (string-match "[^ ]* \\([^ ]*\\) +\\([^ ]*\\) +\\([^ ]*\\)" rest)
      (let ((chnl (liece-channel-virtual (match-string 1 rest)))
	    (nick (match-string 2 rest))
	    (time (funcall liece-format-time-function
			   (liece-seconds-to-time
			    (string-to-int (match-string 3 rest))))))
 	(liece-insert-info (liece-pick-buffer chnl)
			    (format (_ "Topic set by %s at %s\n")
				    nick time))
	(liece-insert-info liece-300-buffer
			    (format (_ "Topic for %s set by %s at %s\n")
				    chnl nick time))
	(liece-set-channel-indicator))))

(defun liece-handle-341-message (prefix rest)
  "RPL_INVITING \"<channel> <nickname>\"."
  (if (string-match "^\\([^ ]+\\) +\\([^ ]+\\) +\\([-#&0-9+][^ ]*\\)" rest)
      (let ((nick (match-string 2 rest))
	    (chnl (liece-channel-virtual (match-string 3 rest))))
	(liece-insert-info (liece-pick-buffer chnl)
			    (format (_ "Inviting user %s\n") nick))
	(liece-insert-info liece-300-buffer
			    (format (_ "Inviting user %s to channel %s\n")
				    nick chnl)))))

(defun liece-handle-346-message (prefix rest)
  "RPL_INVITELIST \"<channel> <inviteid>\"."
  (when (string-match "[^ ]* \\([^ ]*\\) \\([^ ]*\\)" rest)
    (let* ((regexp (match-string 2 rest))
	   (chnl (liece-channel-virtual (match-string 1 rest))))
      (liece-increment-long-reply-count)
      (liece-check-long-reply-count)
      (or (> liece-polling 0)
	  (liece-channel-add-invite regexp chnl)))))

(defun liece-handle-347-message (prefix rest)
  "RPL_ENDOFINVITELIST \"<channel> :End of Channel Invite List\"."
  (when (string-match "[^ ]* \\([^ ]*\\)" rest)
    (let* ((chnl (liece-channel-virtual (match-string 1 rest)))
	   (invites (liece-channel-get-invites chnl)))
      (liece-reset-long-reply-count)
      (liece-insert-info liece-300-buffer
			  (concat "Following users are invited to " chnl
				  ": \n"))
      (dolist (invite invites)
	(liece-insert-info liece-300-buffer
			    (concat "\t" invite "\n"))))))

(defun liece-handle-348-message (prefix rest)
  "RPL_EXCEPTLIST \"<channel> <exceptid>\"."
  (when (string-match "[^ ]* \\([^ ]*\\) \\([^ ]*\\)" rest)
    (let* ((regexp (match-string 2 rest))
	   (chnl (liece-channel-virtual (match-string 1 rest))))
      (liece-increment-long-reply-count)
      (liece-check-long-reply-count)
      (or (> liece-polling 0)
	  (liece-channel-add-exception regexp chnl)))))
  
(defun liece-handle-349-message (prefix rest)
  "RPL_ENDOFEXCEPTLIST \"<channel> :End of Channel Exception List\"."
  (when (string-match "[^ ]* \\([^ ]*\\)" rest)
    (let* ((chnl (liece-channel-virtual (match-string 1 rest)))
	   (exceptions (liece-channel-get-exceptions chnl)))
      (liece-reset-long-reply-count)
      (liece-insert-info liece-300-buffer
			  (concat "Following users are welcome to " chnl
				  ": \n"))
      (dolist (exception exceptions)
	(liece-insert-info liece-300-buffer
			    (concat "\t" exception "\n"))))))

(defun liece-handle-351-message (prefix rest)
  "RPL_VERSION \"<version>.<debuglevel> <server> :<comments>\"."
  (if (string-match "[^ ]+ \\([^ ]+\\) :*\\([^ ]+\\)[ :]*\\(.*\\)" rest)
      (liece-insert-info
       liece-300-buffer
       (format (_ "Machine %s is running IRC version %s (%s)\n")
	       (match-string 2 rest) ; machine
	       (match-string 1 rest) ; version
	       (match-string 3 rest) ; comments
	       ))))

(defun liece-handle-352-message (prefix rest)
  "RPL_WHOREPLY	\"<channel> <user> <host> <server> <nickname> <H|G>[*][@|+] :<hopcount> <real name>\"."
  (if (string-match "\\([^ ]*\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) :[0-9]* ?\\(.*\\)" rest)
      (let ((chnl (liece-channel-virtual (match-string 1 rest)))
	    (user (match-string 2 rest)) (host (match-string 3 rest))
	    (nick (match-string 5 rest)) (oper (match-string 6 rest))
	    (name (match-string 7 rest)))
	(liece-increment-long-reply-count)
	(liece-check-long-reply-count)
	(liece-nick-set-user-at-host nick (concat user "@" host))
	(liece-insert-info liece-300-buffer
			    (format "%3s %10s %9s %-29s %s\n"
				    oper (if (memq (aref chnl 0) '(?* ?0))
					     "Private" chnl)
				    nick
				    (concat "(" user "@"
					    (liece-clean-hostname host)
					    ")")
				    name)))))

(defvar liece-353-names nil)

(defmacro liece-353-scan-channels (chnl)
  `(or (string-assoc-ignore-case ,chnl liece-channel-alist)
       (push (list ,chnl) liece-channel-alist)))

(defun liece-handle-353-message (prefix rest)
  "RPL_NAMREPLY	\"<channel> :[[@|+]<nick> [[@|+]<nick> [...]]]\"."
  (when (string-match "[^ =*@]?[=*@] \\([^ ]*\\) :\\(.*\\)" rest)
    (let ((chnl (liece-channel-virtual (match-string 1 rest)))
	  (users (delete "" (split-string (match-string 2 rest)))))
      (liece-increment-long-reply-count)
      (liece-check-long-reply-count)
      (or (> liece-polling 0)
	  (setq liece-353-names
		(append (nreverse users) liece-353-names )))
      (liece-353-scan-channels chnl))))

(defun liece-handle-361-message (prefix rest)
  "RPL_KILLDONE."
  (if (string-match "[^ ]+ \\([^ ]+\\) +:\\(.*\\)" rest)
      (let ((who (match-string 1 rest))
	    (message (match-string 2 rest)))
	(liece-insert-info liece-300-buffer
			    (format (_ "You just killed %s. %s\n")
				    who message)))))

(defstruct liece-364-link from to hop info)
(defvar liece-364-links nil)

(defun liece-handle-364-message (prefix rest)
  "RPL_LINKS \"<mask> <server> :<hopcount> <server info>\"."
  (if (string-match
       "[^ ]+ \\([^ ]+\\) +\\([^ ]*\\) +:\\(\\(.*\\) +\\(.*\\)\\)" rest)
      (let ((from (match-string 1 rest)) (to (match-string 2 rest))
	    (hop (string-to-int (match-string 4 rest)))
	    (info (match-string 5 rest)) link)
	(liece-increment-long-reply-count)
	(liece-check-long-reply-count)
	(setq rest (match-string 3 rest)
	      link (make-liece-364-link
		    :from from :to to :hop hop :info info))
	(push link liece-364-links))))

(defun liece-handle-365-message (prefix rest)
  "RPL_ENDOFLINKS \"<mask> :End of /LINKS list\"."
  (liece-reset-long-reply-count)
  (dolist (link liece-364-links)
    (liece-insert-info liece-300-buffer
			(concat (liece-364-link-from link)
				" --"
				(number-to-string (liece-364-link-hop link))
				"-- "
				(liece-364-link-to link) "\n")))
  (setq liece-364-links nil))

(defun liece-handle-366-message (prefix rest)
  "RPL_ENDOFNAME \"<channel> :End of /NAMES list\"."
  (when (string-match "[^ ]* \\([^ ]*\\)" rest)
    (let ((level (- liece-polling 1))
	  (users (length liece-353-names))
	  (names (mapconcat #'identity liece-353-names " "))
	  (chnl (liece-channel-virtual (match-string 1 rest))))
      (liece-reset-long-reply-count)
      (setq liece-polling (max 0 level))
      (liece-insert-info (append (liece-pick-buffer chnl)
				  liece-300-buffer)
			  (format "%-10s%6d user%s: %s\n"
				  (if (memq chnl '(?* ?0))
				      "Private"
				    chnl)
				  users (if (= users 1) "" "s") names))
      (and liece-353-names
	   (liece-channel-member chnl liece-current-channels)
	   (liece-nick-update chnl liece-353-names))
      (setq liece-353-names nil))))

(defun liece-handle-367-message (prefix rest)
  "RPL_BANLIST \"<channel> <banid>\"."
  (when (string-match "[^ ]* \\([^ ]*\\) \\([^ ]*\\)" rest)
    (let* ((regexp (match-string 2 rest))
	   (chnl (liece-channel-virtual (match-string 1 rest))))
      (liece-increment-long-reply-count)
      (liece-check-long-reply-count)
      (or (> liece-polling 0)
	  (liece-channel-add-ban regexp chnl)))))

(defun liece-handle-368-message (prefix rest)
  "RPL_ENDOFBANLIST \"<channel> :End of channel ban list\"."
  (when (string-match "[^ ]* \\([^ ]*\\)" rest)
    (let* ((chnl (liece-channel-virtual (match-string 1 rest)))
	   (bans (liece-channel-get-bans chnl)))
      (liece-reset-long-reply-count)
      (liece-insert-info liece-300-buffer
			  (concat "Following users are banned on " chnl
				  ": \n"))
      (dolist (ban bans)
	(liece-insert-info liece-300-buffer
			    (concat "\t" ban "\n"))))))

(defun liece-handle-369-message (prefix rest)
  "RPL_ENDOFWHOWAS \"<nickname> :End of WHOWAS\"."
  (setq liece-recursing-whowas nil))

(defun liece-handle-371-message (prefix rest)
  "RPL_INFO \":<string>\"."
  (if (string-match "^\\([^ ]+\\) +:?\\(.*\\)" rest)
      (liece-insert-info liece-300-buffer
			  (concat (match-string 2 rest) "\n"))))

(defun liece-handle-372-message (prefix rest)
  "RPL_MOTD \":- <text>\"."
  (if (string-match "^\\([^ ]+\\) +:?\\(.*\\)" rest)
      (liece-insert-info liece-300-buffer
			  (concat (match-string 2 rest) "\n"))))

(defun liece-handle-381-message (prefix rest)
  "RPL_YOUREOPER \":You are now an IRC operator\"."
  (if (string-match "^\\([^ ]+\\) +:\\(.*\\)" rest)
      (liece-insert-info liece-300-buffer
			  (format "You are now an IRC operator (%s)\n"
				  (match-string 2 rest)))))

(defun liece-handle-382-message (prefix rest)
  "RPL_REHASHING \"<config file> :Rehashing\"."
  (if (string-match "^\\([^ ]+\\) +:\\(.*\\)" rest)
      (liece-insert-info liece-300-buffer
			  (concat (match-string 2 rest) " "
				  (match-string 1 rest) "\n"))))

(defun liece-handle-391-message (prefix rest)
  "RPL_TIME \"<server> :<string showing server's local time>\"."
  (if (string-match "^\\([^ ]+\\) +\\(.*\\)" rest)
      (liece-insert-info liece-300-buffer
			  (format (_ "Server time is %s\n")
				  (match-string 2 rest)))))


;;; @ register message handlers
;;;

(eval-when-compile (require 'liece-handler))

(liece-handler-define-backend "300")

(defmacro liece-register-300-handler (num)
  `(progn
     (liece-handler-define-function
      ,(number-to-string num) '(prefix rest "300")
      ',(intern (format "liece-handle-%03d-message" num)))
     (defvar ,(intern (format "liece-%03d-hook" num)) nil)
     (defvar ,(intern (format "liece-after-%03d-hook" num)) nil)))

(liece-register-300-handler 301)
(liece-register-300-handler 302)
(liece-register-300-handler 303)
(liece-register-300-handler 305)
(liece-register-300-handler 306)

(liece-register-300-handler 311)
(liece-register-300-handler 312)
(liece-register-300-handler 313)
(liece-register-300-handler 314)
(liece-register-300-handler 315)
(liece-register-300-handler 316)
(liece-register-300-handler 317)
(liece-register-300-handler 318)
(liece-register-300-handler 319)

(liece-register-300-handler 321)
(liece-register-300-handler 322)
(liece-register-300-handler 323)
(liece-register-300-handler 324)

(liece-register-300-handler 331)
(liece-register-300-handler 332)
(liece-register-300-handler 333)

(liece-register-300-handler 341)
(liece-register-300-handler 348)
(liece-register-300-handler 349)

(liece-register-300-handler 351)
(liece-register-300-handler 352)
(liece-register-300-handler 353)

(liece-register-300-handler 361)
(liece-register-300-handler 364)
(liece-register-300-handler 365)
(liece-register-300-handler 366)
(liece-register-300-handler 367)
(liece-register-300-handler 368)
(liece-register-300-handler 369)

(liece-register-300-handler 371)
(liece-register-300-handler 372)

(liece-register-300-handler 381)
(liece-register-300-handler 382)

(liece-register-300-handler 391)

(provide 'liece-300)

;;; liece-300.el ends here
