 
 (def state (atom {:max-id 1
                   :graph {}
-                  :new-tweets-listeners []
-                  :graph-update-listeners []
+                  :listeners {:new-tweets []
+                              :graph-update []
+                              :track-clicked []
+                              :refresh-clicked []}
                   :tweet-count 0}))
 
-(defn add-listener [k f]
-  (swap! state (fn [old] (assoc old k (conj (k old) f)))))
+(defn add-listener [old-state k f]
+  (let [l (-> old-state :listeners k)]
+    (assoc-in old-state [:listeners k] (conj l f))))
+
+(defn register
+  "Register a function to be called when new data arrives specifying
+  the event to receive updates for. Events can be :new-tweets or :graph-update."
+  [event f]
+  (swap! state add-listener event f))
 
 (def twitter-uri (goog.Uri. "http://twitter.com/search.json"))
 

        tweets (filter #(> (:id %) old-max)
                       (:results result-map))]
    (do  (swap! state update-state new-max tweets)
         (send-tweets (:new-tweets-listeners @state) tweets)
         (send-tweets (:graph-update-listeners @state) (:graph @state)))))

(defn register
  "Register a function to be called when new data arrives specifying
  the event to receive updates for. Events can be :new-tweets or :graph-update."
  [event f]
  (cond (= event :new-tweets) (add-listener :new-tweets-listeners f)
        (= event :graph-update) (add-listener :graph-update-listeners f)))

(defn search-tag
  "Get the current tag value from the page."
  []
  (.value (dom/getElement "twitter-search-tag")))

(defn listener []
  (retrieve (.strobj {"q" (search-tag)}) my-callback))

(defn poll

         payload
         callback))

(defn send-event
  ([event]
     (send-event event nil))
  ([event message]
     (doseq [f (-> @state :listeners event)]
       (f message))))

(defn matches [p s]
  (seq (js* "~{s}.match(new RegExp(~{p}, 'g'))")))
