   (:require
     #_[om.core :as om :include-macros true]
     [clojure.set :refer [union]]
-    [clojure.walk :as walk]
+    #_[clojure.walk :as walk]
     [sablono.core :as sab :include-macros true])
   (:require-macros
-    [devcards.core :as dc :refer [defcard deftest]]))
+    [devcards.core :refer [defcard deftest]]))
 
 (enable-console-print!)
 

                                    (map #(next-transition has % qthen inputs) (vals has)))]
    (cond
      (> min-t qnow) (assoc scene :now now)
      (= min-t qnow) (do #_(println "clean border") (assoc scene :now now
                                                                 :objects (follow-transitions has transitions)))
      :else (do #_(println "messy border overflow" (- now min-t)) (update-scene (assoc scene :now min-t
                                                                                             :objects (follow-transitions has transitions))
                                                                                now
                                                                                inputs))
      )))

(defonce scene-a (atom {}))
(defonce last-time nil)

(defn goomba [id x y speed state others]
  (make-ha id                                               ;id
           {:x     x :y y                                   ;init
            :w     16 :h 16
            :state state}
           (make-state
             :right                                         ;name
             {:x speed}                                     ;flows
             ;edges
             ; x + 16 < 96 --> x < 96 - 16 && x + 16 + dx*frame >= 80 --> x >= 80 - dx*frame
             (make-edge :left [[:lt :x 80] [:geq :x '(- 80 [:d :x])]] #{:required})
             ; x + 16 < x2 && x + dx*frame + 16 >= x2 + dx2*frame
             ; x - x2 < -16 && x - x2 >= dx2*frame - dx*frame - 16
             (map #(make-edge :left [[:lt :x [% :x] -16]
                                     [:geq :x [% :x] (list '- [:d % :x] [:d :x] 16)]]
                              #{:required}) others))
           (make-state
             :left                                          ;name
             {:x (- speed)}                                 ;flows
             ;edges
             ; x > 8 && x + dx*frame <= 8 --> x <= 8 - dx*frame
             (make-edge :right [[:gt :x 8] [:leq :x '(- 8 [:d :x])]] #{:required})
             ; x > x2 + 16 && x + dx*frame <= x2 + dx2*frame + 16 --> x - x2 > 16 + dx2 && x - x2 <= dx2*frame + 16 - dx*frame
             ; x - x2 > 16
             (map #(make-edge :right [[:gt :x [% :x] 16]
                                      [:leq :x [% :x] (list '+ [:d % :x] 16 (list '- [:d :x]))]]
                              #{:required}) others))))

(defn make-scene-a [x] (let [objects [(goomba :ga x 8 16 :right #{:gb :gc :gd})
                                      (goomba :gb (+ x 18) 8 16 :left #{:ga :gc :gd})
                                      (goomba :gc (+ x 38) 8 16 :right #{:ga :gb :gd})
                                      (goomba :gd (+ x 58) 8 16 :left #{:ga :gb :gc})]
                             obj-ids (map :id objects)
                             obj-dict (zipmap obj-ids objects)
                             ; got to let every HA enter its current (initial) state to set up state invariants like

              ; >= : t >= rhs --> guard becomes true once t exceeds or equals rhs
              :geq [(.max js/Math rhs min-t) Infinity]
              ;  > : t  > rhs --> guard becomes true once t exceeds rhs
              :gt [(.max js/Math (+ rhs (/ time-unit 16)) min-t) Infinity]))))

(defn transition-interval [has ha transition]
  ;(println "Transition" (:id ha) (:x ha) (:target transition) (:guard transition))
  (let [intervals (map #(simple-interval has ha %) (:guard transition))
        interval (intersect-all intervals)]
    ;(println "interval:" intervals "->" interval)
    ; TODO: handle cases where transition is also guarded on states
    {:interval   interval
     :id         (:id ha)
