; following steps in Silhouette Text tutorial by Issabella
; found at link: http://gimpchat.com/viewtopic.php?f=23&t=10140
; author: Tin Tran
; date: 2014
(define (script-fu-silhouette image layer 
                       silhouette-color
					   apply-curves
					   hue
					   saturation
					   lightness
					   shadow-offset-X
					   shadow-offset-Y
         )
	(let* 
	  (
	  (dummy-variable-to-make-let-happy 0)
	  (get-layers-returned-values)
	  (layers-visibility-array)     ;array of bytes to store visibility flags
	  (layers-name-vector)          ;vector to store layers' names
	  (layers-count)
	  (layers-array)
	  (current-layer)
	  (current-layer-name)
	  (layers)
	  (visibility-flag)
	  (white-layer)
	  (image-width)
	  (image-height)
	  (curve-points (make-vector 18 'integer)) ;used for curve-spline call
	  (copied-layer)
	  (working-layer-name)
	  (i)        ;loop counter
	  ) ;end of variable declaration
	  (gimp-image-undo-group-start image)                   ;undo-group in one step
	  
	  
	  (set! working-layer-name (car (gimp-item-get-name layer)))
      (set! get-layers-returned-values (gimp-image-get-layers image))
	  (set! layers-count (car get-layers-returned-values))
	  (set! layers-array (cadr get-layers-returned-values))
	  ;gets layers visibility and names and save it before hiding them all so that we can set it back later
	  (set! layers-visibility-array (cons-array layers-count 'byte))
	  (set! layers-name-vector (make-vector layers-count 'string))
	  (set! i 0)
	  (while (< i layers-count)
	      (set! current-layer (aref layers-array i))                ;set the current layer we're looking at
	      (vector-set! layers-name-vector i (car (gimp-item-get-name current-layer))) ;saves current the layer's name
		  (aset layers-visibility-array i (car (gimp-item-get-visible current-layer))) ;saves the visibility of current layer
		  (set! i (+ i 1))
	  )
	  ;hide all layers
	  (set! i 0)
	  (while (< i layers-count)
		  (gimp-item-set-visible (aref layers-array i) FALSE)
		  (set! i (+ i 1))
      )
	  
	  
	  (gimp-item-set-visible layer TRUE)   ;show the active layer selected to perform work on
	  ;perform tutorial steps here
	  ;Page 1 of tutorial
	  (gimp-image-select-item image CHANNEL-OP-REPLACE layer)
	  (set! image-width (car (gimp-image-width image)))
	  (set! image-height (car (gimp-image-height image)))
	  (set! white-layer (car (gimp-layer-new image image-width image-height
	                           RGBA-IMAGE "White" 100 NORMAL-MODE)))  ;creates layer
      (gimp-image-insert-layer image white-layer 0 0)
	  (gimp-image-set-active-layer image white-layer)
	  (gimp-context-set-foreground silhouette-color)
	  (gimp-edit-fill layer FOREGROUND-FILL)
	  (gimp-selection-shrink image 3)
	  (gimp-edit-fill white-layer WHITE-FILL)
	  (gimp-selection-none image)
	  (plug-in-gauss RUN-NONINTERACTIVE image white-layer
	                                        2 2
											1 ;1 RLE or 0 IIR
	                                        )
	  (set! layer (car (gimp-image-merge-visible-layers image 
	                                        0 ;0 EXPAND-AS-NECESSARY 1 CLIP-TO-IMAGE 2 CLIP-TO-BOTTOM-LAYER
	                         )))	
      ;page 2 of tutorial							 
	  (python-layer-fx-bevel-emboss 1
	                              image
								  layer
								  1 ;style 2 = emboss 1 = inner bevel
								  3 ;depth
								  0  ;direction 0 up 1 down
								  6 ;size
								  1  ;soften
								  90 ;angle
								  30.0 ;altitude
									5   ;gloss-contour 0 for linear 3 for cove deep 5 for gaussian
								 '(255 255 255) ;highlight color
								 MULTIPLY-MODE ;highlight mode 5 OVERLAY
								 75  ;highlight opacity
	                             '(0 0 0)   ;shadow color
								    NORMAL-MODE       ;shadow mode 3 multiply
	                              75      ;shadow opacity
								     6       ;surface contour half round
									FALSE     ; use texture
                                   "Pine" ;pattern	use clipboard from the copied step above
								   100     ;scale
								   100     ;depth
								   FALSE   ;invert
								   FALSE   ;merge with layer
      )   									
	  (set! layer (car (gimp-image-merge-visible-layers image 
	                                        0 ;0 EXPAND-AS-NECESSARY 1 CLIP-TO-IMAGE 2 CLIP-TO-BOTTOM-LAYER
	                         )))							
    
      (plug-in-bump-map 1 image layer layer 
	                              135 ;Azimuth
								  45  ;Elevation
								  3   ;Depth
								  0   ;X offset
								  0   ;Y offset
								  0   ;Waterlevel
								  0   ;Ambient
								  TRUE ;compensate for darkening
								  FALSE ;invert
								  0     ;Linear(0) Spherical(1) Sinusoidal(2)
      )
      ;page 3 of tutorial
	  (set! layer (car(gimp-image-get-layer-by-name image working-layer-name)))
	  (gimp-image-select-item image CHANNEL-OP-REPLACE layer)
	  (gimp-selection-shrink image 5)
	  (gimp-selection-feather image 5)
	  ;cut selection twice same as delete twice
	  (gimp-edit-cut layer)
	  (gimp-edit-cut layer)
	  (gimp-selection-none image)
      (plug-in-displace 1 image layer
                                  2.0 ;amount-x
                                  2.0 ;amount-y
                                  2   ;displace in X or radial direction
                                  2   ;displace in Y or tangent direction
                                layer ;displacement map for X or radial direction
                                layer ;displacement map for Y or tangent direction
								1     ;edge behavior WRAP(1) SMEAR(2) Black(3)
	  )
	  
	  (if (= apply-curves TRUE)
	  (begin
		  ;sets array to pass into curves-spline call below
		  (vector-set! curve-points 0 0)                (vector-set! curve-points 1 0)
		  (vector-set! curve-points 2  (* (/ 255 8) 1)) (vector-set! curve-points 3 255)
		  (vector-set! curve-points 4  (* (/ 255 8) 2)) (vector-set! curve-points 5 0)
		  (vector-set! curve-points 6  (* (/ 255 8) 3)) (vector-set! curve-points 7 255)
		  (vector-set! curve-points 8  (* (/ 255 8) 4)) (vector-set! curve-points 9 0)
		  (vector-set! curve-points 10 (* (/ 255 8) 5)) (vector-set! curve-points 11 255)
		  (vector-set! curve-points 12 (* (/ 255 8) 6)) (vector-set! curve-points 13 0)
		  (vector-set! curve-points 14 (* (/ 255 8) 7)) (vector-set! curve-points 15 255)
		  (vector-set! curve-points 16	255)             (vector-set! curve-points 17 0)
		  (gimp-curves-spline layer 
							  0    ;The channel to modify { HISTOGRAM-VALUE (0), HISTOGRAM-RED (1), HISTOGRAM-GREEN (2), HISTOGRAM-BLUE (3), HISTOGRAM-ALPHA (4), HISTOGRAM-RGB (5) }
							  18   ;num-points (4 <= num_points <= 34) 18 because we have 9 points
							  curve-points
		  )		
    ;page 4 of tutorial is in middle of our if check (this if check isn't in tutorial) added for user's choice friendliness
          (gimp-colorize layer hue saturation lightness)    
      ) ;end of begin block		  
      ) ;end of if apply-curves
 
      ;drop shadow doesn't need RUN-MODE like documented in procedure browser
	  (script-fu-drop-shadow image layer
	                                 shadow-offset-X ;offset X
									 shadow-offset-Y ;offset Y
									    12             ;blur radius
										'(0 0 0)     ;color
										85           ;opacity
                                        TRUE         ;allow resizing
	  )
      (set! copied-layer (car(gimp-layer-copy layer TRUE)))    ;copies the active layer
	  (gimp-image-insert-layer image copied-layer 0 0)      ;insert the copied layer into our image (on top)
      (gimp-layer-set-mode copied-layer MULTIPLY-MODE)      
	  ;DONE -----------------------------------------------------------------------
	  ;set visibility back to how it was before started running script
	  (set! i 0)
	  (while (< i layers-count)
	      (set! current-layer-name (vector-ref layers-name-vector i)) ;grabs current-layer-name as loop runs through saved vector
	      (set! current-layer (car(gimp-image-get-layer-by-name image current-layer-name))) ;sets current-layer by names saved in vectors
		  (set! visibility-flag (aref layers-visibility-array i)) ;grabs the saved visibility flag
		  (gimp-item-set-visible current-layer visibility-flag)         ;sets visibility to originally saved values
		  (set! i (+ i 1))
	  )
	  

	  
	
	(gimp-image-undo-group-end image)                     ;undo group in one step
	(gimp-displays-flush)
    ) ;end of let*
) ;end of define

(script-fu-register
  "script-fu-silhouette"         ;function name
  "<Image>/Script-Fu/Silhouette"    ;menu register
  "Creates silhouette effect."       ;description
  "Tin Tran"                          ;author name
  "copyright info and description"         ;copyright info or description
  "2014"                          ;date
  "RGB*, GRAY*"                        ;mode
  SF-IMAGE      "Image" 0                   
  SF-DRAWABLE   "Layer" 0
  SF-COLOR      "Silhouette Color"   '(24 194 244)
  SF-TOGGLE     "Apply Curves"	  TRUE
  SF-ADJUSTMENT "Colorize Hue(used if Apply Curves)"        '(187 0 360 1 10 0 0)
  SF-ADJUSTMENT "Colorize Saturation(used if Apply Curves)" '(90 0 100 1 10 0 0)
  SF-ADJUSTMENT "Colorize Lightness(used if Apply Curves)"  '(0 -100 100 1 10 0 0)
  SF-ADJUSTMENT "Drop Shadow offset X"  '(10 -4096 4096 1 50 0 0)
  SF-ADJUSTMENT "Drop Shadow offset Y"  '(10 -4096 4096 1 50 0 0)
)