   (:require [clojure.walk :as walk]
             [retro-fever.sprite :as sprite]
             [retro-fever.util :as util]))
+
+(def active-scene (atom {:game-state nil :scene-lens nil}))
+
+(defn set-active!
+  ([game-state]
+   (set-active! game-state nil))
+  ([game-state scene-lens]
+   (swap! active-scene assoc :game-state game-state
+          :scene-lens (if (or (nil? scene-lens) (vector? scene-lens))
+                        scene-lens (vector scene-lens)))))
+
+(defn get-active []
+  @active-scene)
+
+(defn update-scene! [fn]
+  (let [{:keys [game-state scene-lens]} @active-scene]
+    (if (vector? scene-lens)
+      (swap! game-state update-in scene-lens fn)
+      (swap! game-state fn))))
 
 (defprotocol INode
   (add-child-id [this id])

  ([order update-fn]
   (assoc (group update-fn) :order order)))

(defn scene []
  (assoc (Scene.) :se-root (with-meta (group)  {:se-id :se-root})))

(derive sprite/StaticImage ::sprite)

  (remove-child-id [this id]
    (update-in this [:children] disj id)))

(defn create-id []
  (keyword (gensym "se-")))

(defrecord Scene []
  IScene
  (add [this element]
    (add this (create-id) element))
  (add [this id element]
    (add-to this :se-root id element))
  (add-to [this destination-id element]
    (add-to this destination-id (create-id) element))
  (add-to [this destination-id id element]
    (-> this
        (assoc id (with-meta element {:se-id id :parent destination-id}))
