     (apply merge-with deep-merge vals)
     (last vals)))
 
-(println "test deep-merge" (deep-merge {:a 1} {:b {:c 2}}))
+(println "test deep-merge" (deep-merge {:a {:b 1}} {:a {:d 2}}))
 
 (defn entities-with-component
   "Takes a hashmap and returns all keys whose values contain component-id"

   merged into the game state."
  [component-id f]
  (fn [state entity-id]
    (mk-component-state
     component-id
     entity-id
     (f entity-id
        (get-component-state state component-id entity-id)))))

(println "test mk-component-fn"
         ((mk-component-fn :test (fn [& args] (identity {:foo "bar"})))

   component state which will be merged into the overall state"
  [state uid fns]
  (let [wrapped-fns (for [f fns] (mk-component-fn uid f))]
    (assoc state :components {uid {:fns wrapped-fns :state {}}})))

(println "test mk-component"
         (mk-component {} :my-component [identity]))

(defn mk-system-fn
  "Returns a function representing a system.

   Has two arrities:
   - [f] function f is called with state and wrapped to merge the return
     value of the function with state
   - [f component-id] function f is called with state, a collection of
     component functions, and a collection of entity ids that match the
     given component id. Results are merged with game state."
  ([f]
   (fn [state]
     (deep-merge state (f state (:entities state)))))  
  ([f component-id]
   (fn [state]
     (let [entities (entities-with-component (:entities state) component-id)
           component-fns (get-component-fns state component-id)]
       (deep-merge state (f state component-fns entities))))))

(println "test mk-system-fn"
         ((mk-system-fn (fn [s fns ents] s) :b) {:entities {:a [:b]}}))

(defn integration-test
  "Test the entire CES implementation with a system that changes component state"
  []
  (let [sys-fn (fn [state fns entity-ids]
                 (apply deep-merge (for [f fns, e entity-ids] (f state e))))
        test-system (mk-system-fn sys-fn :testable)
        scenes (-> {}
                   (mk-scene :test-scene [test-system]))
        test-fn (fn [component-state entity-id]
                  (println "testing" entity-id
                           component-state "->"
                           (assoc component-state :x
                                  (inc (or (:x component-state) 0))))
                  (assoc component-state :x (inc (or (:x component-state) 0))))
        state (-> {}
                  (mk-entity :player1 [:testable])
                  (mk-entity :player2 [:testable])
                  (mk-component :testable [test-fn]))]
    (game-loop scenes :test-scene state 0)))

(println "Running integration-test" (integration-test))
