; GIMP - The GNU Image Manipulation Program
; Copyright (C) 1995 Spencer Kimball and Peter Mattis
;
; 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.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
;
;
; 
; Create an animated kaleidoscope from a single image or animation.
;
; The script can be found on an open image in GIMP 2.6 under: Filters > Animation > Kaleidoscope Animation...
; 

; Define the Function

; 27 avril 2011 modif samj - www.aljacom.com/~gimp - Mise à jour de procédures pour Gimp 2.7. À voir pb sur les sélections existant sur script d'origine

(define (script-fu-kaleidoscope-anim 	image		 
				drawable
				animOption
				frames
				direction
				speed
				useSelect
				delete
				semiflatten
				backgroundColor
				)

; Declare the Variables

	(let* (
		    	(activeLayer nil)
			(counter nil)
			(numLayers nil)
			(allLayersRef nil)
			(origSelect nil)	
		    	(height nil)
			(width nil)
			(copyLayer nil)
			(x-dir
				(cond
				(( equal? direction 0 ) 0)		
				(( equal? direction 1 ) 0)
				(( equal? direction 2 ) -1)		
				(( equal? direction 3 ) 1)		
				(( equal? direction 4 ) -1)		
				(( equal? direction 5 ) 1)		
				(( equal? direction 6 ) -1)		
				(( equal? direction 7 ) 1)
				)
			)		
			(y-dir
				(cond
				(( equal? direction 0 ) -1)		
				(( equal? direction 1 ) 1)
				(( equal? direction 2 ) 0)		
				(( equal? direction 3 ) 0)		
				(( equal? direction 4 ) -1)		
				(( equal? direction 5 ) -1)		
				(( equal? direction 6 ) 1)		
				(( equal? direction 7 ) 1)
				)
			)		
			(step-x nil)
			(step-y nil)
			(offset-x 0)
			(offset-y 0)
			(layerName nil)
			(frameNum 1)
			(proceed nil)
		)



(gimp-context-push)
(gimp-image-undo-group-start image)

(if (= animOption 0)
	(begin
	
			(set! proceed (car (gimp-image-get-layers image)))
			(if (< proceed 2)
			(begin
			(gimp-message-set-handler 0)
			(gimp-message "You must have more than one layer for this option.")
			(gimp-image-set-active-layer image drawable)
			)

	(begin
	
	(if (= useSelect FALSE)
    		(begin
		(set! origSelect (car (gimp-selection-save image)))
		(gimp-selection-none image) 
		); closure for begin useSelect FALSE
	)


	(set! counter (car (gimp-image-get-layers image)))
	(set! numLayers (car (gimp-image-get-layers image)))
	(set! allLayersRef (cadr (gimp-image-get-layers image)))
	(set! activeLayer (car (gimp-image-set-active-layer image (aref allLayersRef (- numLayers 1)))))
	(set! activeLayer (car (gimp-image-get-active-layer image))) 
	(plug-in-kaleidoscope RUN-INTERACTIVE image activeLayer 0 0 0 0)
	(if (and (= useSelect TRUE) (= delete TRUE))
		(begin
		(gimp-selection-invert image)
		(gimp-edit-clear activeLayer)
		(gimp-selection-invert image)		
			(if (= semiflatten TRUE)
				(begin
				(gimp-context-set-background backgroundColor) 
				(set! origSelect (car (gimp-selection-save image)))
				(gimp-selection-none image) 
				(plug-in-semiflatten RUN-NONINTERACTIVE image activeLayer)
				(gimp-image-select-item image 2 origSelect)
			      (gimp-image-remove-channel image origSelect)
				)
			)
		)
	)

	(set! numLayers (- numLayers 1))
	
		(while (> numLayers 0)
		(set! activeLayer (car (gimp-image-set-active-layer image (aref allLayersRef (- numLayers 1)))))
		(set! activeLayer (car (gimp-image-get-active-layer image))) 
		(plug-in-kaleidoscope RUN-WITH-LAST-VALS image activeLayer 0 0 0 0)
	(if (and (= useSelect TRUE) (= delete TRUE))
		(begin
		(gimp-selection-invert image)
		(gimp-edit-clear activeLayer)
		(gimp-selection-invert image)		
			(if (= semiflatten TRUE)
				(begin
				(gimp-context-set-background backgroundColor) 
				(set! origSelect (car (gimp-selection-save image)))
				(gimp-selection-none image) 
				(plug-in-semiflatten RUN-NONINTERACTIVE image activeLayer)
				(gimp-image-select-item image 2 origSelect)
			      (gimp-image-remove-channel image origSelect)
				)
			)
		)
	)

		(set! numLayers (- numLayers 1))
		); closure for while numLayers > 0

	(if (= useSelect FALSE)
	    (begin
	    (gimp-image-select-item image 2 origSelect)
	    (gimp-image-remove-channel image origSelect)
	    ); closure for begin useSelect FALSE
	)
	)
	)
)
)

(if (= animOption 1)
	(begin
			(set! proceed (car (gimp-image-get-layers image)))
			(if (> proceed 1)
			(begin
			(gimp-message-set-handler 0)
			(gimp-message "You can only have one layer for this option.")
			(gimp-image-set-active-layer image drawable)
			)
						
			(begin

			(set! width (car (gimp-drawable-width drawable)))
			(set! height (car (gimp-drawable-height drawable)))

			(if (or (and (or (< (/ width frames) 1) (< (/ height frames) 1)) (> direction 3))
			    (or (and (< (/ width frames) 1) (= y-dir 0)))
			    (or (and (< (/ height frames) 1) (= x-dir 0))))
			(begin
			(gimp-message-set-handler 0)
			(gimp-message "Too many frames for this image size.  Choose a smaller number.")
			(gimp-image-set-active-layer image drawable)
			)

			(begin
			(set! origSelect (car (gimp-selection-save image)))
			(gimp-selection-none image) 
			(set! step-x (* x-dir (/ width frames)))
			(set! step-y (* y-dir (/ height frames)))
			(set! offset-x step-x)
			(set! offset-y step-y)

			(set! copyLayer (car (gimp-layer-copy drawable TRUE)))
			(gimp-image-insert-layer image copyLayer 0 -1)
			(plug-in-kaleidoscope RUN-INTERACTIVE image copyLayer 0 0 0 0)
			(set! layerName (string-append "Frame " (number->string frameNum) " (" (number->string speed) "ms)" " (replace)"))
			(gimp-item-set-name copyLayer layerName)
			(set! frameNum (+ frameNum 1))

			(while (> frames 1)
			(set! copyLayer (car (gimp-layer-copy drawable TRUE)))
			(gimp-image-insert-layer image copyLayer 0 -1)
			(gimp-drawable-offset copyLayer TRUE OFFSET-BACKGROUND offset-x offset-y)
			(plug-in-kaleidoscope RUN-WITH-LAST-VALS image copyLayer 0 0 0 0)
			(set! layerName (string-append "Frame " (number->string frameNum) " (" (number->string speed) "ms)" " (replace)"))
			(gimp-item-set-name copyLayer layerName)
			(set! offset-x (+ offset-x step-x))
			(set! offset-y (+ offset-y step-y))
			(set! frameNum (+ frameNum 1))
			(set! frames (- frames 1))
			)

			(gimp-image-remove-layer image drawable)
			(gimp-image-select-item image 2 origSelect)
			(gimp-image-remove-channel image origSelect) 
		
			)
		)
	)
)
)
)
	
	
(gimp-image-undo-group-end image) 
(gimp-context-pop)

(gimp-displays-flush)

  )
)

(script-fu-register "script-fu-kaleidoscope-anim"
  "<Image>/Filters/Animation/Kaleidoscope Animation..."
  "Create an animated kaleidoscope from an existing animation or single image."
  "Art Wade"
  "Art Wade"
  "December 30, 2009"
  "RGB* GRAY*"
  SF-IMAGE       	"Image" 0
  SF-DRAWABLE    	"Drawable" 0
  SF-OPTION		"Create Kaleidoscope On" '("An Existing Animation"
								"A Single Image (Choose options below)"
								)
  SF-ADJUSTMENT	"Number of Frames" '(5 5 2000 1 10 0 1)
  SF-OPTION       "Direction to Move Layer" '( "Up"
                                   "Down"
				           "Left"
                                   "Right"
                                   "Up and Left"
                                   "Up and Right"
                                   "Down and Left"
                                   "Down and Right"
                                    )  
  SF-ADJUSTMENT 	"Animation Speed (in ms)" '(41 10 500 1 1 0 1)
  SF-TOGGLE		"Use existing selection? (Does not work with single image)" FALSE
  SF-TOGGLE		"Delete area outside of selection?" FALSE
  SF-TOGGLE		"Semi-flatten to blend transparent pixels with background color? (Only used if delete option is used)" FALSE
  SF-COLOR "Background Color (Only used if Semi-Flatten option is used)" '(255 255 255)
)


                         

