 
 (defn grids []
   (om/ref-cursor (:grids (om/root-cursor app-state))))
+
+(defn samples []
+  (om/ref-cursor (:samples (om/root-cursor app-state))))
 
 (defn cell-view [{:keys [cursor id]} _]
   (reify

                                                      (get cursor "tracks")
                                                      (repeat id))]
                                     (om/build-all track-view cursors {:state state})))
                            (om/build (:builder-fn state) {:cursor cursor :id id :grid-state owner}))))))))

(defn app-view [cursor _]
  (reify

                                           :get-state-ch (:get-state-ch state)}]
                            (om/build grid-view id {:state sub-state})))))))))

(defn track-builder [{:keys [cursor id set-state-ch]} owner]
  (reify
    om/IInitState
    (init-state [_]
      {:state :init})
    om/IRenderState
    (render-state [_ state]
      (let [p (partial dom/p #js {:style #js {:color "#999"}})
            transition #(om/update-state! owner (fn [s] (merge s %)))
            commit #(condp = (:type state)
                      "sample" (let [track {"type" (:type state)
                                            "beats" (repeat (:width state) [0])
                                            "sample" (:sample state)
                                            "params" {}}
                                     tracks (clj->js (conj cursor track))]
                                 (transition {:state :init})
                                 (om/update! cursor tracks)
                                 (go (>! set-state-ch id)))
                      :else (print "cannot commit"))]
        (condp = (:state state)
          :init (p (dom/span #js {:onClick #(transition {:state :width})} "{+}"))
          :width (p (dom/span #js {:onClick #(transition {:state :init})} "{-")
                    (dom/span #js {:onClick #(transition {:state :type :width 1})} " 1 ")
                    (dom/span #js {:onClick #(transition {:state :type :width 2})} " 2 ")
                    (dom/span #js {:onClick #(transition {:state :type :width 4})} " 4 ")
                    (dom/span #js {:onClick #(transition {:state :type :width 8})} " 8 ")
                    (dom/span #js {:onClick #(transition {:state :type :width 16})} " 16 ")
                    (dom/span #js {:onClick #(transition {:state :type :width 32})} " 32 ")
                    (dom/span #js {:onClick #(transition {:state :type :width 64})} " 64 ")
                    (dom/span nil "}"))
          :type (p (dom/span #js {:onClick #(transition {:state :init})} (str "{- " (:width state) " ... "))
                   (dom/span #js {:onClick #(transition {:state :sample :type "sample"})} " sample ")
                   (dom/span #js {:onClick #(print "bonk")} " play ")
                   (dom/span #js {:onClick #(print "bonk")} " synth ")
                   (dom/span nil "}"))
          :sample (p (dom/span #js {:onClick #(transition {:state :init})} (str "{- " (:width state) " sample ... "))
                     (apply dom/select #js {:onChange #(transition {:state :commit :sample (-> % .-target .-value)})}
                            (map #(dom/option nil %) (om/observe owner (samples)) id))
                     (dom/span nil "}"))
          :commit (p (dom/span #js {:onClick #(transition {:state :init})}
                               (str "{- " (:width state) " sample " (:sample state) " ... "))
                     (dom/span #js {:onClick commit} " commit? ")
                     (dom/span nil "}")))))))

(defn grid-view [id owner]
  (reify
    om/IInitState
    (init-state [_]
      {:grid-expanded true}) ;; false
    om/IRenderState
    (render-state [_ state]
      (let [cursor (get (om/observe owner (grids)) id)]
