;; see file irchat-copyright.el for change log and copyright info
;; irchat.el splitted by kmk@tut.fi Sun Oct 14 18:58:10 EET 1990

(provide 'irchat-commands)

(defun irchat-Command-describe-briefly ()
  (message (substitute-command-keys "Type \\[describe-mode] for help")))

(defun irchat-Command-redisplay (&optional center)
  "Un-freezes and re-selects the Dialogue buffer in another window.
   With argument, recenter with that argument."
  (interactive "P")
  (setq irchat-freeze nil)
  (setq irchat-freeze-indicator "-")
  (if (get-buffer-window irchat-Dialogue-buffer)
     nil
    (if (one-window-p)
	(irchat-configure-windows)
      (display-buffer irchat-Dialogue-buffer)))
  (set-buffer irchat-Dialogue-buffer)
  (set-window-point (get-buffer-window irchat-Dialogue-buffer) (point-max)))

(defun irchat-Command-send-message (message)
  (if irchat-chat-partner
      (progn
	(irchat-send "PRIVMSG %s :%s" irchat-chat-partner message)
	(irchat-own-message (format (format "%s %%s"
					    irchat-format-string)
				    irchat-chat-partner message)))
    (if (not irchat-current-channel)
	(progn
	  (beep t)
	  (message (substitute-command-keys "Type \\[irchat-Command-join] to join a channel")))
      (irchat-send "PRIVMSG %s :%s" irchat-current-channel message)
      (irchat-own-message (concat "> " message)))))

(defun irchat-Command-enter-message ()
  "Enter the current line as an entry in the IRC dialogue on the
current channel."
  (interactive)
  (let (message start stop)
    (beginning-of-line)
    (setq start (point))
    (end-of-line)
    (setq stop (point))
    (setq message (concat (buffer-substring start stop) irchat-nam-suffix))
    (next-line 1)
    (irchat-Command-send-message message)))

(defun irchat-Dialogue-enter-message ()
  "Ask for a line as an entry in the IRC dialogue on the current channel."
  (interactive)
  (let ((message "x"))
    (while (not (string= message ""))
      (setq message (read-string "> "))
      (if (not (string= message ""))
	  (irchat-Command-send-message message)))))

(defun irchat-Command-debug ()
  "Start debugging irchat."
  (interactive)
  (if irchat-debug-buffer
      (progn
	(setq irchat-debug-buffer nil)
	(other-window 1)
	(delete-window)
	(other-window -1))
    (if irchat-use-full-window
	(delete-other-windows))
    (irchat-configure-windows)
    (split-window-horizontally)
    (other-window 1)
    (setq irchat-debug-buffer (get-buffer-create "*IRC Debugging*"))
    (switch-to-buffer irchat-debug-buffer)
    (other-window -1)))

(defun irchat-Command-inline ()
  "Send current line as a message to the IRC server."
  (interactive)
  (let (message start stop)
    (beginning-of-line)
    (setq start (point))
    (end-of-line)
    (setq stop (point))
    (setq message (buffer-substring start stop))
    (newline)
    (irchat-send message)))

(defun irchat-Command-join (join-channel-var)
  "Join a channel."
  (interactive (let (join-channel-var (completion-ignore-case t))
		 (setq join-channel-var 
		       (completing-read
			"Join channel: "
			(append irchat-channel-alist
				irchat-nick-alist)
			'(lambda (s) t) nil irchat-invited-channel))
		 (list join-channel-var)))
  (let ((nicks irchat-nick-alist)
	(found nil))
    (while (and 
	    (not found)
	    nicks)
      (if (and (car (car nicks))	; there can to be a nil in the list
	       (string= (upcase join-channel-var)
			(upcase (car (car nicks)))))
	  (setq join-channel-var (car (get (intern (car (car nicks))) 'chnl))
		found t))
      (setq nicks (cdr nicks))))
  (let ((found nil))
    (mapcar 
     '(lambda (elem)
	(if (string= (upcase join-channel-var)
		     (upcase (format "%s" elem)))
	    (setq irchat-current-channel (format "%s" elem)
		  found t)))
     irchat-current-channels)
    (setq irchat-channel-indicator
	  (if irchat-current-channel
	      (format "Channel %s" irchat-current-channel)
	    "No channel"))
    (setq irchat-invited-channel nil)
    (or found
	(irchat-send "JOIN %s" join-channel-var))))

(defun irchat-Command-part (part-channel-var)
  "Part a channel."
  (interactive (let (part-channel-var (completion-ignore-case t))
		 (setq part-channel-var 
		       (completing-read	
			"Part channel: "
			irchat-channel-alist
			'(lambda (s) t) nil irchat-current-channel))
		 (list part-channel-var)))
  (if (memq (intern part-channel-var) irchat-current-channels)
      (setq irchat-current-channel part-channel-var)) ; just refocusing
  (irchat-send "PART %s" part-channel-var))

(defun irchat-Command-kill (kill-nickname-var)
  "Ignore messages from this user.  If already ignoring him/her, toggle."
  (interactive (let (kill-nickname-var (completion-ignore-case t))
		 (setq kill-nickname-var 
		       (completing-read 
			"Ignore nickname: " 
			irchat-nick-alist
			'(lambda (s) t) nil nil))
		 (list kill-nickname-var)))
  (if (string= "" kill-nickname-var)
      (let ((buf (current-buffer)))
	(set-buffer irchat-Dialogue-buffer)
	(setq buffer-read-only nil)
	(goto-char (point-max))
	(insert "*** Currently ignored people:")
	(let ((mylist irchat-kill-nickname))
	  (while mylist
	    (insert (format " %s" (car mylist)))
	    (setq mylist (cdr mylist))))
	(newline)
	(setq buffer-read-only t)
	(set-buffer buf)))
  (if (memq (intern kill-nickname-var) irchat-kill-nickname)
      (setq irchat-kill-nickname 
	    (delq (intern kill-nickname-var) irchat-kill-nickname))
    (setq irchat-kill-nickname 
	  (cons (intern kill-nickname-var) irchat-kill-nickname))))

(defun irchat-Command-kick (kick-nickname-var)
  "Kick this user out."
  (interactive (let (kick-nickname-var (completion-ignore-case t))
		 (setq kick-nickname-var 
		       (completing-read 
			"Kick out nickname: " 
			irchat-nick-alist
			'(lambda (s) t) nil nil))
		 (list kick-nickname-var)))
  (irchat-send "KICK %s %s" irchat-current-channel kick-nickname-var))

(defun irchat-Command-list (&optional channel)
  "List the channels and their topics, or if numeric ARG, topic of current
   channel. If you enter only Control-U as argument, list the current channel."
  (interactive "P")
  (if (not channel)
      (irchat-send "LIST")
    (irchat-send "LIST %s" (if (listp current-prefix-arg)
			       irchat-current-channel
			     (int-to-string channel)))))

(defun irchat-Command-lusers ()
  "List the number of users and servers"
  (interactive)
  (irchat-send "LUSERS"))

(defun irchat-Command-modec (change)
  "Send a MODE command"
  (interactive "sMode for this channel: ")
  (irchat-send "MODE %s %s"
	       irchat-current-channel
	       change))

(defun irchat-Command-message (message-nick-var message)
  "Send a private message to another user."
  (interactive (let (message-nick-var (completion-ignore-case t))
		 (setq message-nick-var 
		       (completing-read 
			"Private message to: "
			(append irchat-nick-alist irchat-channel-alist)
			'(lambda (s) t) nil irchat-privmsg-partner))
		 (list message-nick-var 
		       (read-string 
			(format "Private message to %s: " message-nick-var)))))
  (setq irchat-privmsg-partner message-nick-var)
  (irchat-send "PRIVMSG %s :%s" message-nick-var message)
  (irchat-own-message 
   (format (format "%s %%s" irchat-format-string) message-nick-var message)))

;; Added at mta@tut.fi's request...

(defun irchat-Command-mta-private ()
  "Send a private message (current line) to another user."
  (interactive)
  (let ((completion-ignore-case t) message start stop)
    (setq irchat-privmsg-partner
	  (completing-read 
	   "To whom: "
	   (append irchat-nick-alist irchat-channel-alist)
	   '(lambda (s) t) 
	   nil irchat-privmsg-partner))
    (beginning-of-line)
    (setq start (point))
    (end-of-line)
    (setq stop (point))
;; we dont clean stings anymore, right?
;; mta Tue Jan 22 00:21:26 EET 1991
;    (setq message (irchat-clean-string
;		   (buffer-substring start stop)))
    (setq message (buffer-substring start stop))
    (next-line 1)
    (irchat-send "PRIVMSG %s :%s" irchat-privmsg-partner message)
    (irchat-own-message (format (format "%s %%s" irchat-format-string) 
				irchat-privmsg-partner message))))

(defun irchat-Command-private-conversation (nick)
  "Enter private conversation mode.  Each line you type in the Command
buffer gets sent to your partner only."
  (interactive (let (nick (completion-ignore-case t))
		 (setq nick (completing-read 
			     "With whom do you wish to chat privately: " 
			     irchat-nick-alist
			     '(lambda (s) t) nil irchat-privmsg-partner))
		 (list nick)))
  (if (string= nick "")
      (progn
	(message "No longer in private conversation mode")
	(setq irchat-chat-partner nil)
	(setq irchat-private-indicator ""))
    (setq irchat-chat-partner nick)
    (setq irchat-private-indicator (format "(Chatting with %s) " nick))))

(defun irchat-Command-names (&optional channel)
  "List the nicknames of the current IRC users per channel.
With an Control-U as argument, only the current channel is listed."
  (interactive "P")
  (if (eq channel '-)
      (irchat-send 
       (concat "NAMES :" 
	       (let ((completion-ignore-case t))
		 (completing-read 
		  "NAMES " 
		  irchat-channel-alist
		  '(lambda (s) t) nil nil))))
    (if (not channel)
	(irchat-send "NAMES")
      (irchat-send "NAMES %s" (if (listp current-prefix-arg)
				  irchat-current-channel
				(int-to-string channel))))))

(defun irchat-Command-nickname (nick)
  "Set your nickname."
  (interactive "sEnter your nickname: ")
  (setq irchat-old-nickname irchat-nickname)
  (setq irchat-nickname nick)
  (irchat-send "NICK %s" nick))

(defun irchat-Command-who (&optional channel)
  "List the users currently on each channel, or if numeric ARG, on that channel.
If you enter only Control-U as argument, list the current channel. With - as
argument, read channel completing."
  (interactive "P")
  (if (eq channel '-)
      (irchat-send 
       (concat "WHO :" 
	       (let ((completion-ignore-case t))
		 (completing-read 
		  "WHO " 
		  irchat-channel-alist
		  '(lambda (s) t) nil nil))))
    (if (not channel)
	(irchat-send "WHO")
      (irchat-send "WHO %s" (if (listp current-prefix-arg)
				irchat-current-channel
			      (int-to-string channel))))))

(defun irchat-Command-wait (nick &optional greeting)
  "Wait for NICK to enter IRC.  When this person appears, you will
be informed.
If the optional argument GREETING is non-nil, it should be a string to send
NICK upon entering."
  (interactive (progn (setq nick (read-string "Wait for: "))
		      (setq greeting (read-string (format "Message to send %s upon entering: " nick)))
		      (if (string= greeting "")
			  (setq greeting nil))
		      (list nick greeting)))
  (put (intern nick) 'irchat-waited-for t)
  (if greeting (put (intern nick) 'irchat-greeting greeting)))

(defun irchat-Command-finger (finger-nick-var)
  "Get information about a specific user."
  (interactive (let (finger-nick-var (completion-ignore-case t))
		 (setq finger-nick-var 
		       (completing-read 
			"Finger whom: " irchat-nick-alist
			'(lambda (s) t) nil nil))
		 (list finger-nick-var)))
  (irchat-send "WHOIS %s" finger-nick-var))

;; Added by nam

(defun irchat-Command-topic (topic)
  "Change topic of channel."
  (interactive "sTopic: ")
  (irchat-send "TOPIC :%s" topic))

;;;
;;; From Masahiko MURAKAMI <murakami@nagao5.kuee.kyoto-u.ac.jp>
;;; now lets you to invite to other than your primary channel
;;;
(defun irchat-Command-invite (&optional invite-channel-var)
  "Invite user to channel."
  (interactive "P")
  (if (not invite-channel-var)
      (let ((completion-ignore-case t))
        (setq invite-channel-var 
	      (completing-read 
	       "Invite channel: "
	       (mapcar '(lambda (x)
			  (list (format "%s" x)))
		       irchat-current-channels )
	       '(lambda (s) t) nil nil)))
    (setq invite-channel-var irchat-current-channel))
  (let ((invite-nick-var nil)
        (completion-ignore-case t))
    (setq invite-nick-var (completing-read "Invite whom: " 
					   irchat-nick-alist
					   '(lambda (s) t) nil nil))
    (list invite-nick-var)
    (irchat-send "INVITE %s %s" invite-nick-var invite-channel-var)))

(defun irchat-Command-away (awaymsg)
  "Mark/unmark yourself as being away."
  (interactive "sAway message: ")
  (irchat-send "AWAY %s" awaymsg))

(defun irchat-Command-scroll-down ()
  "Scroll Dialogue-buffer down from Command-buffer."
  (interactive)
  (pop-to-buffer irchat-Dialogue-buffer)
  (if (pos-visible-in-window-p (point-min))
      (message "Beginning of buffer")
    (scroll-down))
  (pop-to-buffer irchat-Command-buffer))

(defun irchat-Command-scroll-up ()
  "Scroll Dialogue-buffer up from Command-buffer."
  (interactive)
  (pop-to-buffer irchat-Dialogue-buffer)
  (if (pos-visible-in-window-p (point-max))
      (progn
	(goto-char (point-max))
	(recenter 1))
    (scroll-up))
  (pop-to-buffer irchat-Command-buffer))

(defun irchat-Command-freeze ()
  "Toggle the automatic scrolling of the Dialogue window."
  (interactive)
  (if irchat-freeze
      (setq irchat-freeze-indicator "-")
    (setq irchat-freeze-indicator "F"))
  (switch-to-buffer (current-buffer))
  (setq irchat-freeze (not irchat-freeze)))

(defun irchat-Command-quit ()
  "Quit IRCHAT."
  (interactive)
  (if (or (not (irchat-server-opened))
	  (y-or-n-p "Quit IRCHAT? "))
      (progn
	(message "")
	(if (get-buffer-process irchat-server-buffer)
	    (irchat-send "QUIT"))
	(irchat-clear-system)
	(if irchat-use-full-window
	    (delete-other-windows))
	(irchat-close-server)
	(run-hooks 'irchat-Exit-hook)
	(setq irchat-polling 'start)
	(setq irchat-current-channel nil)
	(setq irchat-current-channels nil))))

(defun irchat-Command-generic (message)
  "Enter a generic IRC message, which is sent to the server.
 A ? lists the useful generic messages."
  (interactive "sIRC Command: ")
  (if (string= message "?")
      (with-output-to-temp-buffer "*IRC Help*"
	(princ "The following generic IRC messages may be of interest to you:
TOPIC <new topic>		set the topic of your channel
INVITE <nickname>		invite another user to join your channel
LINKS				lists the currently reachable IRC servers
SUMMON <user@host>		invites an user not currently in IRC
USERS <host>			lists the users on a host
AWAY <reason>			marks you as not really actively using IRC
				(an empty reason clears it)
WALL <message>			send to everyone on IRC
NAMES <channel>			lists users per channel
")
	(message (substitute-command-keys "Type \\[irchat-Command-redisplay] to continue")))
  (irchat-send "%s" message)))

(defun irchat-Command-irc-compatible ()
  "If entered at column 0, allows you to enter a generic IRC message to
be sent to the server.  For a list of messages, see irchat-Command-generic."
  (interactive)
  (if (eq (current-column) 0)
      (call-interactively (function irchat-Command-generic))
    (self-insert-command 1)))

;;
;; mta Thu Jan 24 17:36:03 EET 1991
;;

(defun irchat-Command-exec (command)
  "Execute command, stdout to dialogue."
  (interactive "sShell Command: ")
  (shell-command command t)
  (let ((opoint (point)))
    (while (< (point) (mark))
      (progn
	(irchat-Command-enter-message)
	(set-buffer irchat-Command-buffer)
	))
    (push-mark opoint t)))


;;
;; client-to-client queries
;;
(defun irchat-Command-client-version (client-version-nick-var)
  "Ask about someones client version."
  (interactive (let (client-version-nick-var (completion-ignore-case t))
		 (setq client-version-nick-var 
		       (completing-read 
			"Whose client: " irchat-nick-alist
			'(lambda (s) t) nil irchat-query-client-nick))
		 (list client-version-nick-var)))
  (setq irchat-query-client-nick client-version-nick-var)
  (irchat-send "privmsg %s :%s" 
	       client-version-nick-var irchat-query-client-version))

(defun irchat-Command-client-userinfo (client-userinfo-nick-var)
  "Ask about someones client userinfo."
  (interactive (let (client-userinfo-nick-var (completion-ignore-case t))
		 (setq client-userinfo-nick-var 
		       (completing-read 
			"Whose client: " irchat-nick-alist
			'(lambda (s) t) nil irchat-query-client-nick))
		 (list client-userinfo-nick-var)))
  (setq irchat-query-client-nick client-userinfo-nick-var)
  (irchat-send "privmsg %s :%s"
	       client-userinfo-nick-var irchat-query-client-userinfo))

(defun irchat-Command-client-help (client-help-nick-var)
  "Ask about someones client help."
  (interactive (let (client-help-nick-var (completion-ignore-case t))
		 (setq client-help-nick-var 
		       (completing-read 
			"Whose client: " irchat-nick-alist
			'(lambda (s) t) nil irchat-query-client-nick))
		 (list client-help-nick-var)))
  (setq irchat-query-client-nick client-help-nick-var)
  (irchat-send "privmsg %s :%s" 
	       client-help-nick-var irchat-query-client-help))

(defun irchat-Command-client-clientinfo (client-clientinfo-nick-var)
  "Ask about someones client clientinfo."
  (interactive (let (client-clientinfo-nick-var (completion-ignore-case t))
		 (setq client-clientinfo-nick-var 
		       (completing-read 
			"Whose client: " irchat-nick-alist
			'(lambda (s) t) nil irchat-query-client-nick))
		 (list client-clientinfo-nick-var)))
  (setq irchat-query-client-nick client-clientinfo-nick-var)
  (irchat-send "privmsg %s :%s" 
	       client-clientinfo-nick-var irchat-query-client-clientinfo))

(defun irchat-Command-client-generic (client-generic-nick-var)
  "Ask about someones client clientinfo."
  (interactive (let (client-generic-nick-var (completion-ignore-case t))
		 (setq client-generic-nick-var 
		       (completing-read 
			"Whose client: " irchat-nick-alist
			'(lambda (s) t) nil irchat-query-client-nick))
		 (list client-generic-nick-var)))
  (setq irchat-query-client-nick client-generic-nick-var)
  (setq irchat-query-client-lastcommand
	(completing-read "What info: " irchat-query-client-alist
			 '(lambda (s) t) nil irchat-query-client-lastcommand))
  (irchat-send "privmsg %s :%s%s"
	       client-generic-nick-var
	       irchat-query-client-lastcommand
	       irchat-query-client-insert-to-generic))

(defun irchat-Command-client-userinfo-from-minibuffer ()
  "Ask about someones client clientinfo."
  (interactive)
  (setq irchat-client-userinfo
	(read-from-minibuffer "New userinfo: "
			      irchat-client-userinfo)))

(defun irchat-Command-client-userinfo-from-commandbuffer ()
  "Ask about someones client clientinfo."
  (interactive)
  (beginning-of-line)
  (setq start (point))
  (end-of-line)
  (setq stop (point))
  (setq irchat-client-userinfo (buffer-substring start stop))
  (next-line 1))

;;
;; sending files (any files actually)
;;
(defun irchat-Command-send-file (name to-who)
  "Send a file to given  user"
  (interactive "fFile name: \nsTo who: ")
  (save-excursion 
    (set-buffer (get-buffer-create (format "*IRC S_FILE_%s*" name)))
    (delete-region (point-min) (point-max))
    (insert-file name)
    (let (str)
      (setq str (buffer-string))
      (delete-region (point-min) (point-max))
      (insert (irchat-quote-encode str)))
    (goto-char (point-min))
    (irchat-send "NOTICE %s :FILE START %s :%s" to-who name
		 (buffer-substring (point)
				   (min (point-max)
					(+ 80 (point)))))
    (goto-char (min (point-max) 
		    (+ 80 (point))))
    (while (< (point) (point-max))
      (progn
	(if (=  1 (mod (point) 800))
	    (sleep-for 1))
	(irchat-send "NOTICE %s :FILE CONT %s :%s" to-who name
		     (buffer-substring (point)
				       (min (point-max)
					    (+ 80 (point)))))
	(goto-char (min (point-max) 
			(+ 80 (point))))))
    (irchat-send "NOTICE %s :FILE END %s : " to-who name)
    (kill-buffer (get-buffer-create (format "*IRC S_FILE_%s*" name)))
    ))


;;
;; send all text in kill-buffer
;;

(defun irchat-Command-yank-send (&optional howmany)
  (interactive)
  (let ((beg (point)) end)
    (insert (car kill-ring-yank-pointer))
    (setq end (point))
    (goto-char beg)
    (while (< (point) end)
      (progn
	(irchat-Command-enter-message)
	(set-buffer irchat-Command-buffer)
	))
    ))

;;
;; send rot-13 encrypted data
;;

;;; caesar-region written by phr@prep.ai.mit.edu  Nov 86
;;; modified by tower@prep Nov 86
;;; Modified by umerin@flab.flab.Fujitsu.JUNET for ROT47.

(defun gnus-caesar-region (&optional n)
  "Caesar rotation of region by N, default 13, for decrypting netnews.
ROT47 will be performed for Japanese text in any case."
  (interactive (if current-prefix-arg	; Was there a prefix arg?
		   (list (prefix-numeric-value current-prefix-arg))
		 (list nil)))
  (cond ((not (numberp n)) (setq n 13))
	((< n 0) (setq n (- 26 (% (- n) 26))))
	(t (setq n (% n 26))))		;canonicalize N
  (if (not (zerop n))		; no action needed for a rot of 0
      (progn
	(if (or (not (boundp 'caesar-translate-table))
		(/= (aref caesar-translate-table ?a) (+ ?a n)))
	    (let ((i 0) (lower "abcdefghijklmnopqrstuvwxyz") upper)
	      (message "Building caesar-translate-table...")
	      (setq caesar-translate-table (make-vector 256 0))
	      (while (< i 256)
		(aset caesar-translate-table i i)
		(setq i (1+ i)))
	      (setq lower (concat lower lower) upper (upcase lower) i 0)
	      (while (< i 26)
		(aset caesar-translate-table (+ ?a i) (aref lower (+ i n)))
		(aset caesar-translate-table (+ ?A i) (aref upper (+ i n)))
		(setq i (1+ i)))
	      ;; ROT47 for Japanese text.
	      ;; Thanks to ichikawa@flab.fujitsu.junet.
	      (setq i 161)
	      (let ((t1 (logior ?O 128))
		    (t2 (logior ?! 128))
		    (t3 (logior ?~ 128)))
		(while (< i 256)
		  (aset caesar-translate-table i
			(let ((v (aref caesar-translate-table i)))
			  (if (<= v t1) (if (< v t2) v (+ v 47))
			    (if (<= v t3) (- v 47) v))))
		  (setq i (1+ i))))
	      (message "Building caesar-translate-table... done")))
	(let ((from (region-beginning))
	      (to (region-end))
	      (i 0) str len)
	  (setq str (buffer-substring from to))
	  (setq len (length str))
	  (while (< i len)
	    (aset str i (aref caesar-translate-table (aref str i)))
	    (setq i (1+ i)))
	  (goto-char from)
	  (delete-region from to)
	  (insert str)))))

(defun irchat-Command-caesar-line (&optional n)
  "*Rotate current line."
  (interactive)
  (beginning-of-line nil)
  (push-mark (point))
  (end-of-line)
  (gnus-caesar-region n))

;;;
;;;
;;;

(defun get-word-left ()
  "Return word left from point."
  (save-excursion
    (let (point-now)
      (setq point-now (point))
      (backward-word 1)
      (buffer-substring (point) point-now))))

(defun irchat-Command-complete ()
  "Complete word before point from userlist."
  (interactive)
  (insert
   (save-excursion
     (let ((completion-ignore-case t) point-now word result)
       (setq point-now (point))
       (setq word (get-word-left))
       (setq result (try-completion word irchat-nick-alist))
       (backward-word 1)
       (delete-region (point) point-now)
       (if (or (eq result t) (eq result nil))
           word
         result)))))

(defun irchat-Command-load-vars ()
  "Load configuration from irchat-variables-file."
  (interactive)
  (let ((file (expand-file-name irchat-variables-file)))
    (if (file-exists-p file)
	(progn
	  (load-file file)
	  (irchat-Command-reconfigure-windows)))))

(defun irchat-Command-reconfigure-windows ()
  (interactive)
  (let ((command-window (get-buffer-window irchat-Command-buffer))
	(dialogue-window (get-buffer-window irchat-Dialogue-buffer))
	(old-buffer (current-buffer)))
    (if (and command-window dialogue-window)
	(let ((c-height (window-height command-window))
	      (d-height (window-height dialogue-window)))
	  (delete-window command-window)
	  (pop-to-buffer irchat-Dialogue-buffer)
	  (enlarge-window (+ c-height d-height
			     (- (window-height dialogue-window)))))
      (pop-to-buffer irchat-Dialogue-buffer))
    (irchat-configure-windows)
    (if irchat-one-buffer-mode
	(pop-to-buffer irchat-Dialogue-buffer)
      (pop-to-buffer old-buffer))))

;;;
;;; command to get end of the Dialogue buffer
;;;
(defun irchat-Command-eod-buffer ()
  (interactive)
  (let ((saved-buffer (current-buffer)))
    (set-buffer irchat-Dialogue-buffer)
    (goto-char (point-max))
    (set-buffer saved-buffer)))

;;;
;;; Following 4 functions come from
;;;  Masahiko MURAKAMI <murakami@nagao5.kuee.kyoto-u.ac.jp>
;;;

(defun irchat-Command-push ()
  "Move last channel of channels we are on to current (first)."
  (interactive)
  (if irchat-current-channels
      (let ((channel (format "%s" (nth (1- (length irchat-current-channels))
				       irchat-current-channels))))
	(if (memq (intern channel) irchat-current-channels)
	    (progn
	      (setq irchat-current-channel channel) ; just refocusing
	      (setq irchat-current-channels
		    (cons (intern channel)
			  (delq (intern channel) irchat-current-channels)))
	      (setq irchat-channel-indicator
		    (if irchat-current-channel
			(format "Channel %s" irchat-current-channel)
		      "No channel"))))
	(set-buffer-modified-p (buffer-modified-p)))))

(defun irchat-Command-pop ()
  "Move current channel to last of channels we are on."
  (interactive)
  (let ((channel (format "%s" irchat-current-channel)))
    (if (memq (intern channel) irchat-current-channels)
	(progn
	  (setq irchat-current-channels
		(delq (intern channel) irchat-current-channels))
	  (setq irchat-current-channel
		(and (car irchat-current-channels)
		     (format "%s" (car irchat-current-channels))))
	  (setq irchat-channel-indicator
		(format "Channel %s" irchat-current-channel))
	  (setq irchat-current-channels
		(append irchat-current-channels
			(list (intern channel))))))
    (set-buffer-modified-p (buffer-modified-p))))

;;;
;;; Cannot use completing read, user may want to query many ...
;;; oh what should I do
;;;

(defun irchat-Command-ison (nick)
  "IsON user."
  (interactive "sIsON: ")
  (irchat-send "ISON %s" nick))

(defun irchat-Command-userhost (nick)
  "Ask for userhost."
  (interactive "sUserhost nick(s): ")
  (irchat-send "USERHOST %s" nick))

;;;
;;; dig last kill from KILLS and show it
;;;
(defun irchat-Command-show-last-kill ()
  (interactive)
  (save-excursion
    (let ((buf (current-buffer))
	  str)
      (set-buffer irchat-KILLS-buffer)
      (goto-char (point-max))
      (forward-line -1)
      (setq str (buffer-substring (point) (point-max)))
      (goto-char (point-max))
      (set-buffer irchat-Dialogue-buffer)
      (goto-char (point-max))
      (setq buffer-read-only nil)
      (insert str)
      (goto-char (point-max))
      (setq buffer-read-only t)
      (set-window-point (get-buffer-window irchat-Dialogue-buffer)
			(point-max))
      (set-buffer buf))))
	  
