; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.

;; This script will translate layers so that each layer is centered
;; in a non-overlapping panel in a manner that all layers are visible.
;;
;; For example, if there are 15 layers and the largest layer is 100x50 pixels
;; then the result will be a 4x4 grid on a 400x200 image and each layer
;; will be centered in the cell of the grid.


(define (script-fu-sg-mosaicize image drawable)
  (let* (
      (layers (vector->list (cadr (gimp-image-get-layers image))))
      (max-bounds '())
      (num-cols (truncate (sqrt (length layers))))
      (num-rows (truncate (+ (/ (length layers) num-cols) 0.99999)))
      (window 0)
      (row 0)
      (col 0)
      )
    (gimp-image-undo-group-start image)
    (gimp-context-push)
    (set! max-bounds
      (let loop ((layer layers)
                 (max-width 0)
                 (max-height 0) )
        (if (null? layer)
         (list max-width max-height)
         (loop (cdr layer)
               (max max-width (car (gimp-drawable-width (car layer))))
               (max max-height (car (gimp-drawable-height (car layer)))) ))))
    (set! window (car (gimp-layer-new image
                                      (* num-cols (car max-bounds))
                                      (* num-rows (cadr max-bounds))
                                      (+ 1 (* (car (gimp-image-base-type image)) 2))
                                     "Frames"
                                      100
                                      NORMAL-MODE )))
    (gimp-drawable-fill window FOREGROUND-FILL)
    (gimp-image-add-layer image window -1)
    (gimp-image-lower-layer-to-bottom image window)
    (gimp-image-resize-to-layers image)
    (gimp-layer-set-offsets window 0 0)
    (gimp-context-set-foreground '(220 218 213))
    (gimp-drawable-fill window FOREGROUND-FILL)
    (let loop ((layer (reverse layers))
               (row 0)
               (col 0) )
      (when (pair? layer)
        (let* ((x (* col (car max-bounds)))
              (y (* row (cadr max-bounds))))
          (gimp-layer-set-offsets (car layer)
                                  (+ x (/ (- (car  max-bounds) 
                                             (car (gimp-drawable-width  (car layer))) )
                                           2 ))
                                  (+ y (/ (- (cadr max-bounds) 
                                             (car (gimp-drawable-height (car layer))) )
                                           2 )))
          (set! col (+ col 1))
          (when (= col num-cols)
            (set! col 0)
            (set! row (+ row 1)) )
          (loop (cdr layer)
                row
                col ))))
    (gimp-context-pop)
    (gimp-image-resize-to-layers image)
    (gimp-image-undo-group-end image)
    (gimp-displays-flush)
    )
  )

(script-fu-register "script-fu-sg-mosaicize"
 "Mosaicize"
 "Translate layers into an RxC grid"
 "Saul Goode"
 "Saul Goode"
 "11/21/2006"
 "*"
 SF-IMAGE    "Image"    0
 SF-DRAWABLE "Drawable" 0
 )
(script-fu-menu-register "script-fu-sg-mosaicize"
 "<Image>/Filters/Map"
 )
