(require 'sawfish.wm.defaults)

;;; Programs to run on startup
(system "setxkbmap dvorak")
(system "setxkbmap -option compose:caps")
; (system "xscreensaver &")
(system "lxpanel &")


;;; Custom functions

(defun launch-app (app)
  (case app
    ('chrome (system "google-chrome --disable-gpu-compositing &"))
    ('term-code (system "gnome-terminal -t Code &"))
    ('term-quick (system "gnome-terminal -t Quick &"))
    ('term-std (system "gnome-terminal &")) ))

; Note that the documentation for 'insert-workspace' is wrong, and we insert
; *after* the provided value, not before
(defun launch-app-in-new-workspace (app)
  (progn
    (select-workspace (insert-workspace (cdr (workspace-limits))))
    (launch-app app) ))

(defun send-to-new-workspace ()
  (progn
    (set 'space current-workspace)
    (set 'window (input-focus))
    (move-window-to-workspace
      window
      space
      (insert-workspace (cdr (workspace-limits)))
      t )
    (select-workspace (cdr (workspace-limits))) ))

(defun send-workspace-to-top ()
  (move-workspace current-workspace (- (cdr (workspace-limits)) current-workspace)) )

(defun configure-basic-terminal (window)
  (progn
    (resize-window-to window 1350 800)
    (move-window-to window (- (screen-width) 1355) (- (screen-height) 855)) ))

(defun configure-quick-terminal (window)
  (move-window-to window 1811 0) )

(defun configure-code-terminal (window)
  (progn
    (resize-window-to window 1600 1024)
    (move-window-to window (- (screen-width) 1605) (- (screen-height) 1074)) ))

(defun build-new-workspace ()
  (progn
    (launch-app-in-new-workspace 'chrome)
    (launch-app 'term-code)))

(defun destroy-workspace ()
  (progn
    (mapcar
      (lambda (win)
        (if (not (equal "panel" win)) (destroy-window win)) )
      (workspace-windows) )
    (remove-workspace)
    (previous-workspace 1) ))


;;; Keybinds
(define apps-keymap (make-keymap))

(bind-keys apps-keymap
  "t" '(launch-app 'term-std)
  "q" '(launch-app 'term-quick)
  "o" '(launch-app 'term-code)
  "c" '(launch-app 'chrome) )

(unbind-keys global-keymap
  "W-Left"
  "W-Right"
  "M-Up"
  "M-Down"
  "C-Tab")

; Workspace bindings
(bind-keys global-keymap
  "M-C-Delete"       'restart
  "Super-Left"       '(previous-workspace 1)
  "Super-Right"      '(next-workspace 1)
  "Super-Up"         '(select-workspace (cdr (workspace-limits))) ; top of stack
  "Super-Down"       '(select-workspace (car (workspace-limits))) ; bottom of stack
  "Super-Next"       'move-workspace-forwards
  "Super-Prior"      'move-workspace-backwards
  "Super-Shift-Next"  send-workspace-to-top
  "Super-End"         destroy-workspace
  "M-F1"             '(select-workspace 0)
  "M-F2"             '(select-workspace 1)
  "M-F3"             '(select-workspace 2)
  "M-F4"             '(select-workspace 3)
  "M-F5"             '(select-workspace 4)
  "M-F6"             '(select-workspace 5)
  "M-F7"             '(select-workspace 6)
  "M-F8"             '(select-workspace 7)
)

; Window-specific workspace bindings
(bind-keys window-keymap
  "Super-Shift-Left"  'send-to-previous-workspace
  "Super-Shift-Right" 'send-to-next-workspace
  "Super-Shift-Up"     send-to-new-workspace )

; General bindings
(bind-keys global-keymap
  "M-TAB"       'cycle-windows
  "M-Shift-TAB" 'cycle-windows-backward
  "Super-l"     '(system "xscreensaver-command -lock")
  "Super-x"     apps-keymap
  "Super-n"     build-new-workspace
)

; Mouse bindings
(bind-keys root-window-keymap
  "Button4-Click1" '(previous-workspace 1)
  "Button5-Click1" '(next-workspace 1) )

; Given a list of paired letter-command items, returns a new list of paired
; letter-function items, where each anonymous function calls the passed
; function with the original string as its argument
; 'function' should be a function, 'map' should be a list of strings
;
; This is currently unused, because my needs changed, but it's an excellent idea.
(defun funcmap (function map)
  (mapcar
    (lambda (item)
      (if (= (length item) 1)
          item
          (lambda () (function item)) ))
    map) )


;;; Custom variables
(set 'lock-first-workspace nil)

;;; Hooks
(add-hook 'idle-hook delete-empty-workspaces)

(add-hook 'after-add-window-hook
  (lambda (window)
    (if (string-match "Terminal" (window-name window)) (configure-basic-terminal window))
    (if (string-match "Quick"    (window-name window)) (configure-quick-terminal window))
    (if (string-match "Code"     (window-name window)) (configure-code-terminal window))
))