(ns sekai.macros.components
  (:require [clojure.string :refer [capitalize]]))

(defmacro defcomponent [name fields & [generator constructor destructor]]
  (let [kwname (keyword name)
        compname (str "Component" (capitalize name))
        this (gensym)
        eid (gensym)]
    `(do
       (defrecord ~(symbol compname) ~fields
         ~'IComponent
         (~'attach! [~this ~eid]
          (sekai.entity.entity/register-component! ~eid ~kwname ~this)
          ~(when constructor
             `(~constructor ~eid ~this)))

         (~'_detach! [~this ~eid]
          (sekai.entity.entity/deregister-component! ~eid ~kwname)
          ~(when destructor
             `(~destructor ~eid ~this))))

       (defn ~name [~@fields]
         (apply ~(symbol (str "->" compname))
          ~(if generator
             `(let [result# (~generator ~@fields)]
                (if (sequential? result#)
                  result#
                  [result#]))
             fields))))))
