

(define-library (sx render-trace)
  (export
    *render-trace*
    *render-trace-log*
    *render-trace-depth*
    render-trace-reset!
    render-trace-push!
    render-trace-enter!
    render-trace-exit!
    format-render-trace)
  (begin

(define *render-trace* false)

(define *render-trace-log* (list))

(define *render-trace-depth* 0)

(define
  render-trace-reset!
  (fn () (set! *render-trace-log* (list)) (set! *render-trace-depth* 0)))

(define
  render-trace-push!
  (fn
    (kind detail result)
    (when
      *render-trace*
      (set! *render-trace-log* (append *render-trace-log* (list {:result (if (> (len (str result)) 80) (str (slice (str result) 0 77) "...") (str result)) :depth *render-trace-depth* :kind kind :detail detail}))))))

(define
  render-trace-enter!
  (fn
    (kind detail)
    (when
      *render-trace*
      (render-trace-push! kind detail "...")
      (set! *render-trace-depth* (+ *render-trace-depth* 1)))))

(define
  render-trace-exit!
  (fn
    (result)
    (when
      *render-trace*
      (set! *render-trace-depth* (- *render-trace-depth* 1)))))

(define
  format-render-trace
  (fn
    ()
    (join
      "\n"
      (map
        (fn
          (entry)
          (let
            ((indent (join "" (map (fn (_) "  ") (range 0 (get entry :depth)))))
              (kind (get entry :kind))
              (detail (get entry :detail))
              (result (get entry :result)))
            (str indent kind " " detail " → " result)))
        *render-trace-log*))))


)) ;; end define-library

;; Re-export to global namespace for backward compatibility
(import (sx render-trace))
