;; FinalStep/theme.jl

;; Copyright (C) 2001 Michele Campeotto <micampe@f2s.com>

;; FinalStep has been inspired by Sanity by Jason F. McBrayer and is intended
;; to be a Good Theme (tm).
;;
;; It has a Step-ish look-and-feel and is meant to replace all my previous
;; Step* themes.


;; This code comes from many themes around www.themes.org, but mainly from
;; Sanity and Klarth.
;; Thanks to Jason for the help with 


;; This theme is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public Licence as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;;
;; It is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public Licence for more details.
;;
;; You should have received a copy of the GNU General Public Licence
;; along with sawfish; see the file COPYING.  If not, write to
;; the Free Software Foundation, 675 Mass Ave, Cambridge (Our
;; Fair City), MA 02139, USA.

(require 'gradient)
(require 'sawfish.wm.util.recolor-image)

;; --- Frame preferences ------------------

(defgroup FinalStep-frame "FinalStep"
    :group appearance)

(defcustom FinalStep:the-font (get-font "-*-helvetica-bold-r-normal-*-12-*-*-*-*-*-*")
  "Titlebar font: \\w"
  :type font
  :group (appearance FinalStep-frame)
  :user-level intermediate
  :after-set (lambda () (option-changed)))

(defcustom FinalStep:button-layout 'antiplatinum
    "Titlebar buttons layout: \\w"
    :type (choice
            (default "Platinum+")
            (antiplatinum "AntiPlatinum+")
            (platinum "Mac OS 9")
            (next "NeXTStep")
            (crux "Crux")
            (twm "TWM")
            (win "MS Windows"))
    :group (appearance FinalStep-frame)
    :user-level intermediate
    :after-set (lambda () (option-changed)))

(defcustom FinalStep:titlebar-padding 9
    "Title text padding: \\w"
    :group (appearance FinalStep-frame)
    :type number
    :user-level expert
    :after-set (lambda () (option-changed)))

(defcustom FinalStep:resizebar-height 8
    "Resizebar size: \\w"
    :group (appearance FinalStep-frame)
    :type number
    :user-level expert
    :after-set (lambda () (option-changed)))

(defcustom FinalStep:flat-buttons t
    "Use flat titlebar buttons"
    :group (appearance FinalStep-frame)
    :type boolean
    :user-level beginner
    :after-set (lambda () (option-changed)))

(defcustom FinalStep:title-active-color (get-color "#ffffffffffff")
    "Color of the active window title"
    :group (appearance FinalStep-frame)
    :type color
    :user-level beginner
    :after-set (lambda () (option-changed)))

(defcustom FinalStep:title-inactive-color (get-color "#404040404040")
    "Color of inactive windows titles"
    :group (appearance FinalStep-frame)
    :type color
    :user-level beginner
    :after-set (lambda () (option-changed)))

(defgroup FinalStep-titlebar "Titlebar colors"
    :group (appearance FinalStep-frame))

(defcustom FinalStep:titlebar-gradient 'vertical
    "Gradient direction"
    :type symbol
    :options (none horizontal vertical diagonal)
    :group (appearance FinalStep-frame FinalStep-titlebar)
    :user-level beginner
    :after-set (lambda () (option-changed)))

(defcustom FinalStep:titlebar-active-color (get-color "#3d70785191ea")
    "Start color of the active window titlebar"
    :type color
    :group (appearance FinalStep-frame FinalStep-titlebar)
    :user-level beginner
    :after-set (lambda () (option-changed)))

(defcustom FinalStep:titlebar-active-color-end (get-color "#2e895ac46e14")
    "End color of the active window titlebar"
    :type color
    :group (appearance FinalStep-frame FinalStep-titlebar)
    :user-level beginner
    :after-set (lambda () (option-changed)))

(defcustom FinalStep:titlebar-inactive-color (get-color "#bfbfbfbfbfbf")
    "Start color of inactive windows titlebars"
    :type color
    :group (appearance FinalStep-frame FinalStep-titlebar)
    :user-level beginner
    :after-set (lambda () (option-changed)))

(defcustom FinalStep:titlebar-inactive-color-end (get-color "#7fff7fff7fff")
    "End color of inactive windows titlebars"
    :type color
    :group (appearance FinalStep-frame FinalStep-titlebar)
    :user-level beginner
    :after-set (lambda () (option-changed)))

(defgroup FinalStep-resizebar "Resizebar colors"
    :group (appearance FinalStep-frame))

(defcustom FinalStep:resizebar-gradient 'vertical
    "Gradient direction"
    :type symbol
    :options (none horizontal vertical diagonal)
    :group (appearance FinalStep-frame FinalStep-resizebar)
    :user-level beginner
    :after-set (lambda () (option-changed)))

(defcustom FinalStep:resizebar-active-color (get-color "#bfbfbfbfbfbf")
    "Start color of the active window resizebar"
    :type color
    :group (appearance FinalStep-frame FinalStep-resizebar)
    :user-level beginner
    :after-set (lambda () (option-changed)))

(defcustom FinalStep:resizebar-active-color-end (get-color "#7fff7fff7fff")
    "End color of the active window resizebar"
    :type color
    :group (appearance FinalStep-frame FinalStep-resizebar)
    :user-level beginner
    :after-set (lambda () (option-changed)))

(defcustom FinalStep:resizebar-inactive-color (get-color "#bfbfbfbfbfbf")
    "Start color of inactive windows resizebars"
    :type color
    :group (appearance FinalStep-frame FinalStep-resizebar)
    :user-level beginner
    :after-set (lambda () (option-changed)))

(defcustom FinalStep:resizebar-inactive-color-end (get-color "#7fff7fff7fff")
    "End color of inactive windows resizebars"
    :type color
    :group (appearance FinalStep-frame FinalStep-resizebar)
    :user-level beginner
    :after-set (lambda () (option-changed)))

;; --- Buttons ----------------------------

(define close-images
  (list
    (make-image "close-normal.png")
    (make-image "close-normal.png")
    (make-image "close-normal.png")
    (make-image "close-clicked.png")))

(define close-flat-images
  (list
    (make-image "close-flat.png")
    (make-image "close-flat.png")
    (make-image "close-flat.png")
    (make-image "close-flat.png")))

(define minimize-images
  (list
    (make-image "minimize-normal.png")
    (make-image "minimize-normal.png")
    (make-image "minimize-normal.png")
    (make-image "minimize-clicked.png")))

(define minimize-flat-images
  (list
    (make-image "minimize-flat.png")
    (make-image "minimize-flat.png")
    (make-image "minimize-flat.png")
    (make-image "minimize-flat.png")))

(define maximize-images
  (list
    (make-image "maximize-normal.png")
    (make-image "maximize-normal.png")
    (make-image "maximize-normal.png")
    (make-image "maximize-clicked.png")))

(define maximize-flat-images
  (list
    (make-image "maximize-flat.png")
    (make-image "maximize-flat.png")
    (make-image "maximize-flat.png")
    (make-image "maximize-flat.png")))

(define unmaximize-images
  (list
    (make-image "unmaximize-normal.png")
    (make-image "unmaximize-normal.png")
    (make-image "unmaximize-normal.png")
    (make-image "unmaximize-clicked.png")))

(define unmaximize-flat-images
  (list
    (make-image "unmaximize-flat.png")
    (make-image "unmaximize-flat.png")
    (make-image "unmaximize-flat.png")
    (make-image "unmaximize-flat.png")))

(define shade-images
  (list
    (make-image "shade-normal.png")
    (make-image "shade-normal.png")
    (make-image "shade-normal.png")
    (make-image "shade-clicked.png")))

(define shade-flat-images
  (list
    (make-image "shade-flat.png")
    (make-image "shade-flat.png")
    (make-image "shade-flat.png")
    (make-image "shade-flat.png")))

(define unshade-images
  (list
    (make-image "unshade-normal.png")
    (make-image "unshade-normal.png")
    (make-image "unshade-normal.png")
    (make-image "unshade-clicked.png")))

(define unshade-flat-images
  (list
    (make-image "unshade-flat.png")
    (make-image "unshade-flat.png")
    (make-image "unshade-flat.png")
    (make-image "unshade-flat.png")))

(define resize-images
  (list
    (make-image "resize-normal.png")
    (make-image "resize-normal.png")
    (make-image "resize-normal.png")
    (make-image "resize-clicked.png")))

(define resize-flat-images
  (list
    (make-image "resize-flat.png")
    (make-image "resize-flat.png")
    (make-image "resize-flat.png")
    (make-image "resize-flat.png")))

(define menu-images
  (list
    (make-image "menu-normal.png")
    (make-image "menu-normal.png")
    (make-image "menu-normal.png")
    (make-image "menu-clicked.png")))

(define menu-flat-images
  (list
    (make-image "menu-flat.png")
    (make-image "menu-flat.png")
    (make-image "menu-flat.png")
    (make-image "menu-flat.png")))

;; --- Utilities --------------------------

(define (title-font)
  (if (fontp FinalStep:the-font)
      FinalStep:the-font
    default-font))

;    (get-font "-*-helvetica-bold-r-normal-*-12-*-*-*-*-*-*"))
;    default-font)

(define (title-colors)
  (list FinalStep:title-inactive-color
        FinalStep:title-active-color))

(define border-color
  (get-color "black"))

(define (color-active)
  FinalStep:title-active-color)

(define (color-inactive)
  FinalStep:title-inactive-color)

(define (titlebar-padding)
  FinalStep:titlebar-padding)

(define (titlebar-height) 
  (max 16 (+ (font-height (title-font)) (titlebar-padding))))

(define (resizebar-height)
  FinalStep:resizebar-height)

(define (titlebar-right-edge)
    (cond
      ((eq FinalStep:button-layout 'default)
        (* (- (titlebar-height) 2) 2))
      ((eq FinalStep:button-layout 'antiplatinum)
        (- (titlebar-height) 2))
      ((eq FinalStep:button-layout 'platinum)
        (* (- (titlebar-height) 2) 2))
      ((eq FinalStep:button-layout 'next)
        (- (titlebar-height) 2))
      ((eq FinalStep:button-layout 'crux)
        (* (- (titlebar-height) 2) 3))
      ((eq FinalStep:button-layout 'twm)
        (- (titlebar-height) 2))
      ((eq FinalStep:button-layout 'win)
        (* (- (titlebar-height) 2) 3))
    ))

(define (titlebar-left-edge)
    (cond
      ((eq FinalStep:button-layout 'default)
        (- (titlebar-height) 2))
      ((eq FinalStep:button-layout 'antiplatinum)
        (* (- (titlebar-height) 2) 2))
      ((eq FinalStep:button-layout 'platinum)
        (- (titlebar-height) 2))
      ((eq FinalStep:button-layout 'next)
        (- (titlebar-height) 2))
      ((eq FinalStep:button-layout 'crux)
        (- (titlebar-height) 2))
      ((eq FinalStep:button-layout 'twm)
        (- (titlebar-height) 2))
      ((eq FinalStep:button-layout 'win)
        (- (titlebar-height) 2))
    ))

(define (transient-titlebar-right-edge)
    (cond
      ((eq FinalStep:button-layout 'default)
        0)
      ((eq FinalStep:button-layout 'antiplatinum)
        (- (titlebar-height) 2))
      ((eq FinalStep:button-layout 'platinum)
        0)
      ((eq FinalStep:button-layout 'next)
        (- (titlebar-height) 2))
      ((eq FinalStep:button-layout 'crux)
        0)
      ((eq FinalStep:button-layout 'twm)
        0)
      ((eq FinalStep:button-layout 'win)
        (- (titlebar-height) 2))
    ))

(define (transient-titlebar-left-edge)
    (cond
      ((eq FinalStep:button-layout 'default)
        (- (titlebar-height) 2))
      ((eq FinalStep:button-layout 'antiplatinum)
        0)
      ((eq FinalStep:button-layout 'platinum)
        (- (titlebar-height) 2))
      ((eq FinalStep:button-layout 'next)
        0)
      ((eq FinalStep:button-layout 'crux)
        (- (titlebar-height) 2))
      ((eq FinalStep:button-layout 'twm)
        (- (titlebar-height) 2))
      ((eq FinalStep:button-layout 'win)
        (- (titlebar-height) 2))
    ))

(define (titlebar-gradient)
  (case FinalStep:titlebar-gradient
    ('horizontal draw-horizontal-gradient)
    ('vertical draw-vertical-gradient)
    ('diagonal draw-diagonal-gradient)))

(define (render-titlebar img state)
  (bevel-image
    (if (eq FinalStep:titlebar-gradient 'none)
      (clear-image img
        (if (or (eq state 'focused) (eq state 'highlighted) (eq state 'clicked))
          FinalStep:titlebar-active-color
          FinalStep:titlebar-inactive-color))
      (apply (titlebar-gradient) img
        (if (or (eq state 'focused) (eq state 'highlighted) (eq state 'clicked))
            (list
              FinalStep:titlebar-active-color
              FinalStep:titlebar-active-color-end)
            (list
              FinalStep:titlebar-inactive-color
              FinalStep:titlebar-inactive-color-end))))
    1 t 50))

(define (resizebar-gradient)
  (case FinalStep:resizebar-gradient
    ('horizontal draw-horizontal-gradient)
    ('vertical draw-vertical-gradient)
    ('diagonal draw-diagonal-gradient)))

(define (render-resizebar img state)
  (bevel-image
    (if (eq FinalStep:resizebar-gradient 'none)
      (clear-image img
        (if (or (eq state 'focused) (eq state 'highlighted) (eq state 'clicked))
          FinalStep:resizebar-active-color
          FinalStep:resizebar-inactive-color))
      (apply (resizebar-gradient) img
        (if (or (eq state 'focused) (eq state 'highlighted) (eq state 'clicked))
            (list
              FinalStep:resizebar-active-color
              FinalStep:resizebar-active-color-end)
            (list
              FinalStep:resizebar-inactive-color
              FinalStep:resizebar-inactive-color-end))))
    1 t 50))

(define (render-button img state)
  (bevel-image
    (if (eq FinalStep:titlebar-gradient 'none)
      (clear-image img
        (if (or (eq state 'focused) (eq state 'highlighted) (eq state 'clicked))
          FinalStep:titlebar-active-color
          FinalStep:titlebar-inactive-color))
      (apply (titlebar-gradient) img
        (if (or (eq state 'focused) (eq state 'highlighted) (eq state 'clicked))
            (list
              FinalStep:titlebar-active-color
              FinalStep:titlebar-active-color-end)
            (list
              FinalStep:titlebar-inactive-color
              FinalStep:titlebar-inactive-color-end))))
    1 t (if (eq state 'clicked) 20 50)))
;    1 (not (eq state 'clicked)) 50))

(define (recolor-active)
  (let (
    (recolorer
      (make-image-recolorer (color-active)
                            #:zero-channel blue-channel
                            #:index-channel green-channel)))
    (mapc (lambda (x) (mapc recolorer (cdr x)))
      (list minimize-flat-images
            maximize-flat-images
            unmaximize-flat-images
            shade-flat-images
            unshade-flat-images
            resize-flat-images
            close-flat-images
            menu-flat-images))))

(define (recolor-inactive)
  (let (
    (recolorer
      (make-image-recolorer (color-inactive)
                            #:zero-channel blue-channel
                            #:index-channel green-channel)))
    (mapc (lambda (x) (recolorer (car x)))
      (list minimize-flat-images
            maximize-flat-images
            unmaximize-flat-images
            shade-flat-images
            unshade-flat-images
            resize-flat-images
            close-flat-images
            menu-flat-images))))

(define (recolor-all)
  (recolor-active)
  (recolor-inactive))

(define (reframe-all)
  (reframe-windows-with-style 'FinalStep))

(define (rebuild-all)
  (rebuild-frames-with-style 'FinalStep))

(define (option-changed)
  (recolor-all)
  (rebuild-all)
  (reframe-all))

;; --- Frame parts ------------------------

(define (titlebar-border) `(
  ((background . ,border-color)
   (left-edge . -1)
   (width . 1)
   (top-edge . ,(- (titlebar-height)))
   (height . ,(titlebar-height)))
  ((background . ,border-color)
   (right-edge . -1)
   (width . 1)
   (top-edge . ,(- (titlebar-height)))
   (height . ,(titlebar-height)))
  ((background . ,border-color)
   (right-edge . -1)
   (left-edge . -1)
   (top-edge . ,(- (titlebar-height)))
   (height . 1))
  ((background . ,border-color)
   (right-edge . -1)
   (left-edge . -1)
   (top-edge . -1)
   (height . 1))
))

(define (titlebar) `(
  ((renderer . ,render-titlebar)
   (foreground . ,title-colors)
   (font . ,title-font)
   (text . ,window-name)
   (x-justify . center)
   (y-justify . center)
   (left-edge . ,(lambda () (if FinalStep:flat-buttons (titlebar-left-edge) 0)))
   (right-edge . ,(lambda () (if FinalStep:flat-buttons (titlebar-right-edge) 0)))
   (top-edge . ,(- (- (titlebar-height) 1)))
   (height . ,(- (titlebar-height) 2))
   (class . title))
))

(define (transient-titlebar) `(
  ((renderer . ,render-titlebar)
   (foreground . ,title-colors)
   (font . ,title-font)
   (text . ,window-name)
   (x-justify . center)
   (y-justify . center)
   (left-edge . ,(lambda ()
                   (if FinalStep:flat-buttons
                       (transient-titlebar-left-edge) 0)))
   (right-edge . ,(lambda ()
                   (if FinalStep:flat-buttons
                        (transient-titlebar-right-edge) 0)))
   (top-edge . ,(- (- (titlebar-height) 1)))
   (height . ,(- (titlebar-height) 2))
   (class . title))
))

(define resizebar `(
  ((renderer . ,render-resizebar)
   (left-edge . 0)
   (width . 30)
   (bottom-edge . ,(lambda () (- (+ (resizebar-height) 1))))
;   (bottom-edge . ,(lambda (w) (if (window-maximized-p w) 0 (- (+ (resizebar-height) 1)))))
   (height . ,(lambda () (resizebar-height)))
;   (height . ,(lambda (w) (if (window-maximized-p w) 0 (resizebar-height))))
   (class . bottom-left-corner))
  ((renderer . ,render-resizebar)
   (left-edge . 30)
   (right-edge . 30)
   (bottom-edge . ,(lambda () (- (+ (resizebar-height) 1))))
   (height . ,(lambda () (resizebar-height)))
   (class . bottom-border))
  ((renderer . ,render-resizebar)
   (right-edge . -1)
   (width . 31)
   (bottom-edge . ,(lambda () (- (+ (resizebar-height) 1))))
   (height . ,(lambda () (resizebar-height)))
   (class . bottom-right-corner))
))

(define resizebar-border `(
  ((background . ,border-color)
   (right-edge . -1)
   (width . 1)
   (bottom-edge . ,(lambda () (- (+ (resizebar-height) 1))))
   (height . ,(lambda () (resizebar-height))))
  ((background . ,border-color)
   (left-edge . -1)
   (right-edge . -1)
   (bottom-edge . ,(lambda () (- (+ (resizebar-height) 1))))
   (height . 1))
  ((background . ,border-color)
   (left-edge . -1)
   (width . 1)
   (bottom-edge . ,(lambda () (- (+ (resizebar-height) 1))))
   (height . ,(lambda () (resizebar-height))))
))

(define window-border `(
  ((background . ,border-color)
   (right-edge . -1)
   (width . 1)
   (top-edge . 0)
   (bottom-edge . -1))
  ((background . ,border-color)
   (left-edge . -1)
   (width . 1)
   (top-edge . 0)
   (bottom-edge . -1))
  ((background . ,border-color)
   (left-edge . -1)
   (right-edge . -1)
   (top-edge . -1)
   (height . 1))
  ((background . ,border-color)
   (left-edge . -1)
   (right-edge . -1)
   (bottom-edge . -1)
   (height . 1))
))

;; --- Buttons -----------------------------

(define (close) `(
  (background . ,close-images)
  (removable . t)
  (width . 14)
  (height . 14)
  (top-edge . ,(- (/ (- (titlebar-height) 13) 2) (titlebar-height)))
  (class . close-button)
))

(define (close-flat) `(
  (renderer . ,render-button)
  (foreground . ,close-flat-images)
  (x-justify . center)
  (y-justify . center)
;  (removable . t)
  (width . ,(- (titlebar-height) 2))
  (height . ,(- (titlebar-height) 2))
  (top-edge . ,(+ (- (titlebar-height)) 1))
  (class . close-button)
))

(define (minimize) `(
  (background . ,minimize-images)
  (removable . t)
  (width . 14)
  (height . 14)
  (top-edge . ,(- (/ (- (titlebar-height) 13) 2) (titlebar-height)))
  (class . iconify-button)
))

(define (minimize-flat) `(
  (renderer . ,render-button)
  (foreground . ,minimize-flat-images)
  (x-justify . center)
  (y-justify . center)
;  (removable . t)
  (width . ,(- (titlebar-height) 2))
  (height . ,(- (titlebar-height) 2))
  (top-edge . ,(+ (- (titlebar-height)) 1))
  (class . iconify-button)
))

(define (maximize) `(
  (background . ,(lambda (w)
    (if (window-maximized-p w)
      unmaximize-images
      maximize-images)))
  (removable . t)
  (width . 14)
  (height . 14)
  (top-edge . ,(- (/ (- (titlebar-height) 13) 2) (titlebar-height)))
  (class . maximize-button)
))

(define (maximize-flat) `(
  (renderer . ,render-button)
  (foreground . ,(lambda (w)
    (if (window-maximized-p w)
      unmaximize-flat-images
      maximize-flat-images)))
  (x-justify . center)
  (y-justify . center)
;  (removable . t)
  (width . ,(- (titlebar-height) 2))
  (height . ,(- (titlebar-height) 2))
  (top-edge . ,(+ (- (titlebar-height)) 1))
  (class . maximize-button)
))

(define (shade) `(
  (background . ,(lambda (w)
    (if (window-get w 'shaded)
      unshade-images
      shade-images)))
  (removable . t)
  (width . 14)
  (height . 14)
  (top-edge . ,(- (/ (- (titlebar-height) 13) 2) (titlebar-height)))
  (class . shade-button)
))

(define (shade-flat) `(
  (renderer . ,render-button)
  (foreground . ,(lambda (w)
    (if (window-get w 'shaded)
      unshade-flat-images
      shade-flat-images)))
  (x-justify . center)
  (y-justify . center)
;  (removable . t)
  (width . ,(- (titlebar-height) 2))
  (height . ,(- (titlebar-height) 2))
  (top-edge . ,(+ (- (titlebar-height)) 1))
  (class . shade-button)
))

(define (resize) `(
  (background . ,resize-images)
  (removable . t)
  (width . 14)
  (height . 14)
  (top-edge . ,(- (/ (- (titlebar-height) 13) 2) (titlebar-height)))
  (class . resize-button)
))

(define (resize-flat) `(
  (renderer . ,render-button)
  (foreground . ,resize-flat-images)
  (x-justify . center)
  (y-justify . center)
;  (removable . t)
  (width . ,(- (titlebar-height) 2))
  (height . ,(- (titlebar-height) 2))
  (top-edge . ,(+ (- (titlebar-height)) 1))
  (class . resize-button)
))

(define (menu) `(
  (background . ,menu-images)
  (removable . t)
  (width . 14)
  (height . 14)
  (top-edge . ,(- (/ (- (titlebar-height) 13) 2) (titlebar-height)))
  (class . menu-button)
))

(define (menu-flat) `(
  (renderer . ,render-button)
  (foreground . ,menu-flat-images)
  (x-justify . center)
  (y-justify . center)
;  (removable . t)
  (width . ,(- (titlebar-height) 2))
  (height . ,(- (titlebar-height) 2))
  (top-edge . ,(+ (- (titlebar-height)) 1))
  (class . menu-button)
))

(define (left-buttons)
  (cond
    ((eq FinalStep:button-layout 'antiplatinum)
      (if FinalStep:flat-buttons
        (list (cons '(left-edge . 0) (minimize-flat))
              (cons `(left-edge . ,(- (titlebar-height) 2)) (maximize-flat)))
        (list (cons '(left-edge . 4) (minimize))
              (cons '(left-edge . 20) (maximize)))))
    ((eq FinalStep:button-layout 'next)
      (if FinalStep:flat-buttons
        (list (cons '(left-edge . 0) (minimize-flat)))
        (list (cons '(left-edge . 4) (minimize)))))
    ((eq FinalStep:button-layout 'twm)
      (if FinalStep:flat-buttons
        (list (cons '(left-edge . 0) (minimize-flat)))
        (list (cons '(left-edge . 4) (minimize)))))
    ((eq FinalStep:button-layout 'win)
      (if FinalStep:flat-buttons
        (list (cons '(left-edge . 0) (menu-flat)))
        (list (cons '(left-edge . 4) (menu)))))
    (t
      (if FinalStep:flat-buttons
        (list (cons '(left-edge . 0) (close-flat)))
        (list (cons '(left-edge . 4) (close)))))
  ))

(define (right-buttons)
  (cond
    ((eq FinalStep:button-layout 'antiplatinum)
      (if FinalStep:flat-buttons
        (list (cons '(right-edge . 0) (close-flat)))
        (list (cons '(right-edge . 4) (close)))))
    ((eq FinalStep:button-layout 'platinum)
      (if FinalStep:flat-buttons
        (list (cons '(right-edge . 0) (shade-flat))
              (cons `(right-edge . ,(- (titlebar-height) 2)) (maximize-flat)))
        (list (cons '(right-edge . 4) (shade))
              (cons '(right-edge . 20) (maximize)))))
    ((eq FinalStep:button-layout 'crux)
      (if FinalStep:flat-buttons
        (list (cons '(right-edge . 0) (shade-flat))
              (cons `(right-edge . ,(- (titlebar-height) 2)) (maximize-flat))
              (cons `(right-edge . ,(* (- (titlebar-height) 2) 2)) (minimize-flat)))
        (list (cons '(right-edge . 4) (shade))
              (cons '(right-edge . 20) (maximize))
              (cons '(right-edge . 36) (minimize)))))
    ((eq FinalStep:button-layout 'next)
      (if FinalStep:flat-buttons
        (list (cons '(right-edge . 0) (close-flat)))
        (list (cons '(right-edge . 4) (close)))))
    ((eq FinalStep:button-layout 'twm)
      (if FinalStep:flat-buttons
        (list (cons '(right-edge . 0) (resize-flat)))
        (list (cons '(right-edge . 4) (resize)))))
    ((eq FinalStep:button-layout 'win)
      (if FinalStep:flat-buttons
        (list (cons '(right-edge . 0) (close-flat))
              (cons `(right-edge . ,(- (titlebar-height) 2)) (maximize-flat))
              (cons `(right-edge . ,(* (- (titlebar-height) 2) 2)) (minimize-flat)))
        (list (cons '(right-edge . 4) (close))
              (cons '(right-edge . 20) (maximize))
              (cons '(right-edge . 36) (minimize)))))
    (t
      (if FinalStep:flat-buttons
        (list (cons '(right-edge . 0) (minimize-flat))
              (cons `(right-edge . ,(- (titlebar-height) 2)) (maximize-flat)))
        (list (cons '(right-edge . 4) (minimize))
              (cons '(right-edge . 20) (maximize)))))
  ))

(define (transient-left-buttons)
  (cond
    ((eq FinalStep:button-layout 'antiplatinum)
      (if FinalStep:flat-buttons ()))
    ((eq FinalStep:button-layout 'next)
      (if FinalStep:flat-buttons ()))
    ((eq FinalStep:button-layout 'twm)
      (if FinalStep:flat-buttons
        (list (cons '(left-edge . 0) (minimize-flat)))
        (list (cons '(left-edge . 4) (minimize)))))
    ((eq FinalStep:button-layout 'win)
      (if FinalStep:flat-buttons
        (list (cons '(left-edge . 0) (menu-flat)))
        (list (cons '(left-edge . 4) (menu)))))
    (t
      (if FinalStep:flat-buttons
        (list (cons '(left-edge . 0) (close-flat)))
        (list (cons '(left-edge . 4) (close)))))
  ))

(define (transient-right-buttons)
  (cond
    ((eq FinalStep:button-layout 'antiplatinum)
      (if FinalStep:flat-buttons
        (list (cons '(right-edge . 0) (close-flat)))
        (list (cons '(right-edge . 4) (close)))))
    ((eq FinalStep:button-layout 'platinum)
      (if FinalStep:flat-buttons ()))
    ((eq FinalStep:button-layout 'crux)
      (if FinalStep:flat-buttons ()))
    ((eq FinalStep:button-layout 'next)
      (if FinalStep:flat-buttons
        (list (cons '(right-edge . 0) (close-flat)))
        (list (cons '(right-edge . 4) (close)))))
    ((eq FinalStep:button-layout 'win)
      (if FinalStep:flat-buttons
        (list (cons '(right-edge . 0) (close-flat)))
        (list (cons '(right-edge . 4) (close)))))
    ((eq FinalStep:button-layout 'twm)
      (if FinalStep:flat-buttons ()))
    (t
      (if FinalStep:flat-buttons ()))
  ))

;; --- Frame definitions -------------------

(define (normal-frame) `(
  ,@(titlebar-border)
  ,@(titlebar)
  ,@(left-buttons)
  ,@(right-buttons)
  ,@window-border
  ,@resizebar
  ,@resizebar-border
))

(define (shaped-normal-frame) `(
  ,@(titlebar-border)
  ,@(titlebar)
  ,@(left-buttons)
  ,@(right-buttons)
))

(define (transient-frame) `(
  ,@(titlebar-border)
  ,@(transient-titlebar)
  ,@(transient-left-buttons)
  ,@(transient-right-buttons)
  ,@window-border
))

(define (shaped-transient-frame) `(
  ,@(titlebar-border)
  ,@(transient-titlebar)
  ,@(transient-left-buttons)
  ,@(transient-right-buttons)
))

;; --- Resize button class -----------------

(def-frame-class resize-button '((cursor . left_ptr))
  (bind-keys resize-button-keymap
    "Button1-Move" 'resize-window-interactively)
  (bind-keys resize-button-keymap
    "Button3-Off" 'popup-window-menu))

(recolor-all)
(reframe-all)
(rebuild-all)

;; --- Register frame ----------------------

(add-frame-style 'FinalStep
  (lambda (w type)
    (case type
      ((default) (normal-frame))
      ((shaped) (shaped-normal-frame))
      ((transient) (transient-frame))
      ((shaped-transient) (shaped-transient-frame)))))
