(define (ret->list x) (vector->list (cadr x)))
(define (ret->value x) (if (pair? x) (car x) x))
(define (ret->bool x) (if (equal? (ret->value x) 0) #f #t))
(define (bool->int x) (if x TRUE FALSE))

(define (set-layer-visibility-recursively layer-path pred)
  (let ((layer (car layer-path)))
    (gimp-item-set-visible layer (bool->int (pred layer-path)))
    (if (ret->bool (gimp-item-is-group layer))
        (for-each (lambda (layer)
                    (set-layer-visibility-recursively (cons layer layer-path) pred))
                  (ret->list (gimp-item-get-children layer))))))
(define (set-image-visibility image pred)
  (for-each (lambda (layer)
              (set-layer-visibility-recursively (list layer) pred))
            (ret->list (gimp-image-get-layers image))))

(let* ((image (ret->value (gimp-xcf-load 0 ${infile} ${infile})))
       (visible-layers (map (lambda (name) (ret->value (gimp-image-get-layer-by-name image name))) '(${layers}))))
  (set-image-visibility image (lambda (layer-path)
                                (let ((x (or (> (length layer-path) 1)
                                             (not (not (member (car layer-path) visible-layers))))))
                                  ; (if x (gimp-message (apply string-append (map (lambda (x) (string-append (number->string x) "\\")) layer-path))))
                                  x)))
  (file-png-save RUN-NONINTERACTIVE image (ret->value (gimp-image-merge-visible-layers image CLIP-TO-IMAGE)) ${outfile} ${outfile} FALSE 0 FALSE TRUE FALSE FALSE FALSE)
  (gimp-image-delete image))
(gimp-quit TRUE)
