(define-module (game audio)
  #:use-module (dom element)
  #:use-module (dom media)
  #:use-module (ice-9 match)
  #:use-module (srfi srfi-9)
  #:export (make-sound-effect
            sound-effect?
            sound-effect-src
            play-sound-effect))

(define-record-type <sound-effect>
  (%make-sound-effect src elems)
  sound-effect?
  (src sound-effect-src)
  (elems sound-effect-elems))

(define max-simultaneous 8)

(define (make-sound-effect src)
  (let ((elems (make-vector max-simultaneous #f)))
    (vector-set! elems 0 (make-audio src))
    (%make-sound-effect src elems)))

(define* (play-sound-effect sound #:optional (volume 0.5))
  (define (play elem)
    (set-media-volume! elem volume)
    (media-play elem))
  (match sound
    (($ <sound-effect> src elems)
     (let lp ((i 0))
       (when (< i max-simultaneous)
         (match (vector-ref elems i)
           (#f
            (let ((elem (clone-element (vector-ref elems 0))))
              (vector-set! elems i elem)
              (play elem)))
           (elem
            (if (media-ended? elem)
                (play elem)
                (lp (1+ i))))))))))