;;  -*- lisp -*-

(load "~/.emacs-standard")

(defun tfheen-random-from-list (list)
  (let ((r (random (list-length list))))
    (while (> r 0)
      (setq r (- r 1))
      (setq list (cdr list)))
    (car list)))

(cw/requiring-package (nnir)
  (setq nnir-search-engine 'imap))

(cw/for-host "xoog"
  (setq gnus-select-method '(nnimap "err"
				    (nnimap-server-port 993)
				    (nnimap-stream ssl)
				    (nnimap-authinfo-file "~/.imap-authinfo.gpg")
                                    (nnimap-address "mail.err.no"))))

(cw/for-host "vuizook"
  (setq gnus-select-method '(nnnil ""))
  (add-to-list 'gnus-secondary-select-methods
	       '(nntp "bofh"
		      (nntp-address "nntp.fnord.no")
		      (nntp-port-number 563)
		      (nntp-open-connection-function nntp-open-tls-stream))))
;(cw/for-host "vuizook"
;  (add-to-list 'gnus-secondary-select-methods
;	       '(nnimap "err"
;			(nnimap-address "localhost"))))

(cw/for-host "cyoberpraen"
  (setq gnus-select-method '(nnimap "err"
				    (nnimap-server-port 993)
				    (nnimap-stream ssl)
                                    (nnimap-address "mail.err.no"))))


(cw/for-host "rahvafeir\\|fehawnok"
  (setq gnus-select-method '(nnimap "err"
				    (nnimap-stream ssl)
				    (nnimap-server-port 993)
                                    (nnimap-address "mail.err.no"))))

(setq imap-shell-program
      '("ssh -ax -C -oBatchMode=yes vuizook.err.no 'exec env MAIL_PLUGINS=antispam MAIL_PLUGIN_DIR=/usr/lib/dovecot/modules/imap MAIL=$HOME/Maildir /usr/lib/dovecot/imap'")
      imap-gssapi-program '("imtest -m gssapi -u %l -s %s")
      nntp-rlogin-program "ssh")

(setq imap-ssl-program "stunnel -c -A ~/.cacerts.pem -v 2 -f -r %s:%p")

(setq nnml-crosspost nil
      nnmail-crosspost nil
      gnus-novice-user nil
      gnus-interactive-exit nil
      message-default-charset 'utf-8
      message-send-mail-partially-limit nil)

(add-hook 'nntp-server-opened-hook 'nntp-send-authinfo)
(add-hook 'nntp-server-opened-hook 'nntp-send-mode-reader)

(setq mail-open-quote "\u00AB"
      mail-close-quote "\u00BB")

(defun mail-insert-quote (arg)
  "Insert the appropriate quote marks for Norwegian mail.
Inserts the value of `mail-open-quote' (normally ) or `mail-close-quote'
\(normally ) depending on the context.  With prefix argument, always
inserts \" characters."
  (interactive "*P")
  (if arg
      (self-insert-command (prefix-numeric-value arg))
    (insert
     (cond ((or (bobp)
		(save-excursion
		  (forward-char -1)
		  (looking-at "\\s(\\|\\s \\|\\s>")))
	    mail-open-quote)
	   ((= (preceding-char) ?\\)
	    ?\")
	   (t
	    mail-close-quote)))))

(add-hook  'nnmail-prepare-incoming-header-hook 'nnmail-fix-eudora-headers)

(defun tfheen-de-arntify ()
  (interactive)
  (save-excursion
    (if (string= (message-fetch-field "From") "Arnt Karlsen <arnt@c2i.net>")
        (let ((inhibit-point-motion-hooks t)
              buffer-read-only)
          (set-buffer gnus-article-buffer)
          (goto-char (point-min))
          (replace-regexp "^\\.\\." "")
          (goto-char (point-min))
          (replace-regexp " ? ?;[-o])$" "")))))

(defun tfheen-de-tillify ()
  (interactive)
  (save-excursion
    (if (or (string= (message-fetch-field "From") "Andreas Tille <tillea@rki.de>")
            (string= (message-fetch-field "From") "md@Linux.IT (Marco d'Itri)")
            (string= (message-fetch-field "From") "Nathanael Nerode <neroden@twcny.rr.com>"))
        (let ((inhibit-point-motion-hooks t)
              buffer-read-only)
          (set-buffer gnus-article-buffer)
          (goto-char (point-min))
          (replace-regexp "^\\(>.*\\)
\\([^>]\\)" "\\1

\\2")))))

(defun tfheen-right-quotify ()
  (interactive)
  (save-excursion
    (let ((inhibit-point-motion-hooks t)
          buffer-read-only)
      (set-buffer gnus-article-buffer)
      (goto-char (point-min))
      (while (re-search-forward "^>+" nil t)
        (let ((i 0)
              (str "")
              (tmp (length (match-string 0))))
          (while (< i tmp)
            (setq str (concat str "|"))
            (setq i (+ i 1)))
          (setq str (concat str " "))
          (replace-match str nil nil)))
      (while (re-search-forward "| |+" nil t)
        (replace-match "||" nil nil)))))


(add-hook 'gnus-article-prepare-hook 'tfheen-de-arntify)
(add-hook 'gnus-article-prepare-hook 'tfheen-de-tillify)
;(add-hook 'gnus-article-prepare-hook 'tfheen-right-quotify)
(add-hook 'gnus-article-display-hook 'gnus-article-highlight-citation)

(defadvice message-sendmail-envelope-from (around tfheen-set-sendmail-sender activate)
  "Set the sender to the contents of the Sender field, if present."
  (if (message-fetch-field "sender")
      (let ((message-sendmail-envelope-from 
	     (nth 1 (mail-extract-address-components
		     (message-fetch-field "sender")))))
	ad-do-it)
    ad-do-it))

;; Don't _reply_ in news, dimwit!
(defadvice gnus-summary-reply (around reply-in-news activate)
  (interactive)
  (when (or (not (gnus-news-group-p gnus-newsgroup-name))
            (y-or-n-p "Really reply? "))
    ad-do-it))

(setq gnus-home-score-file
      '(("\\(biz\\|marked\\|annonser\\)" "marked.SCORE")
	("^nnml:jobb.opera.elektra" "opera.SCORE")))

(setq gnus-use-cache t
      gnus-agent-cache nil
      gnus-agent-queue-mail nil
      message-kill-buffer-on-exit t
      nnvirtual-always-rescan t
      rmail-dont-reply-to-names "tfheen\\|tollef\\|nobody\\|never\\|none"
      message-dont-reply-to-names rmail-dont-reply-to-names
)

(defun tfheen-escape-url () "Puts <URL:> around URLs."
(interactive)
(save-excursion 
  (goto-char (point-min))
  (replace-regexp "<URL:\\([^>]*\\)>" "\\1")
  (goto-char (point-min))
  (replace-regexp gnus-button-url-regexp "<URL:\\&>")))

(add-hook 'message-mode-hook '(lambda()(local-set-key "\M-\S-F" 'tfheen-insert-footnote)))
(add-hook 'message-mode-hook '(lambda()(local-set-key "\"" 'mail-insert-quote)))

;(add-hook 'gnus-article-display-hook 'gnus-article-hide-pgp)
;(add-hook 'message-send-hook 'tfheen-escape-url)
(add-hook 'message-send-hook 'tfheen-check-mail-followup-to)
;(add-hook 'mc-pre-encryption-hook 'tfheen-escape-url)
;(add-hook 'mc-pre-signature-hook 'tfheen-escape-url)

(defun tfh-insert-citation-line ()
  "My own function to insert citation. Inserts a line similar to \"]] Tollef Fog Heen\n\n\""
  (if (string-equal gnus-newsgroup-name "nnml:drift.news.nag.submissions")
      "  "
    (when message-reply-headers
      (let ((author (or (mail-header-from message-reply-headers) "")))
	(string-match "[^@ ]+@[^@ ]+" author)
	(insert "]] "(replace-match "" nil nil author) "\n\n")))))

(setq gnus-summary-gather-subject-limit 'fuzzy
      gnus-simplify-subject-fuzzy-regexp "^\\([Aa][Dd]: \\|[Ss][Vv]: \\|[Rr][Ee]: \\)+"
      mc-gpg-comment "Please see my GPG key at http://err.no/gpgkey.asc"
      gnus-simplify-ignored-prefixes "^\\([Aa][Dd]: \\|[Ss][Vv]: \\|[Rr][Ee]: \\)+"
      message-citation-line-function 'tfh-insert-citation-line
      gnus-simplify-subject-functions '(gnus-simplify-subject gnus-simplify-subject-fuzzy)
      gnus-summary-mode-line-format "Gnus: %G [%A] %Z")

(setq gnus-uncacheable-groups "^nnml")
;(add-to-list 'mm-discouraged-alternatives "text/html")

;; text processing definitions

(setq-default sentence-end "[.?!][]\"')}]*[ \n]+")
(setq-default paragraph-start "^[|:> \t]*$")
(setq-default paragraph-separate (default-value 'paragraph-start))
(setq adaptive-fill-regexp (substring (default-value 'paragraph-start) 1 -1))

(defun tfheen-debian-group-p ()
  (if (string-match "nnml:linux.debian" gnus-newsgroup-name) t nil))

(defun tfheen-get-recipients-parsed ()
  (if (bufferp gnus-article-buffer)
      (save-excursion
	(set-buffer gnus-article-buffer)
	(message-narrow-to-headers-or-head)
	(append (mail-header-parse-addresses 
		 (message-fetch-field "to"))
		(mail-header-parse-addresses 
		 (message-fetch-field "cc"))))))

(defun tfheen-debian-find-recipients ()
  "Try to find all the recipients on debian lists."
  (if (bufferp gnus-article-buffer)
      (save-excursion
	(set-buffer gnus-article-buffer)
	(message-narrow-to-headers-or-head)
	(or (message-fetch-field "Mail-Followup-To")
	    (mapconcat '(lambda(x) 
			  (if (string-match ".*@lists.debian.org" (car x))
			      (car x) nil))
		       (tfheen-get-recipients-parsed) ", ")))))

(defun tfheen-gnus-get-current-select-method ()
  "Return the select method of the summary buffer as defined by gnus-summary-buffer"
  (save-excursion
    (if (buffer-live-p gnus-summary-buffer)
	(set-buffer gnus-summary-buffer))
    gnus-current-select-method))

(setq gnus-posting-styles
  '(
    ; Default-verdier
    (".*" 
     (address "tfheen@err.no")
     (Organization "Private")
     (Bcc (concat "tfheen+outgoing" (char-to-string 64) "err.no"))

     (signature-file "~/.signature"))
    ((and (message-mail-p) (stringp gnus-newsgroup-name))
     ("Mail-Followup-To" (or (and (get-buffer gnus-original-article-buffer)
                                  (gnus-mailing-list-followup-to))
                             (gnus-group-get-parameter gnus-newsgroup-name 'to-address))))
;     ("Mail-Followup-To" (or (gnus-group-get-parameter gnus-newsgroup-name 'to-address)
;                             (if (tfheen-debian-group-p)
;                                 (mapconcat '(lambda(x) 
;                                               (if (string-match ".*@lists.debian.org" (car x))
;                                                   (car x) nil))
;                                (tfheen-get-recipients-parsed)
;                                nil)))))
                              
;    ((and (message-mail-p) (stringp gnus-newsgroup-name) (tfheen-debian-group-p))
;     (to (tfheen-debian-find-recipients))
;     (cc nil))
    ("in-"
     (address (let ((addr 
                     (mapconcat '(lambda(x) 
                                   (if (string-match gnus-ignored-from-addresses
                                                     (car x))
                                       (car x) nil))
                                (tfheen-get-recipients-parsed)
                                               nil)))
                (if (string-equal addr "") "tfheen@err.no" addr))))
    ; ITK/Samfundet-ting
    ("drift.\\(itk\\|samfundet\\)"
     (address "tfheen@samfundet.no")
     (Organization "Samfundet - ITK")
     (x-url "http://www.samfundet.no"))
    ; PVV
    ("drift.pvv.*"
     (address "tfheen@pvv.ntnu.no")
     (Organization "Programvareverkstedet i Trondheim")
     (x-url "http://www.pvv.ntnu.no"))))

(defun tfheen-get-header-fuzzy (field)
  "Searches the current buffer for a match to the regexp specified as
field."
  (save-excursion
    (goto-char (point-min))
    (search-forward-regexp (concat field ":[ \t]*\\(.*\\)") (point-max) t)
    (match-string 1)))

(defun tfheen-check-mail-followup-to ()
  "Checks that mail-followup-to is set to one of the recipients.  Breaks
on multiple mail-followup-to headers"
  (goto-char (point-min))
  (let ((headers (mail-header-extract))
	(to-list "")
	(mail-followup-to ""))
    (while headers
      (if (string= (car (car headers)) "to")
	  (setq to-list (concat to-list (cdr (car headers)))))
      (if (string= (car (car headers)) "cc")
	  (setq to-list (concat to-list (cdr (car headers)))))
      (if (string= (car (car headers)) "bcc")
	  (setq to-list (concat to-list (cdr (car headers)))))
      (if (string= (car (car headers)) "mail-followup-to")
	  (setq mail-followup-to (cdr (car headers))))
      (setq headers (cdr headers)))
    (if (not (string-match mail-followup-to to-list))
	(if (not (y-or-n-p "Mail-Followup-To not in recipient list.  Really post?"))
	    (keyboard-quit)))))

(defun tfheen-insert-footnote ()
  "Insert footnote and set mark to where you were in the text."
  (interactive)
  (make-variable-buffer-local 'tfheen-footnotes)
  (setq tfheen-footnotes (+ 1 (or tfheen-footnotes 0)))
  (insert (format "[%d]" tfheen-footnotes))
  (push-mark (point) t nil)
  (goto-char (point-max))
  (re-search-backward "^-- $")
  (backward-char)
  (insert (format "\n[%d] " tfheen-footnotes)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Drittlei av Re: Sv: Re: i subject...
;;
;; fra Lars Clausen <lrclause@cs.uiuc.edu> paa gnu.emacs.gnus
;; 27. juli 2000  --  tilpasset norske forhold.

(defvar message-subject-re-re
  "^\\(\\(\\([Rr][Ee]?\\|[Ss][Vv]\\): *\\)*\\(\\(R\\|[Ss][Vv]\\): *\\)+\\)"
  "Regexp that matches any number of \"Re: \"'s and at least a \"Sv: \" at the end")

(defvar message-re-string
  "Re: "
  "The string added to indicate an answer")

(defun strip-any-re (subject)
  "Remove \"Re:\" from subject lines, internationalizably"
  (message subject)
  (if (string-match message-subject-re-re subject)
      (progn
        (message (int-to-string (match-end 1)))
        (substring subject (match-end 1))
        )
    subject))

(defun message-subject-strip-any-re () 
  (save-excursion
    ;; Would have used
    ;;    (message-goto-subject)
    ;; but it fails :(
    (beginning-of-buffer)
    (let ((subject (mail-fetch-field "Subject")))
      ;; Stripper Subject: for SV:- graps hvis
      ;;  - det er et gyldig Subject-felt
      ;;  - Subject-feltet starter med noe som inneholder minst 1 [Ss][Vv]
      ;;  - jeg vil at det skal strippes
      (if (and subject 
               (not (equal subject ""))
               (string-match message-subject-re-re subject)
               (y-or-n-p "Stripp vekk SV: i Subject? "))
          (let ((replacement (strip-any-re subject)))
            (message-remove-header "Subject")
            (message-add-header 
             (concat "Subject: " message-re-string  replacement)))))))

(add-hook 'message-header-setup-hook 'message-subject-strip-any-re)
(setq gnus-ignored-from-addresses "tfheen@\\(debian\\.org\\|err.no\\|samfundet\\.no\\|uka\\.no\\|pvv\\.\\(org\\|ntnu.no\\)\\)\\|tollef@err\\.no")

(cw/requiring-package (deuglify))

(setq tfheen-spam-folder "spam")

(defun tfheen-mark-as-spam ()
  (interactive)
;  (let ((buf (get-buffer-create "*Spam mark*"))
;	(cacheid (tfheen-fetch-cacheid)))
;    (and cacheid
;	 (start-process "spammark" buf "ssh" "-oBatchMode=yes" "vuizook" "spam" cacheid)))
  (gnus-summary-move-article nil (if (stringp tfheen-spam-folder)
					      tfheen-spam-folder
				     (apply tfheen-spam-folder nil)) nil 'move)
  (gnus-summary-next-subject 1))

(defun tfheen-mark-as-ham ()
  (interactive)
  (let ((buf (get-buffer-create "*Ham mark*")))
    (start-process "hammark" buf "ssh" "-oBatchMode=yes" "vuizook" "ham" (tfheen-fetch-cacheid))))

(defun tfheen-fetch-cacheid ()
  (save-excursion
    (set-buffer gnus-article-buffer)
    (message-fetch-field "x-crm114-cacheid")))

(defun tfheen-kill-ring-cacheid ()
  (interactive)
    (kill-new (tfheen-fetch-cacheid))
    (widen))

(cw/for-host "xoog\\|vuizook\\|rahvafeir\\|fehawnok\\|cyoberpraen"
  (define-key gnus-summary-backend-map "s" 'tfheen-mark-as-spam)
  (define-key gnus-summary-mode-map "z" 'tfheen-mark-as-spam)
  (define-key gnus-summary-mode-map "v" 'tfheen-kill-ring-cacheid)
  (define-key gnus-summary-mode-map "\C-i" 'tfheen-mark-as-ham)
  (setq pgg-default-user-id "tfheen@err.no"
	epg-user-id "CA19D717"
	mml1991-signers '("CA19D717")
	mml2015-signers '("CA19D717")
	mml-secure-openpgp-signers '("CA19D717")
	mml-secure-openpgp-encrypt-to-self '("CA19D717")
	mml-secure-safe-bcc-list '((concat "tfheen+outgoing" (char-to-string 64) "err.no"))
	gnus-subscribe-newsgroup-method 'gnus-subscribe-topics
        gnus-agent-synchronize-flags t))

(setq message-subscribed-address-functions
      '(gnus-find-subscribed-addresses))

(setq gnus-parameters
      '(("^linux.debian\\.\\(announce\\|admin\\|apache\\|boot\\|bsd\\|cd\\|ctte\\|curiosa\\|devel\\|devel-announce\\|dpkg\\|edu\\|emacsen\\|events-eu\\|mentors\\|news\\|policy\\|private\\|project\\|python\\|qa\\|release\\|ruby\\).*"
         (to-address . "debian-\\1@lists.debian.org")
         (to-list . "debian-\\1@lists.debian.org")
         (subscribed . t)))
      gnus-agent-enable-expiration 'DISABLE
      gnus-agent-expire-unagentized-dirs nil
      nnmail-expiry-wait 'never
      nnmail-use-long-file-names t)

; a bit snaer HTML handling
;(cw/for-host "aexonyam"
;  (add-to-list 'mm-text-html-renderer-alist
;               '(vilistextum mm-inline-render-with-file
;                             mm-links-remove-leading-blank
;                             "vilistextum" "-l" "-r" "-c" "-s" file "-"))
;  (add-to-list 'mm-text-html-washer-alist 
;               '(vilistextum mm-inline-wash-with-file
;                             mm-links-remove-leading-blank
;                             "vilistextum" "-l" "-r" "-c" "-s" file "-"))
;  (setq mm-text-html-renderer 'vilistextum))

(defsubst gnus-article-sort-by-message-id (h1 h2)
  "Sort articles by message id length."
  (string-lessp (mail-header-message-id h1)
                (mail-header-message-id h2)))

(defun gnus-thread-sort-by-message-id (h1 h2)
  "Sort threads by root article message id."
  (gnus-article-sort-by-message-id
   (gnus-thread-header h1) (gnus-thread-header h2)))

(defun gnus-summary-sort-by-message-id (&optional reverse)
  "Sort the summary buffer by message id.
Argument REVERSE means reverse order."
  (interactive "P")
  (gnus-summary-sort 'message-id reverse))

(add-hook 'gnus-group-mode-hook 'gnus-topic-mode)

(setq gnus-group-line-format "%M%S%p %5,5y/%5,5t [%2T]: %-30G %z %10D\n"
      gnus-visible-headers "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^Followup-To:\\|^Reply-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^To:\\|^[BGF]?Cc:\\|^Posted-To:\\|^Mail-Copies-To:\\|^Mail-Followup-To:\\|^Apparently-To:\\|^Gnus-Warning:\\|^Resent-From:\\|^X-Sent:\\|^X-CRM114-")

(defun gnus-user-format-function-C (header)
  "Return the X-CRM114-Score value."
  (let ((env (cdr (assoc 'X-CRM114-Score (mail-header-extra header)))))
    (if env
        env
      "")))

(setq gnus-summary-line-format "%U%R%z%-6,6uC %I%(%[%4L: %-23,23f%]%) %s\n")

(add-to-list 'gnus-extra-headers 'X-CRM114-Score)
(add-to-list 'nnmail-extra-headers 'X-CRM114-Score)

(setq message-sendmail-f-is-evil nil
      message-sendmail-envelope-from 'header)
(setq gnus-extract-address-components 'mail-extract-address-components
      gnus-auto-select-first nil)

;;; (setq bbdb/send-auto-create-p 'prompt)
;;; (setq bbdb/send-prompt-for-create-p t)
(setq imap-store-password t
      gnus-large-newsgroup 10000)

(require 'gnus-icalendar)
(setq gnus-icalendar-org-capture-file (expand-file-name "~/Sync/notes/calendar.org"))
(setq gnus-icalendar-org-capture-headline '("Calendar"))
(gnus-icalendar-setup)
;(gnus-icalendar-org-setup)

(add-to-list 'gnus-button-alist
	     '("\\(Bug\\)?#\\([0-9][0-9][0-9][0-9]+\\)" 0 (>= gnus-button-message-level 0) debian-bug-web-bug 2))

; Workaround for race condition with new dovecot..
(define-advice open-gnutls-stream (:after (&rest args) workaround-for-930573)
  (sleep-for 0 250))
(cw/requiring-package (vdirel)
  (setq vdirel-repository "~/.contacts/contacts.vcf")
  (define-key message-mode-map [M-tab] 'vdirel-helm-select-email))
