;; Beat-Triggered Ripple Drops Scan
;;
;; Creates random ripple drops triggered by audio beats.
;; Each drop has a random center position and duration.
;;
;; Required context:
;;   - music: audio analyzer from (streaming:make-audio-analyzer ...)
;;   - core primitives loaded
;;
;; Provides scan: ripple-state
;;   Bind with: (bind ripple-state :gate)  ;; 0 or 1
;;              (bind ripple-state :cx)    ;; center x (0-1)
;;              (bind ripple-state :cy)    ;; center y (0-1)
;;
;; Parameters:
;;   trigger-chance: probability per beat (default 0.15)
;;   min-duration: minimum beats (default 1)
;;   max-duration: maximum beats (default 15)
;;
;; Usage:
;;   (include :path "../templates/scan-ripple-drops.sexp")
;;   ;; Uses default: 15% chance, 1-15 beat duration
;;
;; In frame:
;;   (let [rip-gate (bind ripple-state :gate)
;;         rip-amp (* rip-gate (core:map-range e 0 1 5 50))]
;;     (ripple frame
;;       :amplitude rip-amp
;;       :center_x (bind ripple-state :cx)
;;       :center_y (bind ripple-state :cy)))

(scan ripple-state (streaming:audio-beat music t)
  :init {:gate 0 :cx 0.5 :cy 0.5 :left 0}
  :step (if (> left 0)
          (dict :gate 1 :cx cx :cy cy :left (- left 1))
          (if (< (core:rand) 0.15)
            (dict :gate 1
                  :cx (+ 0.2 (* (core:rand) 0.6))
                  :cy (+ 0.2 (* (core:rand) 0.6))
                  :left (+ 1 (mod (streaming:audio-beat-count music t) 15)))
            (dict :gate 0 :cx 0.5 :cy 0.5 :left 0))))
