sections/shell.rkt
;;
;; Application Classes / Menu and System Interface
;;
(define repl-shell%
  {class
   object%
   (super-new)
  
   ;;
   ;; Preferences
   (define default-background-color "Cornflower Blue")
   (define/public (get-table-background)
     (get-preference 'flower-garden:background-color
                     (lambda () default-background-color)))
   (define/public (get-layout) layout96l%)

    ;; Internal Interface
    ;; This should be encapsulated in an undo action object.
    (define/public (undo-action-enabled) #t)
    (define/public (undo-action-disabled) #f)
})

;; Racket/OS X Shell
(define flower-garden%
  {class
      object%
    (super-new)

    ;;
    ;; Preferences
    (define default-background-color "Cornflower Blue")
    (define/public (get-table-background)
      (get-preference 'flower-garden:background-color
                      (lambda () default-background-color)))
    (define/public (get-layout) layout87%)

    ;;
    ;; Flower Garden App Construction
    (define garden (new garden% [shell this]))
    (define main-frame (send garden get-table))
    (define my-menu-bar (make-object menu-bar% main-frame))
    (define my-game-menu (make-object menu% "Game" my-menu-bar))
    (define my-extra-menu (make-object menu% "Extra" my-menu-bar))

    (define skip-menu-item
      (new menu-item%
           [label "Skip this Animation"]
           [shortcut #\e] ; 'e like end animation or e scape
           [parent my-extra-menu]
           [callback
            {lambda {i e} (send garden skip-this-animation)}]))
    (define sort-bucket-by-rank-menu-item
      (new menu-item%
           [label "Sort Bouquet by Rank"]
           [shortcut #\s]
           [parent my-extra-menu]
           [callback
            {lambda {i e} (send garden sort-bucket-by-rank)}]))
    (define flower-preset-menu-item
      (new menu-item%
           [label "Flower Preset"]
           [parent my-extra-menu]
           [callback
            {lambda {i e} (send garden flower-preset)}]))
    (new separator-menu-item% [parent my-extra-menu])
    (define my-rules-menu (make-object menu% "Rules" my-extra-menu))
    (define rules-venus-menu-item
      (new menu-item%
           [label "Flower Venus Garden"]
           [parent my-rules-menu]
           [callback
            {lambda (i e) (send garden change-rules 'venus)}]))
    (define rules-moon-menu-item
      (new menu-item%
           [label "Flower Moon Garden (Easy)"]
           [parent my-rules-menu]
           [callback
            {lambda (i e) (send garden change-rules 'moon)}]))
    (define rules-hard-menu-item
      (new menu-item%
           [label "Flower Garden (Difficult)"]
           [parent my-rules-menu]
           [callback
            {lambda (i e) (send garden change-rules 'hard)}]))
    (new separator-menu-item% [parent my-rules-menu])
    (define rules-master-menu-item
      (new menu-item%
           [label "Master's Garden (No Rules)"]
           [parent my-rules-menu]
           [callback
            {lambda (i e) (send garden change-rules 'master)}]))

    (new menu-item%
         [label "Laughing Flowers"]
         [shortcut #\l]
         [parent my-game-menu]
         [callback
          {lambda {i e} (send garden laughing-flowers)}])
    (new separator-menu-item% [parent my-game-menu])
    (define hint-menu-item
      (new menu-item%
           [label "Dealer's Hint"]
           [shortcut #\t]
           [parent my-game-menu]
           [callback
            {lambda {i e} (send garden hint)}]))
    (new menu-item%
         [label "New Deal"]
         [shortcut #\n]
         [parent my-game-menu]
         [callback
          {lambda (i e) (send garden reset-game)} ])
    (new menu-item%
         [label "Reversed Deal"]
         [parent my-extra-menu]
         [callback
          {lambda (i e) (send garden reversed-deal)} ])
    (define undo-action-menu-item
      (new menu-item%
           [label "Take back Move"]
           [shortcut #\z]
           [parent my-game-menu]
           [callback
            {lambda {i e} (send garden undo)}]))
    (new separator-menu-item% [parent my-game-menu])
    ;(define my-edit-menu (make-object menu% "Edit" my-menu-bar))
    (new menu-item%
         [label "Leave Table"]
         [parent my-game-menu]
         [callback {lambda (i e)
                     (send main-frame show #f)
                     (exit)}])

    ;; Internal Interface
    ;; This should be encapsulated in an undo action object.
    (define/public (undo-action-enabled)
      (send undo-action-menu-item enable #t))
    (define/public (undo-action-disabled)
      (send undo-action-menu-item enable #f))

    (define/public (skip-action-enabled)
      (send skip-menu-item enable #t))
    (define/public (skip-action-disabled)
      (send skip-menu-item enable #f))

    ;; Start the show!
    (send garden flower-remembered (send this get-table-background))
    ;(my-collect-garbage)
    (send garden grow)
    })