(in-package :nyxt)
(load "~/quicklisp/setup.lisp")
(ql:quickload 'slynk)
;; (push #p"~/common-lisp/sly/" asdf:*central-registry*)
;; (asdf:load-system :slynk)
;; (slynk:create-server :port 4008)

(load-after-system :slynk (nyxt-init-file "my-slink.lisp"))
;; (load-after-system :slynk "~/.config/nyxt/my-slynk.lisp")

;; Vim-normal mode by default
(define-configuration buffer
  ((default-modes (append '(vi-normal-mode) '(blocker-mode) %slot-default%))))

;; Vim-insert for prompt-buffer (minibuffer)
(define-configuration prompt-buffer
  ((default-modes (append '(vi-insert-mode) %slot-default%))))

;; Keybindings
;; (Note: Override Map will override any other custom keybindings so use a prefix key.)
(define-configuration buffer
  ((override-map (define-key %slot-default%
                   "C-x s" 'nyxt/web-mode:search-buffers
                   "C-x u" 'copy-username
                   "C-x p" 'copy-password))))

;;Message buffer color configuration
(define-configuration window
  ((message-buffer-style
    (str:concat
     %slot-default%
     (cl-css:css
      '((body
         :background-color "black"
         :color "white")))))))

;; Mini-buffer style
(define-configuration prompt-buffer
  ((style (str:concat
           %slot-default%
           (cl-css:css
            '((body
               :background-color "black"
               :color "white")
              ("#prompt-area"
               :background-color "black")
              ;; The area you input text in.
              ("#input"
               :background-color "#EDDDAA")
              (".source-name"
               :color "black"
               :background-color "#125458")
              (".source-content"
               :background-color "black")
              (".source-content th"
               :border "1px solid #125458"
               :background-color "black")
              ;; The currently highlighted option.
              ("#selection"
               :background-color "#125458"
               :color "black")
              (.marked :background-color "#8B3A3A"
                       :font-weight "bold"
                       :color "white")
              (.selected :background-color "black"
                         :color "white")))))))

;; Internal buffer (help, bookmarks, buffers panel)
(define-configuration (internal-buffer panel-buffer)
  ((style
    (str:concat
     %slot-default%
     (cl-css:css
      '((title
         :color "#CD5C5C")
        (body
         :background-color "black"
         :color "lightgray")
        (hr
         :color "lightgray")
        (a
         :color "#125458")
        (.button
         :color "white"
         :background-color "#125458")))))))

;; Link hints in web mode
(define-configuration nyxt/web-mode:web-mode
  ((nyxt/web-mode:highlighted-box-style
    (cl-css:css
     '((".nyxt-hint.nyxt-highlight-hint"
        :background "#125458"))))))

;; Modeline
(define-configuration status-buffer
  ((style (str:concat
           %slot-default%
           (cl-css:css
            ;; Arrows on the left.
            '(("#controls"
               :border-top "1px solid white"
               :background-color "#125458")
              ;; To the right of the arrows.
              ("#url"
               :background-color "black"
               :color "white"
               :border-top "1px solid white")
              ;; Far to the right.
              ("#modes"
               :background-color "black"
               :border-top "1px solid white")
              ;; The center segment.
              ("#tabs"
               :background-color "#125458"
               :color "black"
               :border-top "1px solid white")))))))

;; Overriding dark theme colors
(define-configuration nyxt/style-mode:dark-mode
  ((style #.(cl-css:css
             '((*
                :background-color "black !important"
                :background-image "none !important"
                :color "white")
               (a
                :background-color "black !important"
                :background-image "none !important"
                :color "#556B2F !important"))))))

(define-configuration password:keepassxc-interface
  ((password:password-file "/home/opal/.config/keepassxc/.kdbx-store/opal.kdbx")))
   
(define-configuration buffer
  ((password-interface (make-instance 'password:user-keepassxc-interface))))

(define-command set-url (&key (prefill-current-url-p t))
  "Set the URL for the current buffer, completing with history."
  (let ((history (set-url-history *browser*))
        (actions (list (make-command buffer-load* (suggestion-values)
                                     "Load first selected URL in current buffer and the rest in new buffer(s)."
                                     (mapc (lambda (suggestion) (make-buffer :url (url suggestion))) (rest suggestion-values))
                                     (buffer-load (url (first suggestion-values))))
                       (make-command new-buffer-load (suggestion-values)
                                     "Load URL(s) in new buffer(s)."
                                     (mapc (lambda (suggestion) (make-buffer :url (url suggestion))) (rest suggestion-values))
                                     (make-buffer-focus :url (url (first suggestion-values)))))))
    (pushnew-url-history history (url (current-buffer)))
    (prompt
     :prompt "Open URL"
     :input (if prefill-current-url-p
                (render-url (url (current-buffer))) "")
     :history history
     :sources (list (make-instance 'user-new-url-or-search-source :actions actions)
                    (make-instance 'bookmark-source :actions actions)
                    (make-instance 'user-global-history-source :actions actions)
                    (make-instance 'search-engine-url-source :actions actions)))))

(define-command set-url-new-buffer (&key (prefill-current-url-p t))
  "Prompt for a URL and set it in a new focused buffer."
  (let ((history (set-url-history *browser*))
        (actions (list (make-command new-buffer-load (suggestion-values)
                                     "Load URL(s) in new buffer(s)"
                                     (mapc (lambda (suggestion) (make-buffer :url (url suggestion)))
                                           (rest suggestion-values))
                                     (make-buffer-focus :url (url (first suggestion-values)))))))
    (pushnew-url-history history (url (current-buffer)))
    (prompt
     :prompt "Open URL in new buffer"
     :input (if prefill-current-url-p
                (render-url (url (current-buffer))) "")
     :history history
     :sources (list (make-instance 'user-new-url-or-search-source :actions actions)
                    (make-instance 'bookmark-source :actions actions)
                    (make-instance 'user-global-history-source :actions actions)
                    (make-instance 'search-engine-url-source :actions actions)))))

;; I would like to implement redirection, or some extension to handle it for me.
;; todo: Redirect reddit to teddit
;; (defun old-reddit-handler (request-data)
;;   (let ((url (url request-data)))
;;     (setf (url request-data)
;;           (if (search "reddit.com" (quri:uri-host url))
;;               (progn
;;                 (setf (quri:uri-host url) "old.reddit.com")
;;                 (log:info "Switching to old Reddit: ~s" (render-url url))
;;                 url)
;;               url)))
;;   request-data)

;; (define-configuration web-buffer
;;   ((request-resource-hook
;;     (hooks:add-hook %slot-default% (make-handler-resource #'old-reddit-handler)))))
;; (See url-dispatching-handler for a simpler way to achieve the same result.)

(defun nyxt-init-file (&optional subpath)
  "Return SUBPATH relative to `*init-file-path*'.
Return nil if `*init-file-path*' is nil.

Example:
If we want to load a define-command procedure that lives in ~/path/to/nyxt/config/dir/my-slink.lisp
(load-after-system :slynk (nyxt-init-file \"my-slink.lisp\"))"
  (if subpath
      (uiop:subpathname* (uiop:pathname-directory-pathname
                          (expand-path *init-file-path*))
                         subpath)
      (expand-path *init-file-path*)))
