;; Mosaic effect - built from primitive xector operations
;;
;; Uses:
;;   pool-frame  - downsample to cell averages
;;   cell-indices - which cell each pixel belongs to
;;   gather       - look up cell value for each pixel

(require-primitives "xector")

(define-effect mosaic
  :params (
    (cell-size :type int :default 16 :range [4 64] :desc "Size of mosaic cells")
  )
  (let* (
         ;; Pool frame to get average color per cell (returns r,g,b,lum xectors)
         (pooled (pool-frame frame cell-size))
         (cell-r (nth pooled 0))
         (cell-g (nth pooled 1))
         (cell-b (nth pooled 2))

         ;; For each output pixel, get its cell index
         (cell-idx (cell-indices frame cell-size))

         ;; Gather: look up cell color for each pixel
         (out-r (gather cell-r cell-idx))
         (out-g (gather cell-g cell-idx))
         (out-b (gather cell-b cell-idx)))

    ;; Reconstruct frame
    (rgb out-r out-g out-b)))
