;; -*- lexical-binding: t -*-

;;; General configuration
(use-package org
  :ensure t
  :custom ((org-export-backends '(ascii html latex texinfo)))
  :init
  (defalias 'jao-open-gnus-frame 'jao-afio--goto-mail)

  (setq org-adapt-indentation t
        org-catch-invisible-edits 'smart
        org-complete-tags-always-offer-all-agenda-tags t
        org-cycle-separator-lines 0 ;; no blank lines when all colapsed
        org-deadline-warning-days 14
        org-default-notes-file (expand-file-name "inbox.org" org-directory)
        org-directory jao-org-dir
        org-display-remote-inline-images 'download ;; 'skip 'cache
        org-ellipsis " .." ;; ↴
        org-email-link-description-format "Email %c: %s"
        org-enforce-todo-dependencies t
        org-fast-tag-selection-single-key 'expert
        ;; org-list-demote-modify-bullet '(("+" . "-") ("-" . "+") ("*" . "+"))
        org-link-frame-setup
        '((gnus . (lambda (&optional x) (jao-open-gnus-frame)))
          (file . find-file-other-window))
        org-log-done nil
        org-modules '(bibtex info eww eshell git-link)
        org-odd-levels-only t
        org-outline-path-complete-in-steps nil
        org-refile-allow-creating-parent-nodes 'confirm
        org-refile-targets '((nil :maxlevel . 5)
                             (org-agenda-files :maxlevel . 5))
        org-refile-use-outline-path 'file
        org-return-follows-link t
        org-reverse-note-order t
        org-special-ctrl-a/e t
        org-src-fontify-natively t
        org-startup-folded t
        org-tag-alist nil
        org-tags-column -75
        org-todo-keywords
        '((sequence "TODO(t)" "STARTED(s!)" "|" "DONE(d!)")
          (sequence "REPLY(r)" "WAITING(w!)" "|" "DONE(d!)")
          (sequence "TOREAD(T)" "READING(R!)" "|" "READ(a!)")
          (sequence "|" "CANCELLED(x!)" "SOMEDAY(o!)" "DONE(d!)"))
        org-use-fast-todo-selection t
        org-use-speed-commands nil ;; t and then ? to see help
        org-gnus-prefer-web-links nil))
(require 'org)

;;; Agenda
(setq ;; org-agenda-custom-commands
      ;; '(("w" todo "WAITING" nil)
      ;;   ("W" agenda "" ((org-agenda-ndays 21))))
      org-agenda-files (mapcar (lambda (f)
                                 (expand-file-name f jao-org-dir))
                              '("inbox.org" "bigml.org"))
      org-agenda-block-separator " "
      org-agenda-breadcrumbs-separator "•"
      org-agenda-current-time-string "•" ;; "*"
      org-agenda-time-grid
      '((daily today require-timed)
        (800 1000 1200 1400 1600 1800 2000) "" "·")
      org-agenda-include-diary t
      org-agenda-include-inactive-timestamps t
      org-agenda-inhibit-startup nil
      org-agenda-restore-windows-after-quit t
      org-agenda-show-all-dates t
      org-agenda-skip-deadline-if-done t
      org-agenda-skip-scheduled-if-done nil
      org-agenda-span 14
      org-agenda-start-on-weekday nil
      org-agenda-window-setup 'current-window)

;;; Capture templates
(setq  org-capture-templates
       '(("t" "TODO" entry
          (file+headline "inbox.org" "Todo")
          "* TODO %?\n  %i%a" :prepend t)
         ("r" "REPLY" entry
          (file+headline "inbox.org" "Todo")
          "* REPLY %:subject%?\n  %t\n %i%a" :prepend t)
         ("a" "Appointment" entry
          (file+olp "inbox.org" "Appointments")
          "* %^T %?\n  %a" :time-prompt t)
         ("i" "Inbox note" entry (file+headline "inbox.org" "Notes")
          "* %a\n  %i%?(added on: %u)" :prepend t)))
;; (org-capture-upgrade-templates org-capture-templates)

;;; MIME and file apps
(setq org-file-apps
      '((system . mailcap)
        (".*\\.djvu" . system)
        (t . emacs)))

;;; Appearance
;; Show hidden emphasis markers
(use-package org-appear
  :ensure t
  :init (setq org-appear-autolinks nil
              org-appear-delay 0.0
              org-appear-manual-linger t)
  :hook (org-mode . org-appear-mode))

;; #+caption: Image caption.
;;  #+attr_org: :width 100
;;  [[file:path/to/image.png]]

(setq org-startup-indented nil
      org-pretty-entities nil
      org-hide-emphasis-markers t
      org-hide-leading-stars t
      org-startup-with-inline-images t
      org-image-actual-width '(300))

;;; LaTeX
(use-package org-fragtog
  :after org
  :ensure t
  :hook ((org-mode . org-fragtog-mode)))

(require 'org-fragtog)

(setq org-format-latex-options
      `(:foreground default
                    :background
                    ,(if (jao-colors-scheme-dark-p) "black" "white")
                    :scale 1.25
                    :html-foreground "black"
                    :html-background "Transparent"
                    :html-scale 1.0
                    :matchers ("begin" "$1" "$" "$$" "\\(" "\\["))
      org-preview-latex-image-directory
      (expand-file-name "~/.emacs.d/cache/ltximg/")
      org-latex-hyperref-template nil
      org-highlight-latex-and-related '(latex script entities))

(require 'ox-latex)

;;; Export (minted)
(setq org-latex-listings 'minted
      org-latex-packages-alist '(("" "minted"))
      org-latex-pdf-process
      '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
        "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))

;;; Babel and literate programming
(setq org-src-window-setup 'other-window) ;; current-window
(require 'org-tempo nil t) ;; <s TAB for 9.2 and later

;; (use-package poly-org :ensure t)

(use-package ob-prolog
  :ensure t
  :after org)

(org-babel-do-load-languages
 'org-babel-load-languages
 '((calc . t)
   (clojure . t)
   ;; (elixir . t)
   (emacs-lisp .t)
   (gnuplot .t)
   (haskell . t)
   (makefile . t)
   (ocaml . t)
   (org . t)
   (python . t)
   (scheme .t)
   (shell . t)
   (prolog . t)))

;;; Org cliplink (link from clipboard)
(use-package org-cliplink
  :ensure t
  :bind (:map org-mode-map ("C-c C-f" . org-cliplink))
  :config
  (add-to-list 'org-capture-templates
               '("k" "Cliplink capture task" entry
                 (file+headline "inbox.org" "Todo")
                 "* TODO %(org-cliplink-capture) %?" :prepend t)
               t))

;;; Notes
(use-package jao-org-notes
  :commands (jao-org-notes-setup)
  :config
  (defun jao-org-notes-note-p ()
    (string-prefix-p jao-org-notes-dir (buffer-file-name)))

  (defun jao-org-notes-recoll ()
    "Use consult-recoll to search notes."
    (interactive)
    (consult-recoll (format "dir:%s " jao-org-notes-dir)))

  (jao-transient-major-mode org
    ["Notes"
     ("o" "find and open note" jao-org-notes-open)
     ("c" "open or create note" jao-org-notes-open-or-create)
     ("\\" "grep notes" jao-org-notes-grep)
     ("r" "recoll notes" jao-org-notes-recoll)]
    ["Current note" :if jao-org-notes-note-p
     ("i" "insert link" jao-org-notes-insert-link)
     ("t" "insert tags" jao-org-notes-insert-tags)
     ("v" "show backlinks" jao-org-notes-backlinks)]))

(jao-org-notes-setup "n")

;;; Links
(require 'ol-eshell nil t)
;; (require 'ol-bbdb nil t)
(require 'ol-info nil t)
(setq org-link-abbrev-alist '(("jao.io" "https://jao.io/")))

(defun jao-org-link-at-point (&optional copy)
  (when (thing-at-point-looking-at "\\[\\[\\([^]]+\\)\\]\\[[^]]+\\]\\]")
    (when copy (kill-ring-save (match-beginning 1) (match-end 1)))
    (match-string-no-properties 1)))

(defun jao-org-copy-link-at-point ()
  (interactive)
  (message "%s" (or (jao-org-link-at-point t) "No link at point")))

(defun jao-org-insert-link (url title)
  (insert (format "[[%s][%s]]" url title)))

(defun jao-insert-eww-link ()
  "Look for last eww buffer and insert an org link to it."
  (interactive)
  (when-let (b (car (jao-eww-session--list-buffers)))
    (let ((lnk (with-current-buffer b
                 (format "[[%s][%s]]"
                         (eww-current-url)
                         (jao-eww-buffer-title)))))
      (insert lnk))))

(use-package jao-org-links
  :commands jao-org-links-setup
  :bind (("C-c T" . jao-org-insert-doc)))

(jao-org-links-setup jao-sink-dir)

(with-eval-after-load "pdf-view"
  (define-key pdf-view-mode-map (kbd "C-c o") #'jao-org-pdf-goto-org)
  (define-key pdf-view-mode-map (kbd "C-c O") #'jao-org-pdf-goto-org*))

(with-eval-after-load "doc-view"
  (define-key doc-view-mode-map (kbd "C-c o") #'jao-org-pdf-goto-org)
  (define-key doc-view-mode-map (kbd "C-c O") #'jao-org-pdf-goto-org*))

;; eldoc
(defun jao-org-eldoc--hook ()
  (set (make-local-variable 'eldoc-documentation-function)
       'jao-org-link-at-point)
  (eldoc-mode))
(add-hook 'org-mode-hook 'jao-org-eldoc--hook)

;;; savedoc
(defun jao-org--show-if-hidden ()
  (when (outline-invisible-p)
    (save-excursion
      (outline-previous-visible-heading 1)
      (org-show-subtree))))
(add-hook 'org-mode-hook 'jao-org--show-if-hidden t)

;;; Keybindings
(define-key mode-specific-map [?a] 'org-agenda)
(define-key org-mode-map "\C-cv" 'jao-org-copy-link-at-point)
(define-key org-mode-map [(control ?c) tab] 'org-force-cycle-archived)
(define-key org-mode-map [(f7)] 'org-archive-to-archive-sibling)
(define-key org-mode-map "\C-cE" 'jao-insert-eww-link)
(define-key org-mode-map "\C-cW" 'jao-insert-eww-link)
(define-key org-mode-map "\C-c'" 'org-edit-src-code)
(define-key org-mode-map "\C-cO" 'outline-hide-other)
(global-set-key "\C-cr" 'org-capture)
(global-set-key "\C-c\C-l" 'org-store-link)
;; (global-set-key "\C-cL" 'org-insert-link-global)
(global-set-key "\C-cO" 'org-open-at-point-global)

(jao-transient-major-mode+ org
  ["Links"
   ("le" "insert current eww link" jao-insert-eww-link)
   ("lf" "insert link from clipboard" org-cliplink)
   ("lc" "copy link at point" jao-org-copy-link-at-point)])

;;; .
(provide 'jao-custom-org)