;;; This work is licensed under the Creative Commons
;;; Attribution-NonCommercial-ShareAlike 4.0 International License.
;;; To view a copy of this license, visit
;;; http://creativecommons.org/licenses/by-nc-sa/4.0/ or send a letter to
;;; Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.

;;; Functions to provide generate graphic output from lfgmodel.lisp

(defvar *slotlist* (list 'dep1 'dep2 'dep3 'dep4))
(defvar *slotgfs* '((dep1 dep1.gf)
                    (dep2 dep2.gf)
                    (dep3 dep3.gf)
                    (dep4 dep4.gf)))

(defun output (chunklist)

;initialise the functions
   (let ((output ())
         (mothers ())
         (uniquemothers ()))

;start the file
    (format t "~&digraph G {")

;iterate over each chunk in the list to generate node, motherlist and outputlist
    (dolist (i chunklist t)
       (let ((mapred (chunk-slot-value-fct i 'pred))
             (isma (chunk-slot-value-fct i 'ma)))
         (format t "~&~A [shape=box,label=\"~A\\n~A\"];" mapred i mapred)
         (if (and isma
                  (not (equal isma t)))
            (push (list (chunk-slot-value-fct isma 'pred) mapred "?") mothers)
            nil)
         (dolist (slot *slotlist* t)
           (let ((kidchunk (chunk-slot-value-fct i slot)))
              (if kidchunk
                 (let ((kidpred (chunk-slot-value-fct kidchunk 'pred))
                       (kidgf (chunk-slot-value-fct i (second (assoc slot *slotgfs*)))))
                    (push (list mapred kidpred kidgf) output))
                 nil)))))

;iterate over the motherlist to test if the link should be added to output
     (setf uniquemothers mothers)
     (dolist (j mothers t)
        (dolist (k output t)
          (if (and (equal (first j) (first k)) (equal (second j) (second k)))
              (progn (setf uniquemothers (remove j uniquemothers))
                     (return t)))))
     (setf output (append uniquemothers output))

; generate the links - looping through outputlist
    (dolist (l output t)
        (format t "~&~A -> ~A [label=\"~A\"];" (first l) (second l) (third l)))

;wrap up the file
    (format t "~&}")))


(defun fileout (chunklist stream)

;initialise the functions
   (let ((output ())
         (mothers ())
         (uniquemothers ()))

;start the file
    (format stream "~&digraph G {")

;iterate over each chunk in the list to generate node, motherlist and outputlist
    (dolist (i chunklist t)
       (let* ((mapred (chunk-slot-value-fct i 'pred))
              (isma (chunk-slot-value-fct i 'ma))
;              (namestring "")
              )
;         (setf namestring (string i))
;         (setf (aref namestring (- (length namestring) 2)) #\_)
         (format stream "~&~A [shape=box,label=\"~A\\n~A\"];" mapred i mapred)  ; was i i mapred
         (if (and isma
                  (not (equal isma t))
                  (not (equal isma 'no)))
            (push (list (chunk-slot-value-fct isma 'pred) mapred "?" isma) mothers)
            nil)
         (dolist (slot *slotlist* t)
           (let ((kidchunk (chunk-slot-value-fct i slot)))
              (if kidchunk
                 (let ((kidgf (chunk-slot-value-fct i (second (assoc slot *slotgfs*)))))
                    (push (list mapred (chunk-slot-value-fct kidchunk 'pred) kidgf i) output))
                 nil)))))

;iterate over the motherlist to test if the link should be added to output
     (setf uniquemothers mothers)
     (dolist (j mothers t)
        (dolist (k output t)
          (if (and (equal (first j) (first k))
                   (equal (second j) (second k))
                   (equal (fourth j) (fourth k)))
              (progn (setf uniquemothers (remove j uniquemothers))
                     (return t)))))
     (setf output (append uniquemothers output))

; generate the links - looping through outputlist
    (dolist (l output t)
        (if (equal (third l) "?")
            (format stream "~&~A -> ~A [style=dotted];" (first l) (second l))
            (format stream "~&~A -> ~A [label=\"~A\"];" (first l) (second l) (third l))))

;wrap up the file
    (format stream "~&}~%")))




(defun generate-graph (chunklist filepath)
    (with-open-file (stream filepath
                       :direction :output
                       :if-exists :append
                       :if-does-not-exist :create)
        (fileout chunklist stream)))

(defun interim-graph (flag path runtime runindex wordindex chunklist)
   (if flag
       (let ((thispath (outputpath-with-index path (timepoint-with-index runtime runindex) wordindex "gv")))
          (generate-graph chunklist thispath))
       t))
