; 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.

; Perform various actions on the layers of an image
; 
; Can work on all layers, only visible layers, only linked layers,
; only layers above the current layer, or only layers that are below
; the current one.
;
; 


(define (script-fu-sg-process-layers image
                                     drawable 
                                     constraint 
                                     active 
                                     operation
                                     disposition )
  (let* ((active? (not (zero? active)))
         (active-position (car (gimp-image-get-layer-position image drawable)))
         (layers (let loop ((all-layers (vector->list (cadr (gimp-image-get-layers image))))
                            (layers '()) )
                   (if (null? all-layers)
                     (reverse layers)
                     (loop 
                       (cdr all-layers)
                       (let* ((layer (car all-layers))
	                            (pos (car (gimp-image-get-layer-position image layer))) )
                         (case constraint
                           ((0) ; all layers
                             (if (or (<> layer drawable) active?)
                               (cons layer layers)
                               layers ))
                           ((1) ; visibles
                             (if (and (or (<> layer drawable) active?)
                                      (not (zero? (car (gimp-layer-get-visible layer)))) )
                               (cons layer layers)
                               layers ))
                           ((2) ; linked
                             (if (and (or (<> layer drawable) active?)
                                      (not (zero? (car (gimp-layer-get-linked layer)))) )
                               (cons layer layers)
                               layers ))
                           ((3) ; above
                             (cond 
                               ((< pos active-position) (cons layer layers))
                               ((> pos active-position) layers)
                               (else (if active? (cons layer layers) layers)) ))
                           ((4) ; below
                             (cond 
                               ((> pos active-position) (cons layer layers))
                               ((< pos active-position) layers)
                               (else (if active? (cons layer layers) layers)) )))))))))
    (gimp-image-undo-group-start image)
    (map (case operation 
             ((1) ; add alpha
               gimp-layer-add-alpha )
             ((2) ; autocrop
               (lambda (layer) 
                 (gimp-image-set-active-layer layer)
                 (plug-in-autocrop-layer RUN-NONINTERACTIVE image layer) ))
             ((3) ; layer to image size
               gimp-layer-resize-to-image-size )
             ((4) ; clear selected
               gimp-edit-clear )
             ((5) ; paste
               (lambda (layer)
                 (gimp-floating-sel-anchor (car (gimp-edit-paste layer FALSE))) ))
             ((6) ; paste behind (retaining original layer ID)
               (lambda (layer)
                 (let ((orig-sel (car (gimp-selection-save image)))
                       (temp-layer (car (gimp-layer-copy layer TRUE))) )
                   (gimp-floating-sel-anchor (car (gimp-edit-paste layer FALSE)))
                   (gimp-selection-none image)
                   (gimp-image-add-layer image temp-layer 0)            
                   (gimp-floating-sel-anchor 
                     (car (gimp-edit-named-paste 
                            layer 
                            (car (gimp-edit-named-copy temp-layer "temp-buffer"))
                            FALSE )))
                   (gimp-selection-load orig-sel)
                   (gimp-image-remove-channel image orig-sel)
                   (gimp-image-remove-layer image temp-layer) )))
             ((7) ; apply layer mask
               (lambda (layer)
                 (unless (= (car (gimp-layer-get-mask layer)) -1)
                   (gimp-image-remove-layer-mask image layer MASK-APPLY) )))
             (else
               (lambda (layer)) ))
         layers )
    (map (case disposition
           ((1)
             (lambda (layer)
               (gimp-drawable-set-visible layer TRUE) ))
           ((2)
             (lambda (layer)
               (gimp-drawable-set-linked layer TRUE) ))
           ((3)
             (lambda (layer)
               (gimp-drawable-set-visible 
                 layer 
                 (if (zero? (car (gimp-drawable-get-visible layer)))
                   TRUE
                   FALSE ))))
           ((4)
             (lambda (layer)
               (gimp-drawable-set-linked 
                 layer
                 (if (zero? (car (gimp-drawable-get-linked layer)))
                   TRUE
                   FALSE ))))
           (else
             (lambda (layer)) ))
       layers )
    )
  (gimp-image-undo-group-end image)
  (gimp-displays-flush)
  )

(script-fu-register 
    "script-fu-sg-process-layers"
    "Process layers..."
    "Perform various actions on the layers of an image"
    "Saul Goode"
    "Saul Goode"
    "4/9/2008"
    "*"
    SF-IMAGE    "Image"    0
    SF-DRAWABLE "Layer" 0
    SF-OPTION "Limit to" '( "All layers"
                            "Visible"
                            "Linked"
                            "Above active"
                            "Below active" )
    SF-TOGGLE "Include Active Layer" TRUE          
    SF-OPTION "Operation" '( "Do nothing"
                             "Add alpha channel"
                             "Autocrop"
                             "Layer to image size"
                             "Clear selected"
                             "Paste"
                             "Paste behind"
                             "Apply layer mask"
                             "Flip"
                             "Rotate 90" )
    SF-OPTION "Disposition" '( "Unchanged"
                               "Set visible"
                               "Set linked"
                               "Toggle visibility"
                               "Toggle linkage" )
    )

(script-fu-menu-register "script-fu-sg-process-layers"
    "<Image>/Image"
    )
                           
