;;;;;;;;;;;;;;SELF MODULE;;;;;;;;;;;;;;

(require-compiled "GOAL-STYLE-MODULE" "ACT-R6:support;goal-style-module")

(undefine-module-fct 'self-module)

(defun reset-self-module (module)
	(declare (ignore module))
	(sgp :do-not-harvest self)
	(create-self-chunk-type-fct 'self)
)

(define-module-fct 'self-module  ;; the module is named self
  '(self)             ;; it has one buffer called self
  nil                    ;; it has no parameters
  :version "1.0"
  :documentation "A module that stores information about the ACT-R agent."
  :query #'goal-style-query
  :request #'goal-style-request 
  :reset (list nil #'reset-self-module)
  :buffer-mod #'goal-style-mod-request)

(defun self-module-update-cycle (module)
	(declare (ignore module))
) 

(defun create-self-chunk-type-fct (self-chunk-name)
	"Creates the self chunk type."
	(let ((fields (get-self-chunk-type-fields)))
		(push self-chunk-name fields)
		(chunk-type-fct fields))
)

(defun get-self-chunk-type-fields ()
	"Returns a list of fields for the self chunk type."
	(let ((fields nil))
		(dolist (row (select *triples-db* (where :predicate 'isa :object 'agent-property)))
			(push (getf row :subject) fields))
		fields)
)

(defun init-selves ()
	"Creates a self chunk based on the self chunk type, adds the chunk to the self buffer of the self module, and then updates the chunk with respect to agent property information."
	(dolist (m (get-act-r-agents) nil)
		(unless (eq m 'base-model)
			(with-model-eval m ;;make m the current model	 
				(define-chunks (s1 isa self))
				(set-buffer-chunk 'self 's1)
				(update-self m))))
)

(defun update-self (agent)
	"Updates the slots of the self chunk with respect to agent property information."
	(dolist (field (get-self-chunk-type-fields))
		(modify-self-fct (list field (get-object-from-triple agent field))))
)		

(defmacro modify-self (&rest modifications)
  "Modify the chunk in the self buffer as if by mod-chunk"
  `(modify-self-fct ',modifications))

(defun modify-self-fct (modifications)
  "Modify the chunk in the self buffer as if by mod-chunk-fct"
  (let ((chunk (buffer-read 'self)))
    (if chunk
        (progn
          (schedule-event-relative 0 'self-modification 
                                   :module 'self-module
                                   :priority :max
                                   :output 'medium)
          (mod-chunk-fct chunk modifications))
                                   
      (print-warning "No chunk in the self buffer to modify")))
)

(defun self-modification ()
  "Dummy function for self-mod event"
  nil)