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

;;; x11 utils
(defun jao-xdotool (arg-or-wait &rest args)
  (apply 'jao-shell-exec*
         (if (stringp arg-or-wait) "xdotool" arg-or-wait)
         (if (stringp arg-or-wait) arg-or-wait "xdotool")
         args))

(defsubst jao-xdotool-string (&rest args)
  (apply 'jao-shell-string "xdotool" args))

(defsubst jao-x11-focused-id () (jao-xdotool-string "getwindowfocus"))

(defsubst jao-x11-window-name (&optional wid)
  (jao-xdotool-string "getwindowname" (or wid (jao-x11-focused-id))))

(defsubst jao-x11-search-window (title)
  (jao-xdotool-string "search" "--name" title))

(defsubst jao-x11-goto-ws (n) (jao-xdotool t "set_desktop" (format "%s" n)))

;;; exwm
(defun jao-exwm-enable ()
  (require 'jao-custom-exwm)
  (setq jao-exwm-enabled t)
  (display-time-mode -1)
  (jao-ednc-setup 95)
  (x-change-window-property "_XMONAD_TRAYPAD" "" nil nil nil nil 0)
  (jao-mode-line-add-to-minibuffer-left 90)
  (jao-xmobar-restart)
  (jao-trisect t))

;;; xmonad
(defun jao-xmonad-enable ()
  (setq jao-pdf-open-in-emacs (display-graphic-p))
  (setq jao-mode-line-in-minibuffer nil)
  (display-battery-mode -1)
  (jao-trisect)
  (message "Welcome to xmonad"))

(when jao-xmonad-enabled
  (add-hook 'after-init-hook #'jao-xmonad-enable))

;;; wayland

(use-package jao-wayland :demand t)

(defun jao-wayland-enable ()
  (interactive)
  (defalias 'x-change-window-property #'ignore)
  (jao-trisect)
  (message "Welcome to wayland"))

(defun jao-river-enable ()
  (jao-wayland-enable)
  (when (jao-shell-running-p "i3bar-river")
    (jao-tracking-set-log ""))
  (message "Welcome to river"))

(when jao-river-enabled
  (add-hook 'after-init-hook #'jao-river-enable t))

(when jao-sway-enabled
  (add-hook 'after-init-hook #'jao-wayland-enable t))

;;; wallpaper
(defvar jao-wallpaper-dir "~/.wallpapers/")

(defvar jao-wallpaper-random-candidates
  '("wallpaper.jpg" "wallpaper2.jpg"))

(defvar jao-wallpaper-random-candidates-light
  '("wallpaper.jpg" "wallpaper2.jpg"))

(defvar jao-wallpaper-random-wake t
  "Set to t for getting a new wallpaper on awaking from sleep")

(defun jao-set-wallpaper (&optional path)
  (interactive)
  (let ((current (format "~/.wallpaper.%s" (jao-colors-scheme))))
    (when-let* ((f (or (and path (expand-file-name path))
                       (read-file-name "Image: "
                                       jao-wallpaper-dir
                                       (file-symlink-p current)
                                       t))))
      (make-symbolic-link f current t)
      (cond (jao-river-enabled (jao-river-set-wallpaper f))
            (jao-sway-enabled (jao-sway-set-wallpaper f))
            (t (shell-command-to-string (format "xwallpaper --zoom %s" f)))))))

(defun jao-set-random-wallpaper ()
  (interactive)
  (when (or (called-interactively-p 'interactive)
            jao-wallpaper-random-wake)
    (let* ((ws (if (jao-colors-scheme-dark-p)
                   jao-wallpaper-random-candidates
                 jao-wallpaper-random-candidates-light))
           (f (seq-random-elt ws)))
      (jao-set-wallpaper (expand-file-name f jao-wallpaper-dir))
      (message "%s" f))))

(add-to-list 'jao-sleep-awake-functions #'jao-set-random-wallpaper)

;;; screensaver and lock
(defun jao-screensaver-enabled ()
  (string= (jao-shell-string "xdg-screensaver status") "enabled"))

(defvar jao-screensaver--wid nil)
(defun jao-screensaver-toggle ()
  (interactive)
  (if (jao-screensaver-enabled)
      (let ((wid (jao-x11-focused-id)))
        (setq jao-screensaver--wid wid)
        (jao-shell-exec* t "xdg-screensaver" "suspend" wid))
    (jao-shell-exec* t "xdg-screensaver" "resume" jao-screensaver--wid)
    (setq jao-screensaver--wid nil))
  (jao-notify (format "Screensaver %s"
                      (jao-shell-string "xdg-screensaver status"))))

(jao-shell-def-exec jao-xlock-screen "xdg-screensaver" "activate")
(jao-shell-def-exec jao-suspend "sudo" "systemctl" "suspend")
(jao-shell-def-exec jao-poweroff "sudo" "systemctl" "poweroff")

(defun jao-lock-screen ()
  (interactive)
  (if jao-wayland-enabled
      (shell-command "swaylock -i ~/.lockimage")
    (jao-xlock-screen)))

(transient-define-prefix jao-transient-sleep ()
  ["Sleep"
   ("l" "lock screen" jao-lock-screen)
   ("z" "sleep" jao-suspend)
   ("u" (lambda ()
          (if (jao-screensaver-enabled) "suspend screensaver" "resume screensaver"))
    jao-screensaver-toggle)
   ("poof" "power-off" jao-poweroff)])

;;; X clipboard
(setq select-enable-clipboard t
      select-enable-primary t
      selection-timeout 100
      xterm-select-active-regions t)

(use-package xclip
  :ensure t
  :init (setq xclip-method (if jao-wayland-enabled 'wl-copy 'xclip)))

(unless (display-graphic-p) (xclip-mode 1))

;;; pop-up frames
(defun jao-open-in-x-frame (&optional width height)
  (interactive)
  (make-frame `((window-system . x)
                (name . "emacs popup")
                (width . ,(or width (window-width)))
                (height . ,(or height (window-height)))))
  (define-key (current-local-map) "q" #'delete-frame))

;;; xmobar
(defun jao-xmobar-kill ()
  (interactive)
  (shell-command "killall xmobar-single"))

(defun jao-xmobar-restart ()
  (interactive)
  (jao-xmobar-kill)
  (start-process "" nil "xmobar-single" "-d"))

(use-package tab-bar
  :init (setq tab-bar-close-button-show nil
              tab-bar-show (> emacs-major-version 28)
              tab-bar-format ()))

(use-package xmobar
  :init (setq  xmobar-tab-bar t
               xmobar-tab-split "*"
               xmobar-tab-bar-format
               (if window-system
                   '(xmobar-left-string
                     tab-bar-format-align-right
                     xmobar-right-string)
                 '(xmobar-left-string
                   xmobar-elastic-space
                   xmobar-right-string))
               xmobar-command
               (if window-system '("xmobar-emacs" "-TAnsi") "xmobar-emacs")))


;;; - provide
(provide 'jao-custom-x11)
