#lang racket/base
(require racket/class
         ffi/unsafe
         ffi/unsafe/objc
          "../../syntax.rkt"
         "item.rkt"
         "types.rkt"
         "const.rkt"
         "utils.rkt"
         "window.rkt"
         "../common/event.rkt"
         "liquid-glass.rkt")

(provide 
 (protect-out choice%))

;; ----------------------------------------

(import-class NSPopUpButton)

(define-objc-class RacketPopUpButton NSPopUpButton 
  #:mixins (FocusResponder KeyMouseResponder CursorDisplayer)
  [wxb]
  (-a _void (clicked: [_id sender])
      (queue-window*-event wxb (lambda (wx) (send wx clicked)))))

(defclass choice% item%
  (init parent cb label
        x y w h
        choices style font)
  (inherit get-cocoa init-font register-as-child)

  (super-new [parent parent]
             [cocoa
              (let ([cocoa
                     (as-objc-allocation
                      (tell (tell RacketPopUpButton alloc)
                            initWithFrame: #:type _NSRect (make-NSRect (make-init-point x y)
                                                                       (make-NSSize w h))
                            pullsDown: #:type _BOOL #f))])
                (define menu (tell cocoa menu))
                (for ([lbl (in-list choices)]
                      [i (in-naturals)])
                  (tell menu
                        insertItemWithTitle: #:type _NSString lbl
                        action: #:type _SEL #f
                        keyEquivalent: #:type _NSString ""
                        atIndex: #:type _NSInteger i))
                (init-font cocoa font)
                (tellv cocoa sizeToFit)
                (tellv cocoa setTarget: cocoa)
                (tellv cocoa setAction: #:type _SEL (selector clicked:))
                cocoa)]
             [callback cb]
             [no-show? (memq 'deleted style)])

  (define callback cb)
  (define/public (clicked)
    (callback this (new control-event%
                        [event-type 'choice]
                        [time-stamp (current-milliseconds)])))

  (define/override (get-margin-adjustments)
    (if (and (not liquid-glass?)
             (version-10.9-or-later?))
        (values 0 2 0 0)
        (values 0 0 0 0)))

  (define/public (set-selection i)
    (tellv (get-cocoa) selectItemAtIndex: #:type _NSInteger i))
  (define/public (get-selection)
    (tell #:type _NSInteger (get-cocoa) indexOfSelectedItem))
  (define/public (number)
    (tell #:type _NSInteger (get-cocoa) numberOfItems))
  (define/public (clear)
    (tellv (get-cocoa) removeAllItems))
  (define/public (append lbl)
    (define menu (tell (get-cocoa) menu))
    (tell menu
          insertItemWithTitle: #:type _NSString lbl
          action: #:type _SEL #f
          keyEquivalent: #:type _NSString ""
          atIndex: #:type _NSInteger (number))
    (void))
  (define/public (delete i)
    (tellv (get-cocoa) removeItemAtIndex: #:type _NSInteger i))

  (define/override (maybe-register-as-child parent on?)
    (register-as-child parent on?)))
