;; process-pair template
;;
;; Reusable video-pair processor: takes a single video source, creates two
;; clips (A and B) with opposite rotations and sporadic effects, blends them,
;; and applies a per-pair slow rotation driven by a beat scan.
;;
;; All sporadic triggers (invert, hue-shift, ascii) and pair-level controls
;; (blend opacity, rotation) are defined internally using seed offsets.
;;
;; Parameters:
;;   video         - source video node
;;   energy        - energy analysis node (drives rotation/zoom amounts)
;;   beat-data     - beat analysis node (drives sporadic triggers)
;;   rng           - RNG object from (make-rng seed) for auto-derived seeds
;;   rot-dir       - initial rotation direction: 1 (clockwise) or -1 (anti-clockwise)
;;   rot-a/b       - rotation ranges for clip A/B (e.g. [0 45])
;;   zoom-a/b      - zoom ranges for clip A/B (e.g. [1 1.5])

(deftemplate process-pair
  (video energy beat-data rng rot-dir rot-a rot-b zoom-a zoom-b)

  ;; --- Sporadic triggers for clip A ---

  ;; Invert: 10% chance per beat, lasts 1-5 beats
  (def inv-a (scan beat-data :rng rng :init 0
    :step (if (> acc 0) (- acc 1) (if (< (rand) 0.1) (rand-int 1 5) 0))
    :emit (if (> acc 0) 1 0)))

  ;; Hue shift: 10% chance, random hue 30-330 deg, lasts 1-5 beats
  (def hue-a (scan beat-data :rng rng :init (dict :rem 0 :hue 0)
    :step (if (> rem 0)
              (dict :rem (- rem 1) :hue hue)
              (if (< (rand) 0.1)
                  (dict :rem (rand-int 1 5) :hue (rand-range 30 330))
                  (dict :rem 0 :hue 0)))
    :emit (if (> rem 0) hue 0)))

  ;; ASCII art: 5% chance, lasts 1-3 beats
  (def ascii-a (scan beat-data :rng rng :init 0
    :step (if (> acc 0) (- acc 1) (if (< (rand) 0.05) (rand-int 1 3) 0))
    :emit (if (> acc 0) 1 0)))

  ;; --- Sporadic triggers for clip B (offset seeds) ---

  (def inv-b (scan beat-data :rng rng :init 0
    :step (if (> acc 0) (- acc 1) (if (< (rand) 0.1) (rand-int 1 5) 0))
    :emit (if (> acc 0) 1 0)))

  (def hue-b (scan beat-data :rng rng :init (dict :rem 0 :hue 0)
    :step (if (> rem 0)
              (dict :rem (- rem 1) :hue hue)
              (if (< (rand) 0.1)
                  (dict :rem (rand-int 1 5) :hue (rand-range 30 330))
                  (dict :rem 0 :hue 0)))
    :emit (if (> rem 0) hue 0)))

  (def ascii-b (scan beat-data :rng rng :init 0
    :step (if (> acc 0) (- acc 1) (if (< (rand) 0.05) (rand-int 1 3) 0))
    :emit (if (> acc 0) 1 0)))

  ;; --- Pair-level controls ---

  ;; Internal A/B blend: randomly show A (0), both (0.5), or B (1), every 1-11 beats
  (def pair-mix (scan beat-data :rng rng
    :init (dict :rem 0 :opacity 0.5)
    :step (if (> rem 0)
            (dict :rem (- rem 1) :opacity opacity)
            (dict :rem (rand-int 1 11) :opacity (* (rand-int 0 2) 0.5)))
    :emit opacity))

  ;; Per-pair rotation: one full rotation every 20-30 beats, alternating direction
  (def pair-rot (scan beat-data :rng rng
    :init (dict :beat 0 :clen 25 :dir rot-dir :angle 0)
    :step (if (< (+ beat 1) clen)
            (dict :beat (+ beat 1) :clen clen :dir dir
                  :angle (+ angle (* dir (/ 360 clen))))
            (dict :beat 0 :clen (rand-int 20 30) :dir (* dir -1)
                  :angle angle))
    :emit angle))

  ;; --- Clip A processing ---
  (def clip-a (-> video (segment :start 0 :duration (bind energy duration))))
  (def rotated-a (-> clip-a
    (effect rotate :angle (bind energy values :range rot-a))
    (effect zoom :amount (bind energy values :range zoom-a))
    (effect invert :amount (bind inv-a values))
    (effect hue_shift :degrees (bind hue-a values))
    ;; ASCII disabled - too slow without GPU
    ;; (effect ascii_art
    ;;   :char_size (bind energy values :range [4 32])
    ;;   :mix (bind ascii-a values))
    ))

  ;; --- Clip B processing ---
  (def clip-b (-> video (segment :start 0 :duration (bind energy duration))))
  (def rotated-b (-> clip-b
    (effect rotate :angle (bind energy values :range rot-b))
    (effect zoom :amount (bind energy values :range zoom-b))
    (effect invert :amount (bind inv-b values))
    (effect hue_shift :degrees (bind hue-b values))
    ;; ASCII disabled - too slow without GPU
    ;; (effect ascii_art
    ;;   :char_size (bind energy values :range [4 32])
    ;;   :mix (bind ascii-b values))
    ))

  ;; --- Blend A+B and apply pair rotation ---
  (-> rotated-a
    (effect blend rotated-b
      :mode "alpha" :opacity (bind pair-mix values) :resize_mode "fit")
    (effect rotate
      :angle (bind pair-rot values))))
