 USING: cocoa cocoa.plists core-foundation iokit iokit.hid
 kernel cocoa.enumeration destructors math.parser cocoa.application 
 sequences locals combinators.short-circuit threads
-namespaces assocs vectors arrays combinators
+namespaces assocs vectors arrays combinators hints alien
 core-foundation.run-loop accessors sequences.private
 alien.c-types math parser game-input vectors ;
 IN: game-input.iokit

    } cleave ;

M: iokit-game-input-backend (reset-game-input)
    { +hid-manager+ +keyboard-state+ +controller-states+ }
    [ f swap set-global ] each ;

M: iokit-game-input-backend (close-game-input)

        [ 3drop ]
    } cond ;

HINTS: record-controller { controller-state alien } ;

: ?set-nth ( value nth seq -- )
    2dup bounds-check? [ set-nth-unsafe ] [ 3drop ] if ;

: record-keyboard ( keyboard-state value -- )
    dup IOHIDValueGetElement dup keyboard-key? [
        [ IOHIDValueGetIntegerValue c-bool> ]
        [ IOHIDElementGetUsage ] bi*
        rot ?set-nth
    ] [ 3drop ] if ;

HINTS: record-keyboard { array alien } ;

: record-mouse ( mouse-state value -- )
    dup IOHIDValueGetElement {
        { [ dup button? ] [ record-button ] }
        { [ dup axis? ] [ {
            { [ dup x-axis? ] [ drop mouse-axis-value [ + ] curry change-dx drop ] }
            { [ dup y-axis? ] [ drop mouse-axis-value [ + ] curry change-dy drop ] }
            { [ dup wheel?  ] [ drop mouse-axis-value [ + ] curry change-scroll-dx drop ] }
            { [ dup z-axis? ] [ drop mouse-axis-value [ + ] curry change-scroll-dy drop ] }
            [ 3drop ]
        } cond ] }
        [ 3drop ]
    } cond ;

HINTS: record-mouse { mouse-state alien } ;

M: iokit-game-input-backend read-mouse
    +mouse-state+ get ;
