;;
;; Charms-Colour.Quill
;;
;; An example program in Quill using the :charms library.
;;
;; Prints random characters to the screen in colour(s), optionally
;; with argument, where the characters of the argument are scattered
;; on screen.
;;
;; @burtons
;; AGPL
;; 2026

(define :variable letters "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789*+.-")

(define :function random-char ()
  (aref letters
        (random (length letters))))

(define :function random-color-pair ()
  (1+ (random 7)))

(define :function main (arguments)
  (if (> (length arguments) 1)
    (setf letters (second arguments)))

  (charms:with-curses ()
    (charms:disable-echoing)
    (charms:enable-raw-input)
    (charms:enable-non-blocking-mode
     charms:*standard-window*)

    ;; Start ncurses colour support.
    (charms/ll:start-color)

    ;; Define our seven colour pairs.
    (charms/ll:init-pair
     1 charms/ll:COLOR_RED charms/ll:COLOR_BLACK)

    (charms/ll:init-pair
     2 charms/ll:COLOR_GREEN charms/ll:COLOR_BLACK)

    (charms/ll:init-pair
     3 charms/ll:COLOR_YELLOW charms/ll:COLOR_BLACK)

    (charms/ll:init-pair
     4 charms/ll:COLOR_BLUE charms/ll:COLOR_BLACK)

    (charms/ll:init-pair
     5 charms/ll:COLOR_MAGENTA charms/ll:COLOR_BLACK)

    (charms/ll:init-pair
     6 charms/ll:COLOR_CYAN charms/ll:COLOR_BLACK)

    (charms/ll:init-pair
     7 charms/ll:COLOR_WHITE charms/ll:COLOR_BLACK)

    (loop
      (multiple-value-bind (width height)
          (charms:window-dimensions charms:*standard-window*)

        (charms:clear-window charms:*standard-window*)

        (dotimes (y (1- height))
          (dotimes (x width)

            ;; Turn on a random colour pair.
            (let ((pair (random-color-pair)))
              (charms/ll:wattron
               (charms::window-pointer charms:*standard-window*)
               (charms/ll:color-pair pair))

              ;; Draw the character.
              (charms:write-char-at-point
               charms:*standard-window*
               (random-char)
               x
               y)

              ;; Turn the colour back off.
              (charms/ll:wattroff
               (charms::window-pointer charms:*standard-window*)
               (charms/ll:color-pair pair))))

        (charms:refresh-window charms:*standard-window*))

      ;; Press Q to quit.
      (let ((key
              (charms:get-char
               charms:*standard-window*
               :ignore-error t)))
        (when (member key '(#\q #\Q))
          (return)))

      (sleep (/ 10 60.0))))))