   (atom
    {:app {:name "Spinning"
           :version "0.1.0"
+          :count-frames? false
           :measure-fps? false
           :rendering? false
           }

   (let [[c1 c2 c3] (map #(:color %1) (keep #(get cells %1) (neighbors k)))]
     {:age 0 :color {:r (:r c1) :g (:g c2) :b (:b c3)}})))

(defn step [cells]
  (into {} (for [[k n] (->> (keys cells) (mapcat neighbors) (frequencies))
                 :let [cell (or (get cells k) (create-cell k cells))]
                 :when (or (= n 3) (and (= n 2) (contains? cells k)))]
             [k (update-in cell [:age] inc)])))


;; -----------------------------------------------------------------------------
;; Update / Render Cycle

(defn update! []
  (swap! state update-in [:gui :generation] inc))

(defn render! [timestamp state]
  (let [app-name (get-in state [:app :name])
        env-time (get-in state [:env :time])
        fps (get-in state [:env :frames-per-second])
        mouse-move (get-in state [:env :mouse-move])
        mouse-x (:client-x mouse-move)
        mouse-y (:client-y mouse-move)
        mouse-pos (str "[" mouse-x ":" mouse-y "]")
        gen (get-in state [:gui :generation])
        display [gen fps env-time timestamp mouse-pos]]
    (set! (.-innerText (app-div)) (string/join ", " display))))

(defn on-env-animation-frame [timestamp]
  (update!)
  (render! timestamp @state)
  (get-in @state [:app :rendering?]))

(defn start-rendering! []
  (console/info "start rendering")
  (swap! state assoc-in [:app :rendering?] true)
  (poly/listen-animation-frame! cycle!))

(defn stop-rendering! []
  (console/info "stop rendering")
