;;; Loads the bible from http://mlbible.com/ in several languages into a buffer
;;; Peter Salvi, 2009.05.20.

;;; Usage:
;;; Setup the BIBLE-LANGUAGES, and then call BIBLE-LOOKUP from the minibuffer.

(defvar bible-languages
  '((greek     . "Greek \\(OT: Septuagint with Diacritics\\|NT: Westcott\\)")
    (latin     . "Latin: Biblia Sacra Vulgata")
    (german    . "German: Luther (1545)")
    (english   . "King James Bible")
    (hungarian . "Hungarian: Karoli")
    (chinese   . "Chinese Bible: Union (Simplified)")
    (arabic    . "Arabic: Smith & Van Dyke"))
  "*The needed languages, in the required order.")

(defun bible-get-page (url)
  (let ((buffer (url-retrieve-synchronously url)))
    (save-excursion
      (set-buffer buffer)
      (set-buffer-multibyte t)
      (decode-coding-region (point-min) (point-max) 'utf-8))
    buffer))

(defun bible-get-translation (buffer language-str)
  (save-excursion
    (set-buffer buffer)
    (goto-char (point-min))
    (when (and (search-forward-regexp language-str nil t)
               (search-forward-regexp "class=\"pd1\"" nil t)
               (search-forward-regexp "<br>\\(</?span[^>]*>\\)*\\([^>]+\\)\\(</span>\\)?<br>" nil t))
      (match-string 2))))

(defun bible-headline (language-sym)
  (format "* %s:" (capitalize (symbol-name language-sym))))

(defun bible-contents (book chapter verse to-verse)
  (when (get-buffer "*bible*")
    (kill-buffer "*bible*"))
  (let ((output (get-buffer-create "*bible*")))
    (set-buffer output)
    (dolist (language bible-languages)
      (insert (format "%s\n\n\n" (bible-headline (car language)))))
    (while (<= verse to-verse)
      (goto-char (point-min))
      (let ((page (bible-get-page (format "http://mlbible.com/%s/%d-%d.htm"
                                          book chapter verse))))
        (dolist (language bible-languages)
          (let ((content (bible-get-translation page (cdr language))))
            (when content
              (search-forward-regexp (format "^%s$"
                                             (bible-headline (car language))))
              (unless (search-forward-regexp "^\* " nil t)
                (goto-char (point-max)))
              (beginning-of-line)
              (forward-line -1)
              (insert (format "%d. %s\n" verse content)))))
        (kill-buffer page))
      (setq verse (1+ verse)))
    (goto-char (point-min))
    (switch-to-buffer-other-window output)))

(defun bible-lookup (place)
  "Displays the given place in the languages selected by BIBLE-LANGUAGES."
  (interactive "sVerse (e.g. John 3:4-7) ")
  (if (string-match "^\\([^ ]+\\) \\([0-9]+\\):\\([0-9]+\\)\\(-[0-9]+\\)?$"
                    place)
      (let ((book (downcase (match-string 1 place)))
            (chapter (string-to-number (match-string 2 place)))
            (verse (string-to-number (match-string 3 place)))
            (to-verse (match-string 4 place)))
        (bible-contents book chapter verse
                        (if to-verse
                            (string-to-number (substring to-verse 1))
                          verse)))
    (message "I cannot understand what verse(s) you want.")))

;;; (bible-lookup "John 3:4-7")