       (reify
         om/IRender
         (render [_]
-          (dom/h1 nil (str "nuf " (:text app))))))
+          (dom/h1 nil (:text app)))))
     app-state
     {:target (. js/document (getElementById "app"))}))

            )
  (:require-macros [cljs.core.async.macros :refer [go]]))

(defonce app-state (atom {:text "Hello Chestnut!"}))

(defn log [& args]
  (.apply (.-log js/console) js/console (clj->js args)))

(defn guid "Generates a random GUID" []
  (str (s4) (s4) "-" (s4) "-" (s4) "-" (s4) "-" (s4) (s4) (s4)))


(defn user
  []
  (let [user "user"
        result (.getItem js/localStorage user)]
    (if result
      result
      (do
        (let [id (guid)]
          (.setItem js/localStorage user id)
          id)))))


(declare send on-message)

(defn on-open
  [cat event]
  (swap! cat assoc :connected? true)
  (send cat "identify" {}))

(defn init []
  (let [url "ws://localhost:9000/api/ws"
        s (js/WebSocket. url)
        cat (atom {:socket s
                   :connected? false
                   :identified? false
                   :queue []
                   :sent-messages {}})]
    (set! (.-onopen s ) #(on-open cat %))
    (set! (.-onmessage s ) #(on-message cat (.parse js/JSON (.-data %))))

    cat))

(defn send [cat action data]
  (let [params {:api_key "foo"
                :user (user)
                :action action
                :data data
                :id (guid)
                :timestamp (.getTime (js/Date.))}]
    (if (:connected? @cat)
      (do
        (log "sending" (clj->js params))
        (swap! cat update-in [:sent-messages] assoc (:id params) params)
        (.send (:socket @cat) (stringify params)))
      (do
        (log "enqueing")
        (swap! cat update-in [:queue] conj params)))))

(defn flush-queue [cat]
  (log "identified, flushing queue")

  (let [q (:queue @cat)]
    (swap! cat assoc :queue [])

    (doseq [item q]
      (log "sending" (clj->js item))
      (.send (:socket @cat) (stringify item)))))

(defn on-message [cat data]
  (condp = (.-action data)
    "ack" (do
            (let [id (.-id data)]
              (when (= "identify" (get-in @cat [:sent-messages id :action]))
                (swap! cat assoc :identified? true)
                (flush-queue cat))

              (log "ACK received: " data)
              (swap! cat update-in [:sent-messages] dissoc id)))
    (log "unrecognized message" data)))

(defn join [cat room]
  (send cat "join" {:room room}))

(defn leave [cat room]
  (send cat "leave" {:room room}))

(defn broadcast [cat room msg]
  (send cat "broadcast" {:room room :message msg}))

;;

(defn main []
  (let [cat (init)]
    (join cat "test")
    (broadcast cat "test" "hello!"))


  (om/root
