; FilmStrip Combine rel 0.01
; Created by Graechan
; You will need to install GMIC to run this Scipt
; GMIC can be downloaded from http://sourceforge.net/projects/gmic/files/
; Comments directed to http://gimpchat.com or http://gimpscripts.com
;
; License: GPLv3
;    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 3 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.
;
;    To view a copy of the GNU General Public License
;    visit: http://www.gnu.org/licenses/gpl.html
;
;
; ------------
;| Change Log |
; ------------ 
; Rel 0.01 - Initial Release
;
;
;find layer by name proceedure
(define (find-layer-by-name image layerName)
  (let* (
           (layerList (vector->list (cadr (gimp-image-get-layers image))))    
           (wantedLayerId -1)
		   (layerId 0)
           (layerText "")
        )
       
        (while (not (null? layerList))
          (set! layerId (car layerList))
		  (set! layerText (cond ((defined? 'gimp-image-get-item-position) (car (gimp-item-get-name layerId)))
		                  (else (car (gimp-drawable-get-name layerId)))))
          (if (string=? layerText layerName) (set! wantedLayerId layerId))          
          (set! layerList (cdr layerList))) ;endwhile        
        (if (= -1 wantedLayerId) (error (string-append "Could not find a layer with name:- " layerName)))
        (list wantedLayerId)
  ) ;end variables
) ;end find layer by name proceedure
;
;
; include layer Procedure
(define (include-layer image newlayer oldlayer stack)	;stack 0=above 1=below
	(cond ((defined? 'gimp-image-get-item-position) ;test for 2.8 compatability
            (gimp-image-insert-layer image newlayer (car (gimp-item-get-parent oldlayer)) 
			(+ (car (gimp-image-get-layer-position image oldlayer)) stack))                                     ;For GIMP 2.8 
          )
          (else
           (gimp-image-add-layer image newlayer (+ (car (gimp-image-get-layer-position image oldlayer)) stack)) ;For GIMP 2.6 
          )
    ) ;end cond
) ;end add layer procedure

(define (script-fu-filmstrip-combine inDir)

 (let* (
        (image (car (gimp-image-new 256 256 RGB)))
		(layer 0)
		(pasted 0)
		(width 0)
		(height 0)
		(drawable 0)
		(file-list 0)
		(loadfile 0)
		(img 0)
		(drawable-width 0)
		(drawable-height 0)
		(cnt 4)
		(n 0)
		(layer0 0)
		(layer1 0)
		(layer2 0)
		(layer3 0)
       )
    
;	(set! file-list (cadr (file-glob (string-append inDir DIR-SEPARATOR "*.jpg") 1)))
	(set! file-list
  (let loop ((patterns '("*.[Jj][Pp][Gg]" "*.[Pp][Nn][Gg]")) ;If you want to be case insensitive, use '("*.[Jj][Pp][Gg]" "*.[Pp][Nn][Gg]") for the patterns.
             (names '()) )
    (if (null? patterns)
      names
      (loop (cdr patterns)
            (append names (cadr (file-glob (string-append inDir DIR-SEPARATOR (car patterns)) 1))) ))))
			

    (while (not (null? file-list)) 
 
        (set! loadfile (car file-list))
        (set! img (car (gimp-file-load RUN-NONINTERACTIVE loadfile loadfile)))
		(set! width (car (gimp-image-width img)))
		(set! height (car (gimp-image-height img)))
		
        	
    
	(set! layer (car (gimp-layer-new image (car (gimp-image-width img)) (car (gimp-image-height img)) RGBA-IMAGE "Frame" 100 NORMAL-MODE)))
    (gimp-image-add-layer image layer 0)
	(gimp-edit-copy-visible img)
	(set! pasted (car (gimp-edit-paste layer FALSE)))
	(gimp-floating-sel-anchor pasted)

    (gimp-image-delete img)
;	(gimp-display-new image)
	(set! file-list (cdr file-list))
	)
	(gimp-image-resize-to-layers image)
	(set! drawable (car (gimp-image-get-active-layer image)))
	
	(Stitch-layers image drawable
                       0 ;overlap 
					   FALSE ;top-on-right 
					   FALSE) ;use-mask
	
	(set! drawable (car (gimp-image-get-active-layer image)))
	(set! drawable-width (car (gimp-drawable-width drawable)))
	(set! drawable-height (car (gimp-drawable-height drawable)))
	(gimp-image-resize image drawable-width (* drawable-height 3.5) 0 0)
	(set! width (car (gimp-image-width image)))
	(set! height (car (gimp-image-height image)))
	
	(while (> cnt 0)
	(set! layer0 (car (gimp-layer-copy drawable TRUE)))
	(gimp-image-add-layer image layer0 1)
	(gimp-drawable-set-name layer0 (string-append "layer" (number->string n)))
	(set! n (+ n 1))
	(set! cnt (- cnt 1))
	)
	(set! layer0 (car (find-layer-by-name image "layer0")))
	(set! layer1 (car (find-layer-by-name image "layer1")))
	(set! layer2 (car (find-layer-by-name image "layer2")))
	(set! layer3 (car (find-layer-by-name image "layer3")))
		
	(gimp-layer-set-offsets layer0 0 drawable-height)
	(gimp-desaturate-full layer0 0) ;{ DESATURATE-LIGHTNESS (0), DESATURATE-LUMINOSITY (1), DESATURATE-AVERAGE (2) }
	
	(gimp-layer-set-offsets layer1 0 (* drawable-height 1.75))
	(gimp-desaturate-full layer1 0) ;{ DESATURATE-LIGHTNESS (0), DESATURATE-LUMINOSITY (1), DESATURATE-AVERAGE (2) }
	
	(gimp-layer-set-offsets layer2 0 (* drawable-height 2.25))
	(gimp-desaturate-full layer2 0) ;{ DESATURATE-LIGHTNESS (0), DESATURATE-LUMINOSITY (1), DESATURATE-AVERAGE (2) }
	
	(gimp-layer-set-offsets layer3 0 (- height drawable-height))
	
	(plug-in-colorify 0 image drawable '(255 255 129))
	
	(set! drawable (car (gimp-image-merge-visible-layers image  EXPAND-AS-NECESSARY))) 
	
	(gimp-display-new image)
	
 )
) 

(script-fu-register "script-fu-filmstrip-combine"        		    
  "FilmStrip Combine"
  "Select a directory with approx 5 equal sized JPG or PNG images"
  "Graechan for Mackenzieh"
  "Graechan - http://gimpchat.com"
  "June 2014"
  ""
  SF-DIRNAME        "Load pictures from" "(none)"
)

(script-fu-menu-register "script-fu-filmstrip-combine" "<Image>/Script-Fu/Effects/")

(define (Stitch-layers img drawable
                                   overlap top-on-right use-mask)
  ;; Calculate the size for the new image
  (let* ((layers (gimp-image-get-layers img))
         (num-layers (car layers))
         (layer-array (cadr layers))
         (bottomlayer (aref layer-array (- num-layers 1)))
         ; Pandora assumes that all layers are the same size as the first:
         ; XXX change this eventually.
         (layer-w (car (gimp-drawable-width bottomlayer)))
         (layer-h (car (gimp-drawable-height bottomlayer)))
		 (width layer-w)
		 (height (/ layer-h (car (gimp-image-get-layers img))))
		 (area (* width height))
         (overlap-frac (/ overlap 100))
         (extra-frac (- 1.0 overlap-frac))
         (hslop (/ layer-w 4))
         (vslop (/ (* hslop 3) 2))
         (pan-img-w (* layer-w (+ 1 (* (- num-layers .3) (- 1 overlap-frac)))))
         (pan-img-h (+ layer-h vslop))
         (newy (/ vslop 2))
         (i (- num-layers 1) 1)    ; start from the bottom layer
         )
    ;(gimp-message (number->string pan-img-w))
    (gimp-image-undo-group-start img)
    (gimp-image-resize img pan-img-w pan-img-h 0 0)

    ;; Loop over the layers starting with the second, moving each one.
    ;; Layers are numbered starting with 0 as the top layer in the stack.
    ;(gimp-layer-translate bottomlayer 0 newy)
    (gimp-context-push)
    (while (>= i 0)
           ;(gimp-message (number->string i))
           (let* ((thislayer (aref layer-array i))
                  (thislayer-w (car (gimp-drawable-width thislayer)))
                  (newx (if (= top-on-right TRUE)
                            (* (- (- num-layers i) 1)
                               (* thislayer-w extra-frac))
                            (* i (* thislayer-w extra-frac))
                            ))
                  )
             (if (= (car (gimp-layer-is-floating-sel thislayer)) FALSE)
                 (prog1
                  (gimp-layer-translate thislayer newx newy)
                  (if (and (= use-mask TRUE)
                           (= (car (gimp-layer-get-mask thislayer)) -1)
                           (not (= i (- num-layers 1))))
                      (let* ((masklayer (car (gimp-layer-create-mask
                                              thislayer ADD-BLACK-MASK)))
                             (grad-w (* (* layer-w overlap-frac) .5))
                             (grad-start (if (= top-on-right TRUE)
                                             grad-w
                                             (- thislayer-w grad-w)))
                             (grad-end (if (= top-on-right TRUE)
                                           0 thislayer-w))
                             )
                        (gimp-layer-add-alpha thislayer)
                        (gimp-layer-add-mask thislayer masklayer)
                        (gimp-context-set-foreground '(255 255 255))
                        (gimp-context-set-background '(0 0 0))
                        (gimp-edit-blend masklayer FG-BG-RGB-MODE NORMAL-MODE
                                         GRADIENT-LINEAR 100 0 REPEAT-NONE FALSE
                                         FALSE 0 0 TRUE
                                         grad-start 0 grad-end 0)
                        (gimp-layer-set-edit-mask thislayer FALSE)
                        ))))
             )
           (set! i (- i 1))
           )
		   
	(set! drawable (car (gimp-image-merge-visible-layers img EXPAND-AS-NECESSARY)))
	(gimp-image-resize-to-layers img)
;;;;scale image to given area if required	
	(gimp-image-scale-full img 
		(max 1 (min 262144 (round (* width (sqrt (/ area (* width height)))))))
		(max 1 (min 262144 (round (* height (sqrt (/ area (* width height)))))))3)	
    (gimp-context-pop)
    (gimp-image-undo-group-end img)
    (gimp-displays-flush)
    )
)