(ns buddho.core.state.idea
  (:require [buddho.core.state.memory :refer [state]]
            [buddho.core.state.property :refer [remove-property! properties]]
            [buddho.core.state.protocols :refer [value reference fn-liberal]]))

(defn apply-fn [fn idea] (fn-liberal idea fn))

(defn- register-idea! [iid]
  (swap! state assoc-in [iid :_properties] #{})
  (swap! state assoc-in [iid :_reference] iid)
  iid)

(defn have-idea! [& [prefix count]]
  (let [pf (or prefix "idea_")
        fun #(register-idea! (gensym pf))]
    (if-not count
      (fun)
      (take count (repeatedly fun)))))

(defn update-idea! [idea data]
  (swap! state update idea merge data)
  idea)

(defn forget-idea! [idea]
  (let [iid (reference idea)]
    (apply remove-property! iid (properties idea))
    (swap! state dissoc iid)))

;; XXX is this used anywhere?
(defn elem [idea element]
  (get (value idea) element))

(defn rm-elem! [idea & elements]
  (run! #(swap! state update idea dissoc %) elements))
