;; Composable ASCII Art with Per-Zone Expression-Driven Effects
;; Requires ascii primitive library for the ascii-fx-zone primitive

(require-primitives "ascii")

;; Two modes of operation:
;;
;; 1. EXPRESSION MODE: Use zone-* variables in expression parameters
;;    Zone variables available:
;;      zone-row, zone-col: Grid position (integers)
;;      zone-row-norm, zone-col-norm: Normalized position (0-1)
;;      zone-lum: Cell luminance (0-1)
;;      zone-sat: Cell saturation (0-1)
;;      zone-hue: Cell hue (0-360)
;;      zone-r, zone-g, zone-b: RGB components (0-1)
;;
;;    Example:
;;      (ascii-fx-zone frame
;;        :cols 80
;;        :char_hue (* zone-lum 180)
;;        :char_rotation (* zone-col-norm 30))
;;
;; 2. CELL EFFECT MODE: Pass a lambda to apply arbitrary effects per-cell
;;    The lambda receives (cell-image zone-dict) and returns modified cell.
;;    Zone dict contains: row, col, row-norm, col-norm, lum, sat, hue, r, g, b,
;;                        char, color, cell_size, plus any bound analysis values.
;;
;;    Any loaded sexp effect can be called on cells - each cell is just a small frame:
;;      (blur cell radius)           - Gaussian blur
;;      (rotate cell angle)          - Rotate by angle degrees
;;      (brightness cell factor)     - Adjust brightness
;;      (contrast cell factor)       - Adjust contrast
;;      (saturation cell factor)     - Adjust saturation
;;      (hue_shift cell degrees)     - Shift hue
;;      (rgb_split cell offset_x offset_y) - RGB channel split
;;      (invert cell)                - Invert colors
;;      (pixelate cell block_size)   - Pixelate
;;      (wave cell amplitude freq)   - Wave distortion
;;      ... and any other loaded effect
;;
;;    Example:
;;      (ascii-fx-zone frame
;;        :cols 60
;;        :cell_effect (lambda [cell zone]
;;          (blur (rotate cell (* (get zone "energy") 45))
;;                (if (> (get zone "lum") 0.5) 3 0))))

(define-effect ascii_fx_zone
  :params (
    (cols :type int :default 80 :range [20 200]
      :desc "Number of character columns")
    (char_size :type int :default nil :range [4 32]
      :desc "Character cell size in pixels (overrides cols if set)")
    (alphabet :type string :default "standard"
      :desc "Character set: standard, blocks, simple, digits, or custom string")
    (color_mode :type string :default "color"
      :desc "Color mode: color, mono, invert, or any color name/hex")
    (background :type string :default "black"
      :desc "Background color name or hex value")
    (contrast :type float :default 1.5 :range [0.5 3.0]
      :desc "Contrast for character selection")
    (char_hue :type any :default nil
      :desc "Hue shift expression (evaluated per-zone with zone-* vars)")
    (char_saturation :type any :default nil
      :desc "Saturation multiplier expression (1.0 = unchanged)")
    (char_brightness :type any :default nil
      :desc "Brightness multiplier expression (1.0 = unchanged)")
    (char_scale :type any :default nil
      :desc "Character scale expression (1.0 = normal size)")
    (char_rotation :type any :default nil
      :desc "Character rotation expression (degrees)")
    (char_jitter :type any :default nil
      :desc "Position jitter expression (pixels)")
    (cell_effect :type any :default nil
      :desc "Lambda (cell zone) -> cell for arbitrary per-cell effects")
    ;; Convenience params for staged recipes (avoids compile-time expression issues)
    (energy :type float :default nil
      :desc "Energy multiplier (0-1) from audio analysis bind")
    (rotation_scale :type float :default 0
      :desc "Max rotation at top-right when energy=1 (degrees)")
  )
  ;; The ascii-fx-zone special form handles expression params
  ;; If energy + rotation_scale provided, it builds: energy * scale * position_factor
  ;; where position_factor = 0 at bottom-left, 3 at top-right
  ;; If cell_effect provided, each character is rendered to a cell image,
  ;; passed to the lambda, and the result composited back
  (ascii-fx-zone frame
    :cols cols
    :char_size char_size
    :alphabet alphabet
    :color_mode color_mode
    :background background
    :contrast contrast
    :char_hue char_hue
    :char_saturation char_saturation
    :char_brightness char_brightness
    :char_scale char_scale
    :char_rotation char_rotation
    :char_jitter char_jitter
    :cell_effect cell_effect
    :energy energy
    :rotation_scale rotation_scale))
