;;;; window.el
;; Inspiration: https://christiantietze.de/posts/2022/12/updated-org-mode-agenda-display-buffer-alist/
(defun rul/display-buffer-org-agenda-managed-p (buffer-name action)
  "Determine whether BUFFER-NAME is an org-agenda managed buffer."
  (with-current-buffer buffer-name
    (or (derived-mode-p 'org-mode 'org-agenda-mode)
         (member (buffer-file-name) (org-agenda-files)))))

;; Side window for dictionary
(setq switch-to-buffer-obey-display-actions t)
(add-to-list 'display-buffer-alist
   '("^\\*Dictionary\\*" display-buffer-in-side-window
     (side . left)
     (window-width . 80)))

;;;; tab-bar.el
(let ((map global-map))
(define-key map (kbd "C-<next>") 'tab-bar-switch-to-next-tab)
(define-key map (kbd "C-<prior>") 'tab-bar-switch-to-prev-tab)
(define-key map (kbd "<f8>") 'tab-bar-mode))

(setq tab-bar-format
      '(tab-bar-format-tabs
        ;; tab-bar-format-align-right
        ;; tab-bar-format-global
        ))

(setq tab-bar-new-tab-to 'rightmost)
(setq tab-bar-close-button-show nil)
(set-face-attribute 'tab-bar nil :height 0.8)

;; I've moved to a frame oriented workflow, so I no longer use tabs.
;; (tab-bar-mode 1)

;; Pop-up buffers
;; https://protesilaos.com/codelog/2024-09-19-emacs-command-popup-frame-emacsclient/
(defun prot-window-delete-popup-frame (&rest _)
  "Kill selected selected frame if it has parameter `prot-window-popup-frame'.
Use this function via a hook."
  (when (frame-parameter nil 'prot-window-popup-frame)
    (delete-frame)))

(defmacro prot-window-define-with-popup-frame (command)
  "Define interactive function which calls COMMAND in a new frame.
Make the new frame have the `prot-window-popup-frame' parameter."
  `(defun ,(intern (format "prot-window-popup-%s" command)) ()
     ,(format "Run `%s' in a popup frame with `prot-window-popup-frame' parameter.
Also see `prot-window-delete-popup-frame'." command)
     (interactive)
     (let ((frame (make-frame '((prot-window-popup-frame . t)))))
       (select-frame frame)
       ;; Placeholder for frame, otherwise it'll get autoclosed.
       (switch-to-buffer " prot-window-hidden-buffer-for-popup-frame")
       (condition-case nil
           (call-interactively ',command)
         ((quit error user-error)
          (delete-frame frame))))))

(declare-function org-capture "org-capture" (&optional goto keys))
(defvar org-capture-after-finalize-hook)

;;;###autoload (autoload 'prot-window-popup-org-capture "prot-window")
(prot-window-define-with-popup-frame org-capture)

(add-hook 'org-capture-after-finalize-hook #'prot-window-delete-popup-frame)

(use-package olivetti
  :ensure t
  :defer t
  :config
  (setq olivetti-body-width 100))

(use-package logos
:ensure t
:config

;; If you want to use outlines instead of page breaks (the ^L)
(setq logos-outlines-are-pages t)
(setq logos-outline-regexp-alist
      `((emacs-lisp-mode . "^;;;+ ")
        (org-mode . "^\\*+ +")
        (markdown-mode . "^\\#+ +")
        ))

;; These apply when `logos-focus-mode' is enabled.  Their value is
;; buffer-local.
(setq-default logos-hide-mode-line t
              logos-hide-buffer-boundaries t
              logos-hide-fringe t
              logos-variable-pitch nil
              logos-buffer-read-only nil
              logos-scroll-lock nil
              logos-olivetti t
              olivetti-body-width 100
              )


(let ((map global-map))
  (define-key map [remap narrow-to-region] #'logos-narrow-dwim)
  (define-key map [remap forward-page] #'logos-forward-page-dwim)
  (define-key map [remap backward-page] #'logos-backward-page-dwim)
  (define-key map (kbd "<f7>") #'logos-focus-mode))
)

(use-package beframe
  :ensure t
  :hook (after-init . beframe-mode)
  :config
  (setq beframe-functions-in-frames '(project-prompt-project-dir))
  (setq beframe-global-buffers nil)
  (define-key global-map (kbd "C-c b") beframe-prefix-map)

  ;;Integration with Consult
  (defvar consult-buffer-sources)
  (declare-function consult--buffer-state "consult")

  (with-eval-after-load 'consult
    (defface beframe-buffer
      '((t :inherit font-lock-string-face))
      "Face for `consult' framed buffers.")

    (defun my-beframe-buffer-names-sorted (&optional frame)
      "Return the list of buffers from `beframe-buffer-names' sorted by visibility.
With optional argument FRAME, return the list of buffers of FRAME."
      (beframe-buffer-names frame :sort #'beframe-buffer-sort-visibility))

    (defvar beframe-consult-source
      `( :name     "Frame-specific buffers (current frame)"
         :narrow   ?F
         :category buffer
         :face     beframe-buffer
         :history  beframe-history
         :items    ,#'my-beframe-buffer-names-sorted
         :action   ,#'switch-to-buffer
         :state    ,#'consult--buffer-state))

    (add-to-list 'consult-buffer-sources 'beframe-consult-source)))

(provide 'rul-wm)