 (defn intersector []
   (map->Intersector {:raycaster (js/THREE.Raycaster.)}))
 
-(defrecord RenderContext [
-                          events
+(defrecord RenderContext [events
                           width height
                           scene camera renderer
                           intersector

  IInitialise
  (initialise! [this positions]
    (.setClearColor renderer 0xdbf1ff 1)
    (set! (.. light -position -x) 10)
    (set! (.. light -position -y) 50)
    (set! (.. light -position -z) 130)

    (.setSize renderer width height)

    (doseq [pos positions]
      (add-block! scene pos))

    (when (empty? positions)
      (add-block! scene [0 0 0])
      (send-position! [0 0 0]))

    ;; (.add scene floor)
    ;; (.add scene floor2)
    (.add scene light)

    (set! (.-y (.-position camera)) 10)
    (set! (.-z (.-position camera)) 10)
    (.lookAt camera (js/THREE.Vector3. 0 0 0)))

  IRender
  (render [this]
    (if-let [events (swap-and-return! events [])]
      ;; TODO find a better syntax for this keys/keys/keys
      (let [keys (swap! keys (fn [keys] (events/events->keys keys events)))]
        ;; TODO move this into a side-channel
        (doseq [pos (swap-and-return! new-positions [])]
          (add-block! scene pos))

        ;; TODO move into intersector -- deal with side-effecting nature of intersector
        (when-let [last @last-intersect]
          (.. (:object last) -material -color (setHex (:color last))))
        (reset! last-intersect nil)
        (intersections intersector mouse camera scene last-intersect)

        ;; TODO let's remove the side effect, and move the actual side-effecting update into
        ;; a side channel
        (update-camera! keys camera light (.. clock (getElapsedTime)))

        ;; TODO too many parameters -- and who knows what this modifies
        (events/call-event-handlers events scene @last-intersect mouse renderer camera)

        (.render renderer scene camera)))))
