      [:rotate [:from 0 :to rotation-strength :time rotation-time]]
      [:rotate [:from rotation-strength :to 0 :time rotation-time]])))
 
+(def pathspec-kw->applyable-fn
+     {:linear (fn [path x y] (do (log/info logger (str "Adding path to " x "," y)) (.addLineTo path x y)))
+      :quadric (fn [path cpx cpy x y] (.addQuadricTo path cpx cpy x y))
+      :cubic (fn [path cpx1 cpy1 cpx2 cpy2 x y] (.addCubicTo path cpx1 cpy1 cpx2 cpy2 x y))
+      ;; TODO:
+      ;; :catmull (fn [path cpx1 cpy1 cpx2 cpy2 x y] (.addCubicTo path cpx1 cpy1 cpx2 cpy2 x y))
+      })
+
+(defn- apply-pathspec-to-path
+  ([path]
+     path)
+  ([path [kind & args]]
+     (if (number? kind)
+       (apply (pathspec-kw->applyable-fn :linear) path kind args)
+       (apply (pathspec-kw->applyable-fn kind) path args)))
+  ([path spec1 spec2 & more]
+     (doto path
+       (apply-pathspec-to-path spec1)
+       (apply-pathspec-to-path spec2))
+     (apply apply-pathspec-to-path path more)))
+
 (defn move-behavior
   "Generate & return a move behavior for the target. Still must be added by calling .addBehavior.
    Examples: 

  CAAT.Behavior
  (behavior [s] s)
  cljs.core.Vector
  (behavior [v]
                (let [[kind & args] v] 
                  (apply (kind kw->behavior-fn) args))))

(defn animation-specs->behavior
  "Given a TARGET and any number of animation SPECS, create & return a

               ])
     (fn [director]
       (binding [*director* director]
         (log/info logger " Images loaded. Creating scene.")
         (doto director
           (.addAudio "chime" "sounds/22267__zeuss__the-chime.ogg" ;; "sounds/22267__zeuss__the-chime.mp3"
                      ) 
           (.addAudio "doppp" "sounds/8001__cfork__cf-fx-doppp-01.ogg" ;; "sounds/8001__cfork__cf-fx-doppp-01.wav"
                      )
           (.addAudio "flopp" "sounds/8006__cfork__cf-fx-flopp-03-dry.ogg" ;; "sounds/8006__cfork__cf-fx-flopp-03-dry.wav"
                      )
           (.addAudio "munching" "sounds/27877__inequation__munching.ogg" ;; "sounds/27877__inequation__munching.wav"
                      )
           (.addAudio "song" "sounds/448614_Happiness_Alone.ogg"))
         (let [scene (. director (createScene))
               background (actor :image "room")
               basket (basket scene :x 440 :y 240)
               bookshelf (bookshelf scene)
               counter (count-actor 6 :on-total-reached (fn [e] (add! scene (winning-screen scene))))
               basket-objects (map
                               #(let [actor (apply animated-actor (apply concat %))]
                                  (make-draggable-into
                                   actor
                                   basket scene 
                                   (fn [] (throw-into-basket director scene basket actor counter))
                                   :valid-fn (fn [] (and (not (.isOpened basket)) (not (.eating basket))))))
                               [{:image "football" :animation-indices [0] :draggable? true :thumbnail [60 60]}
                                {:image "car" :animation-indices [0] :draggable? true :thumbnail [60 60]}
                                {:image "blocks" :animation-indices [0] :draggable? true}
                                {:image "teddy" :animation-indices [0 1 0 2] :draggable? true}])
               bookshelf-objects (map
                                  #(let [actor (apply animated-actor (apply concat %))]
                                     (make-draggable-into
                                      actor bookshelf scene 
                                      (fn []
                                        (.setExpired actor true)
                                        (. bookshelf (inc-book-count))
                                        (. counter (inc)))))
                                  [{:image "book" :animation-indices [2] :default-index 2 :key-frames 3 :draggable? true}
                                   {:image "book" :animation-indices [0] :default-index 0 :key-frames 3 :draggable? true}])
               objects (concat basket-objects bookshelf-objects)] 
           (log/info logger " Displaying scene")
           (add! scene background)
           (add! scene basket)
           (add! scene counter) 
           (add! scene bookshelf)
           ;; (let [actor (actor :fill-style "black" :size [50 50])]
           ;;   (add! scene actor)
           ;;   ;; BUG: (create-animation [:move :to [[400 300] [500 200]] :dur 6000])
           ;;   ;; NO BUG: (create-animation [:move :to [[400 300] [500 250]] :dur 6000])  ;; what is the difference?
           ;;   ((create-animation [:move :to [[400 300] [500 250]] :dur 2000]
           ;;                      (fn [target] (log/info logger "first stage finished!"))
           ;;                      [:move :up 100 :dur 3000]
           ;;                      (fn [target] (log/info logger "second stage finished!")))
           ;;    :on-finish (fn [actor] (log/info logger "Finished!"))))
         
           (dotimes [index (count objects)]
             (let [object (nth objects index)]
               (add!
                scene
                object
                :position [(+ (rand-int 30) (* (/ 600 (count objects)) index) 100)
                           (+ (rand-int 50) 360)])))
           ;; (add! scene (winning-screen scene))
           ))))))
