                              ;; Forces a re-render
                              (om/set-state! owner :modified (new js/Date))))}
 
-            [:rect {:x 0 :y 0 :width 140 :height 100 :fill "black"}]
-            [:text {:x 30 :y 80 :style {:font-size default-font :stroke "white" :fill "white"}} ">!"]]
+            [:g {:transform "translate(90,0)"}
+             [:rect {:x 0 :y 0 :width 140 :height 100 :fill "black"}]
+             [:text {:x 0 :y 80 :style {:font-size default-font :stroke "white" :fill "white"}} ">!"]]]
 
            (for [x (range bufsize)]
              [:g {:transform (str "translate(320,320)")}

            [:text {:x 30 :y 80 :style {:font-size default-font :stroke "white" :fill "white"}}
             "(alts! ch (time-out 2000))"]]]])))))

(defn create-circle [offset angle]
  (fn [app owner]
    (reify
      om/IInitState
      (init-state [_]
        {:label (rand-int 10)}
        )
      om/IWillMount
      (will-mount [_]
        (go-loop []
          (<! (timeout (+ 1000 (rand-int 200))))
          (om/set-state! owner :label (str (rand-int 10)))
          (recur)
          )
        )
      om/IRender
      (render [_]
        (html
         (let [x (+ 300 (* offset (Math/cos angle)))
               y (- 300 (* offset (Math/sin angle)))
               x2 (+ 300 (* (inc offset) (Math/cos angle)))
               y2 (- 300 (* (inc offset) (Math/sin angle)))
               ]
           [:g {:transform (str "translate(" x "," y ")")}
            [:circle {:cx 0 :cy 0 :r 30 :fill "#5F8"}]
            [:text {:x -10 :y 10 :style {:font-size "32pt"}} (str (om/get-state owner :label))]]
))))))

(defn go-block-slide [data owner opts]
  (reify
    om/IInitState
    (init-state [_]
      (let [circles (:circles opts)]
        {:default-font (:font-size opts)
         :circles (for [n (range circles)]
                    (let [angle (* n (/ (* 2 Math/PI) circles))
                          offset 250]
                      (create-circle offset angle)))}))
    om/IRender
    (render [_]
      (let [default-font (om/get-state owner :default-font)]
        (html
         [:div
          [:svg {:version "1.1" :width 600 :height 600}
           [:g
            [:rect {:x 0 :y 0 :width 600 :height 600 :fill "#292"}]
            (for [c (om/get-state owner :circles)]
              (om/build c data))
            #_[:text {:x 20 :y 120 :fill "#f00"
                      :style {:font-size "80pt"}}
               "Hello Ruben, buon compleano!!!"]]]])))))

(def app-model
  (atom {:current-slide 1
         :slides
         ;; TODO Add cardinal such that each slide has its own number to avoid react warning
         [{:title "core.async"
           :event "QCon 2014"
           :author "Malcolm Sparks"
           :company "JUXT"
           :email "malcolm@juxt.pro"
           :twitter "@malcolmsparks"
           }

          {:subtitle "What is core.async?"
           ;;:text "Here is the first slide"
           ;;:background "/static/cspdiag.jpg"
           :bullets ["Clojure library released May 2013"
                     "Based on Communicating Sequential Processes"
                     "Available in Clojure and ClojureScript"]
           }

          {:title "Quick tutorial"}

          {:subtitle "channels (TODO)"}

          ;; TODO Add source code on right hand side of slide
          {:subtitle "put and take"
           :custom put-and-take-slide
           :opts {:buffer-size 7 :font-size "72pt" :radius 50}}

          {:subtitle "timeouts"
           :custom timeout-slide
           :opts {:font-size "72pt"}}

          {:subtitle "buffers (TODO)"
           :code "(<! (chan))"}

          {:subtitle "alts!"
           :custom alts-slide
           :opts {:font-size "30pt"}}

          {:subtitle "go blocks"
           :custom go-block-slide
           :opts {:font-size "80pt" :circles 5}
           }

          ;; TODO Play catch between go blocks

          ;; TODO Show source code from cljs sources on disk - via cljs - use different namespaces

          ;; TODO result of race in alts! between a channel and a timeout

          ;; Go blocks

          {:title "When?"}

          ;; TODO Don't forget to mention Hecuba and Stentor (that they're free software)

          {:title "END?"}]}))

(defn source-snippet [data owner fname]
  (reify

                           (go
                             (<! ch)
                             (om/set-state! owner :modified (new js/Date))))}

            [:g {:transform "translate(90,0)"}
             [:rect {:x 0 :y 0 :width 140 :height 100 :fill "black"}]
             [:text {:x 0 :y 80 :style {:font-size default-font :stroke "white" :fill "white"}} "<!"]]

            ]]])))))

(defn timeout-slide [data owner opts]
  (reify
