;nyquist plug-in
;version 4
;type tool
;name "Macro Step Through"
;author "Steve Daulton"
;release 3.0.0
;copyright "Released under terms of the GNU General Public License version 2"

;control macro "Macro name" string "" "Fade Ends" ""
;control action "Action" choice "Step,Restart,Skip Step,Repeat Step,Run All,Reset" 0

(setf macro (string-trim " " macro))  ;trim spaces
(setf fname "")
(when (string/= macro "")
  (setf fname (format nil "~a.txt" macro))
  ;; Get fully qualified name of file
  (setf fname (format nil "~a~aMacros~a~a"
                      (string-right-trim "\/" (get '*system-dir* 'data))
                      *file-separator*
                      *file-separator*
                      fname)))

(setf id 'Macro-Step-Through-21Mar2021-13:55) ;Unique ID for *scratch*

(defun reset ()
  (remprop '*scratch* id)
  "Reset.")

(defun do-command (fp)
  (let ((command "")
        (line (get '*scratch* id)))
    (if line
        (incf line)
        (setf line 0))
    (putprop '*scratch* line id)
    ;;ignore lines that have already been done.
    (dotimes (i line)
      (read-line fp))
    (setf command (read-line fp))
    (cond
      (command
          (aud-do command)
          "")
      (t  (reset)
          "Macro completed"))))

(defun repeat-command (fp)
  (let ((line (get '*scratch* id)))
    (when line
      (putprop '*scratch* (decf line) id))
    (do-command fp)))

(defun skip-command (fp)
  (let ((line (get '*scratch* id)))
    (if line
      (putprop '*scratch* (incf line) id)
      (putprop '*scratch* 1 id))
    (do-command fp)))

(defun do-all ()
  (setf macro (char-remove #\space macro))
  (format t "Macro_~a:" macro)
  (aud-do (format nil "Macro_~a:" macro)))

(let ((fp (open fname :direction :input)))
  (cond
    ((string= fname "")
        (reset))
    ((not fp)
        (reset)
        (format nil "~a~%does not exist." fname))
    ((= action 0) ;Run
        (setf rslt (do-command fp))
        (close fp)
        rslt)
    ((= action 1) ;Restart
        (reset)
        (setf rslt (do-command fp))
        (close fp)
        rslt)
    ((= action 2) ;Skip
        (setf rslt (skip-command fp))
        (close fp)
        rslt)
    ((= action 3) ;Repeat
        (setf rslt (repeat-command fp))
        (close fp)
        rslt)
    ((= action 4)
        (reset)
        (do-all))
    (t (reset)
        "Reset")))
