(ns sekai.core.event
  (:require [main.sekai.core.gamestate
             :as gs
             :refer [game-state]]
            [main.sekai.core.entity :as entity]
            [main.sekai.core.selector :as selector]))

(defn enqueue! [event]
  (swap! (:queue @game-state) conj event))

(defn dequeue! []
  (let [queue (:queue @game-state)
        item (first @queue)]
    (swap! queue rest)
    item))

(defn make-event [id type source selector data]
  {:id id
   :type type
   :source source
   :selector selector
   :data data})

(defn dispatch-helper! [event changes]
  (selector/do-selector
   (:selector event)
   (fn [entity]
     (doseq [[component fun] changes]
       (entity/update-component! entity component fun)))))

(defmulti do-event! :type)
(defmethod do-event! :move [event]
  (dispatch-helper! event {:position (fn [_] (:data event))}))

(defmethod do-event! :register-entity [event]
  (let [eid (entity/register-entity!)]
    (doseq [tag (-> event :data :tags)] (entity/register-tag! eid tag))
    (doseq [component (-> event :data :components)] (entity/register-component! eid component))))
