;; -*- emacs-lisp -*-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; $Id: erc.el,v 1.19 2006/03/06 12:07:06 ole Exp $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* Emacs IRC client
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(require 'erc-menu)
(require 'erc-bbdb)
(require 'erc-notify)
(require 'erc-lang)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* Connect
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(setq erc-server "localhost" 
      erc-port 6667 
      erc-nick "ole"
      erc-user-full-name user-full-name
      erc-email-userid user-mail-address
      erc-prompt-for-password nil
      erc-keywords '("sugarshark" "ole:")
      erc-notify-list '("britta" "Sascha" "tina")

      ;; autojoin channels
      erc-autojoin-channels-alist
      '(("freenode.net" "#emacs" "#lisp")
        ("irc.irc-mania.de" "#netbiker")
        ("oliver" "#oneup" "#cegbot")
        ("localhost" "&bitlbee"))

      ;; automatically open buffers on query
      ;; erc-auto-query 'window-noselect

       erc-default-coding-system
       '(utf-8 . undecided)

      erc-encoding-coding-alist
      '(("#oneup" . utf-8))

      ;; presets
      erc-server-history-list
        (list "oliver"  "irc.freenode.org"  "irc.irc-mania.de" "irc.stratics.com" "localhost")
      erc-nick-history-list   (list "sugarshark" "ole")
)


(defun my-erc-after-connect-hook (server nick)
  "hook function run after server connect"
  (message "Connected to server %s with nick %s" server nick)
  (cond 
   ((string= server "nowhere")
    (erc-message "PRIVMSG" "NickServ identify ircpass"))
   ((string-match ".*\\.freenode.\\(org\\|net\\)" server)
    (erc-message "PRIVMSG" (concat "NickServ identify " secret-erc-freenode)))
   ((string-match "localhost" server)
    (message "Connected to server %s with nick %s" server nick)
    (erc-message "PRIVMSG" (concat "root identify " secret-erc-bitlbee)))
    ))

(add-hook 'erc-after-connect 'my-erc-after-connect-hook)

(defun my-erc-mode-hook ()
  "hook function to run when entering erc mode"
  (erc-add-scroll-to-bottom)
  (when (not (featurep 'xemacs))
    (set (make-variable-buffer-local 'coding-system-for-write) 'emacs-mule))
  )

(add-hook 'erc-mode-hook 'my-erc-mode-hook)

;; erc submodes
(erc-autojoin-mode 1)
(erc-match-mode)
(erc-ring-mode t)
(erc-netsplit-mode t)
;; (erc-pcomplete-mode 1)
(erc-smiley-mode 1)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* Tracking
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; (erc-track-modified-channels-mode t)

(defun reset-erc-track-mode ()
  (interactive)
  (setq erc-modified-channels-alist nil)
  (erc-modified-channels-update))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* Logging
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(setq erc-log-insert-log-on-open nil
      erc-log-channels t
      erc-log-channels-directory "~/.irclogs/"
      erc-save-buffer-on-part t
      erc-max-buffer-size 50000
      erc-truncate-buffer-on-save t)

(defun my-erc-insert-post-hook ()
  "hook function run after inserting text in erc mode"
  (erc-save-buffer-in-logs)
  (erc-truncate-buffer)
  (set-buffer-modified-p nil))

(add-hook 'erc-insert-post-hook 'my-erc-insert-post-hook)

(defadvice save-buffers-kill-emacs (before save-logs (arg) activate)
  (save-some-buffers t (lambda () (when (and (eq major-mode 'erc-mode)
                                             (not (null buffer-file-name)))))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* Timestamp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(setq erc-hide-timestamps nil
      erc-timestamp-only-if-changed-flag nil
      erc-timestamp-format "[%H:%M] "
      erc-insert-timestamp-function 'erc-insert-timestamp-left)

(erc-timestamp-mode t)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* Filling
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(setq  erc-fill-prefix nil
       erc-fill-function 'erc-fill-variable)

(add-hook 'erc-insert-modify-hook 'erc-fill)
(add-hook 'erc-send-modify-hook 'erc-fill)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* H4x0r Mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(add-hook 'erc-send-pre-hook 'erc-maybe-h4x0r)

(define-minor-mode erc-h4x0r-mode
  "Toggle automatic usage of h4x0r code for everything you type in ERC.")

(defun erc-maybe-h4x0r (ignore)
  "Change the text to h4x0r code, if `erc-h4x0r-mode' is non-nil."
  (when erc-h4x0r-mode
    (with-temp-buffer
      (insert str)
      (erc-h4x0r)
      (setq str (buffer-string)))))

(defun erc-h4x0r ()
  "Transform the buffer into h4x0r code."
  (h4x0r-region (point-min) (point-max)))

(autoload 'h4x0r-region "h4x0r")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* Goto ERC function
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defvar *erc-track-restore* nil)

(defun erc-track-switch-buffer-other-window (arg)
  "Switch to the next active ERC buffer, or if there are no active buffers,
switch back to the last non-ERC buffer visited.  Next is defined by
`erc-track-switch-direction', a negative argument will reverse this.
This function switches to the escreen for erc."
  (interactive "p")
  (when erc-track-mode
    (let ((dir erc-track-switch-direction))
      (if erc-modified-channels-alist
          (progn
            (unless (eq major-mode 'erc-mode)
              (lexical-let ((buf (current-buffer))
                            (win (select-window (split-window))))
                (setq *erc-track-restore*
                      (lambda ()
                        (if (window-live-p win) (delete-window win))
                        (if (buffer-live-p buf) (switch-to-buffer buf))
                        (setq *erc-track-restore* nil)))))
            ;; and jump to the next active channel
            (switch-to-buffer (erc-track-get-active-buffer arg)))
        ;; if no active channels, switch back to what we were doing before
        (message "No active channel.")
        (when (and (eq major-mode 'erc-mode) erc-track-switch-from-erc)
          (if *erc-track-restore* (funcall *erc-track-restore*)))))))


(defun switch-to-irc ()
  "Switch to an IRC buffer, or run `erc-select'.
    When called repeatedly, cycle through the buffers."
  (interactive)
    (let ((buffers (and (fboundp 'erc-buffer-list)
                        (erc-buffer-list))))
      (when (eq (current-buffer) (car buffers))
        (bury-buffer)
        (setq buffers (cdr buffers)))
      (if buffers
          (switch-to-buffer (car buffers))
        (erc-select))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* Commands
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun erc-cmd-INFO (&rest ignore)
  "Send current info node."
  (unless (get-buffer "*info*")
    (error "No *info* buffer"))
  (let (output)
    (with-current-buffer "*info*"
      (let* ((file (file-name-nondirectory Info-current-file))
             (node Info-current-node))
        (setq output (format "(info \"(%s)%s\") <-- hit C-x C-e to evaluate"
                             file node))))
    (erc-send-message output)))

(defun erc-cmd-NP (&rest ignore)
  "Post what emms is playing." 
   (interactive)
   (when emms-player-playing-p
     (erc-send-action (erc-default-target)
                      (with-temp-buffer
                        (let ((emms-show-format "currently listens to: %s"))
                          (emms-show t)
                          (buffer-string)))
                      )))

(require 'erc-show)
(require 'lisppaste)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* Keys
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defvar erc-keymap (make-sparse-keymap "IRC")
  "Keymap used to globally access irc related functionality.")
(define-key mode-specific-map [?e] erc-keymap)

(define-key erc-keymap [?e] 'erc-select)
(define-key erc-keymap [?r] 'reset-erc-track-mode)
(define-key erc-keymap [?l] 'erc-chanlist)
(define-key erc-keymap [?q] 'erc-quit-server)

(define-key mode-specific-map [? ] 'erc-track-switch-buffer-other-window)
(define-key mode-specific-map [(control ? )] 'erc-track-switch-buffer-other-window)
(define-key goto-keymap [?e] 'switch-to-irc)