;;;; app-menu.lisp

(in-package #:app-menu)

;;; "app-menu" goes here. Hacks and glory await!
(export '(show-menu load-menu-file))

(defvar *app-menu* nil "Where the menu structure is held")

(defun load-menu-file (file-name &key (strip 0))
  (with-open-file (file file-name)
    (when (char= #\# (peek-char nil file)) (read-line file))  ; Hack around the "autogenerated file" comment
    (let* ((*read-eval* nil)
           (list (list (read file))))
      (dotimes (i strip) (setf list (mapcan #'cdr list)))
      (setf *app-menu* (nconc *app-menu* list)))))

(defun commandp (command-name)
  (loop
    :for command :being :the :hash-keys :of stumpwm::*command-hash*
    :when (string= (symbol-name command-name)
                   (symbol-name command ))
      :return command))

(defcommand show-menu () ()
  "Show the application menu"
  (labels
      ((pick (options)
         (let ((selection
                 (select-from-menu
                  (current-screen) ; screen
                  options          ; table
                  nil              ; prompt
                  0                ; initial-selection
                  )))
           (cond
             ((null selection)
              nil)
             ((stringp (second selection))
              (run-shell-command (second selection)))
             ((and (symbolp (second selection))
                   (commandp (second selection)))
              (funcall (second selection)))
             (t
              (if (equalp ".." (first selection))
                  (pick (second selection))
                  (pick (append (list (list ".." options))
                                (cdr selection)))))))))
    (pick *app-menu*)))
