;; Gleam/theme.jl

(require 'gradient)

(defgroup gradient "Gleam Customization"
  :group appearance)

(defcustom gradient:gradient-type 'diagonal
  "Direction of gradient in `gradient' frame style."
  :type symbol
  :options (horizontal vertical diagonal)
  :group (appearance gradient)
  :after-set after-setting-frame-option)

(defcustom gradient:normal-from-color (get-color "#dedede")
  "`From' color of inactive frames in `gradient' frame style."
  :type color
  :group (appearance gradient)
  :after-set after-setting-frame-option)

(defcustom gradient:normal-to-color (get-color "#9e9e9e")
  "`To' color of inactive frames in `gradient' frame style."
  :type color
  :group (appearance gradient)
  :after-set after-setting-frame-option)

(defcustom gradient:active-from-color (get-color "#c8c3de")
  "`From' color of active frames in `gradient' frame style."
  :type color
  :group (appearance gradient)
  :after-set after-setting-frame-option)

(defcustom gradient:active-to-color (get-color "#736c8c")
  "`To' color of active frames in `gradient' frame style."
  :type color
  :group (appearance gradient)
  :after-set after-setting-frame-option)

(defcustom gradient:save-memory t
  "Use less memory when creating gradients, possibly affecting quality."
  :type boolean
  :group (appearance gradient)
  :after-set after-setting-frame-option)

;; this is stuff that i've added to try to give more
;; configuration options. -rowan

(defcustom title-alignment 'center
  "Alignment of window title."
  :type symbol
  :options (left center right)
  :group (appearance gradient)
  :after-set after-setting-frame-option)

(defcustom normal-font-color (get-color "#333333")
  "Color of unfocused text."
  :type color
  :group (appearance gradient)
  :after-set after-setting-frame-option)

(defcustom active-font-color (get-color "#000000")
  "Color of focused text."
  :type color
  :group (appearance gradient)
  :after-set after-setting-frame-option)

;(defcustom resize-with-corner t
;  "Use corner to resize window, instead of borders."
;  :type boolean
;  :group (appearance gradient)
;  :after-set after-setting-frame-option)

(defcustom resize-type 'sunk
  "Type of image used for the bottom right corner."
  :type symbol
  :options (sunk cutoff plain off)
  :group (appearance gradient)
  :after-set after-setting-frame-option)

(let*
    ((render-bg (lambda (img state)
		  (apply (cond ((eq gradient:gradient-type 'diagonal)
				draw-diagonal-gradient)
			       ((eq gradient:gradient-type 'horizontal)
				draw-horizontal-gradient)
			       ((eq gradient:gradient-type 'vertical)
				draw-vertical-gradient))
			 img (if state
				 (list gradient:active-from-color
				       gradient:active-to-color)
			         (list gradient:normal-from-color
				       gradient:normal-to-color)))
		  (when (> (cdr (image-dimensions img)) 4)
		    (bevel-image img 1 (not (eq state 'clicked))))
		  (set-image-border img 1 1 1 1)))

     (scale (lambda () (if gradient:save-memory 2 1)))

     ;; functions to control text
     (align-text (lambda () (cond ((eq title-alignment 'left) '6)
                                  ((eq title-alignment 'center) 'center)
                                  ((eq title-alignment 'right) '-6))))

     (color-text (lambda () (list normal-font-color active-font-color)))

     ;; buttons
     (maximize (list (make-image "buttons/block_off.png") (make-image "buttons/block.png")
                     nil (make-image "buttons/block_in.png")))
     (shade (list (make-image "buttons/top_off.png") (make-image "buttons/top.png")
		     nil (make-image "buttons/top_in.png")))
     (minimize (list (make-image "buttons/dot_off.png") (make-image "buttons/dot.png")
                     nil (make-image "buttons/dot_in.png")))
     (close (list (make-image "buttons/box_off.png") (make-image "buttons/box.png")
		  nil (make-image "buttons/box_in.png")))

     ;; borders
     (border-top (make-image "border_top.png"))
     (border-topleft (make-image "border_topleft.png"))
     (border-topright (make-image "border_topright.png"))
     (border-left (make-image "border_left.png"))
     (border-right (make-image "border_right.png"))
     (border-bottom (make-image "border_bottom.png"))
     (border-bottomleft (make-image "border_bottomleft.png"))
     (border-bottomright (make-image "border_bottomright.png"))
     (border-shadeleft (make-image "border_left_shade.png"))
     (border-shaderight (make-image "border_right_shade.png"))

     ;; resize
     ;(handle (make-image "resize_handle.png"))
     (resize-sunk (make-image "resize_sunk.png"))
     (resize-cutoff (make-image "resize_cutoff.png"))
     (resize-normal (make-image "resize_normal.png"))
     (resize-off (make-image "buttons/clear.png"))

     (select-resize (lambda () (cond ((eq resize-type 'sunk) resize-sunk)
                                     ((eq resize-type 'cutoff) resize-cutoff)
                                     ((eq resize-type 'plain) resize-normal)
                                     ((eq resize-type 'off) resize-off))))

     ;(set-resize-method (lambda () (if resize-with-corner 'title 'left-border)))

     ;; title
     (title-right (make-image "title_right.png"))
     (title-shade-right (make-image "title_shade_right.png"))
     (title-trough (make-image "title_trough.png"))
     (title-shade-trough (make-image "title_shade_trough.png"))

     ;; frame definitions
     (frame `(((renderer . ,render-bg)
	       (render-scale . ,scale)
               (foreground . ,color-text)
               (text . ,window-name)
               (x-justify . ,align-text)
               (y-justify . center)
	       (left-edge . -5)
	       (right-edge . 30)
	       (top-edge . -20)
	       (height . 21)
	       (class . title))
	      ((background . "black")
	       (left-edge . -5) 
	       (right-edge . 30)
	       (top-edge . -21)
	       (height . 1))
              ((background . "black")
               (left-edge . -6)
               (top-edge . -21)
               (width . 1)
               (height . 22))
              ((background . ,title-right)
               (right-edge . -6)
               (top-edge . -21)
               (class . title))
              ;; if you're adding buttons ...
              ;; this is where they sit.
              ;; so make sure to resize it appropriately
              ;; and also, adjust the width of stuff
              ;; above so it doesn't overlap
              ;; you can use about 15 pixels per button
              ((background . ,title-trough)
               (right-edge . 0)
               (top-edge . -21)
               (width . 30)
               (class . title))
              ((background . ,close)
               (left-edge . -2)
               (top-edge . -16)
               (class . close-button)
               (removable . t))
              ((background . ,minimize)
               (right-edge . 14)
               (top-edge . -16)
               (class . iconify-button)
               (removable . t))
	      ((background . ,maximize)
	       (right-edge . -1)
	       (top-edge . -16)
	       (class . maximize-button)
	       (removable . t))
              ((background . ,border-left)
               (left-edge . -6)
               (top-edge . 1)
               (bottom-edge . 0)
               ;(class . ,set-resize-method))
               (class . title))
              ((background . ,border-right)
               (right-edge . -6)
               (top-edge . 0)
               (bottom-edge . 0)
               (class . title))
              ((background . ,border-bottom)
               (left-edge . 0)
               (right-edge . 0)
               (bottom-edge . -6)
               (class . title))
              ((background . ,border-bottomleft)
               (left-edge . -6)
               (bottom-edge . -6)
               (class . title))
              ;; eventually, i want to be able
              ;; to configure this so you can
              ;; choose between styles of resize
              ;; decorations ...
              ((background . ,border-bottomright)
               (right-edge . -6)
               (bottom-edge . -6)
               (class . bottom-right-corner))
              ;((background . ,handle)
               ;(right-edge . 3)
               ;(bottom-edge . -9)
               ;(class . resize-button))
              ((background . ,select-resize)
               (right-edge . -7)
               (bottom-edge . -7)
               (class . resize-button))
              ))

     (shaped-frame `(((renderer . ,render-bg)
		      (render-scale . ,scale)
		      (foreground . ,color-text)
		      (text . ,window-name)
		      (x-justify . ,align-text)
		      (y-justify . center)
		      (left-edge . -5)
		      (right-edge . 30)
		      (top-edge . -20)
		      (height . 21)
		      (class . title))
		     ((background . "black")
		      (left-edge . -5)
		      (right-edge . 30)
		      (top-edge . -21)
		      (height . 1))
		     ((background . "black")
		      (left-edge . -6)
		      (width . 1)
		      (top-edge . -21)
		      (height . 23))
                     ((background . "black")
                      (left-edge . -5)
                      (right-edge . 30)
                      (top-edge . 1)
                      (height . 1))
                     ((background . ,title-shade-right)
                      (right-edge . -6)
                      (top-edge . -21)
                      (class . title))
                    ((background . ,title-shade-trough)
                     (right-edge . 0)
                     (top-edge . -21)
                     (width . 30)
                     (class . title))
                     ((background . ,close)
                      (left-edge . -2)
                      (top-edge . -16)
                      (class . close-button)
                      (removable . t))
                     ((background . ,minimize)
                      (right-edge . 14)
                      (top-edge . -16)
                      (class . iconify-button)
                      (removable . t))
		     ((background . ,maximize)
		      (right-edge . -1)
		      (top-edge . -16)
		      (class . maximize-button)
		      (removable . t))
                     ))

     (transient-frame `(((background . ,border-top)
			 (left-edge . 0)
			 (right-edge . 6)
			 (top-edge . -6)
			 (class . title))
			((background . ,border-topleft)
			 (left-edge . -6)
			 (top-edge . -6)
                         (class . title))
                        ((background . ,border-shaderight)
                         (right-edge . 0)
                         (top-edge . -6)
                         (class . title))
			((background . ,border-left)
			 (left-edge . -6)
			 (top-edge . 0)
			 (bottom-edge . 0)
                         (class . title))
                        ((background . "black")
                         (right-edge . -6)
                         (top-edge . -6)
                         (width . 6)
                         (height . 1))
                        ((renderer . ,render-bg)
                         (render-scale . ,scale)
                         (right-edge . -5)
                         (top-edge . -5)
                         (bottom-edge . 0)
                         (width . 5)
                         (class . title))
                        ((background . "black")
                         (right-edge . -6)
                         (top-edge . -5)
                         (bottom-edge . 0)
                         (width . 1))
                        ((background . ,border-bottom)
                         (left-edge . 0)
                         (right-edge . 0)
                         (bottom-edge . -6)
                         (class . title))
                        ((background . ,border-bottomleft)
                         (left-edge . -6)
                         (bottom-edge . -6)
                         (class . title))
			((background . ,border-bottomright)
			 (right-edge . -6)
			 (bottom-edge . -6)
			 (class . title))))

     (shaped-transient-frame `(((background . ,border-shadeleft)
                                (left-edge . -6)
                                (top-edge . -6)
                                (class . title))
                               ((background . ,border-shaderight)
                                (right-edge . 24)
                                (top-edge . -6)
                                (class . title))
                               ((background . "black")
                                (right-edge . -6)
                                (top-edge . -6)
                                (width . 30)
                                (height . 1))
                               ((renderer . ,render-bg)
                                (render-scale . ,scale)
                                (right-edge . -5)
                                (top-edge . -5)
                                (width . 30)
                                (height . 5)
                                (class . title))
                               ((background . "black")
                                (right-edge . -6)
                                (top-edge . -6)
                                (height . 7)
                                (width . 1))
                               ((background . "black")
                                (left-edge . -6)
                                (right-edge . -6)
                                (top-edge . 0)
                                (height . 1))
			       ((background . ,border-top)
                                (left-edge . 0)
				(right-edge . 30)
				(top-edge . -6)
				(class . title)))))

  (def-frame-class shade-button '((cursor . sb_up_arrow))
    (bind-keys shade-button-keymap "Button1-Off" 'toggle-window-shaded))

  (def-frame-class resize-button '((cursor . sizing))
    (bind-keys resize-button-keymap "Button1-Move" 'resize-window-interactively)
    (bind-keys resize-button-keymap "Button1-Click2" 'maximize-window-toggle))

  (add-frame-style 'Gleam
		   (lambda (w type)
		     (cond ((eq type 'shaped)
			    shaped-frame)
                           ((eq type 'shaded)
                            shaped-frame)
			   ((eq type 'transient)
			    transient-frame)
			   ((eq type 'shaped-transient)
			    shaped-transient-frame)
                           ((eq type 'shaded-transient)
                            shaped-transient-frame)
			   ((eq type 'unframed)
			    nil-frame)
			   (t
			    frame)))))
