;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; SCRIPT-FU-STARRY-SKY produces an image of a nighty sky with stars at random
; version 1.01  2006.07.11
; version 1.10  2007.10.24 - Migration to Gimp 2.4
; version 1.20  2014.09.01 - Ensure compatibility with GIMP 2.6.x & 2.8.x (GnuTux) - http://gimpchat.com
;                            Adds Starry Background to existing image (previously created a new image)
;                            Properly save context and allow undo
;                            Places starry backgound at the bottom of the layer stack
;                            Keep or merge layers
;
; Copyright (c) 2006-2007 Tharsice Demand <www.td-e.com>
;
;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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
;
;Copy of the license at http://td-e.com/site/gpl.php


(define (script-fu-starry-sky image drawable smalls mediums bigs bglum bgcon keep-layers)

  (let* (
      (layer-one -1)
      (layer-two -1)
      (ii 0)
      (ns 0)
      (xs 0)
      (ys 0)
      (nm 0)
      (xm 0)
      (ym 0)
      (nb 0)
      (xb 0)
      (yb 0)
      (lum 0)
      (pixw (cons-array 3 'byte))
      (height (car (gimp-drawable-height drawable)))     ; Get Height 
      (width (car (gimp-drawable-width drawable)))       ; Get Width
    )

    (srand (realtime))
    (aset pixw 0 255)
    (aset pixw 1 255)
    (aset pixw 2 255)

;
; Save Context
; 
    (gimp-context-push)

; Start Undo Group

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

    ; Set the fg to white, bg to black
    (gimp-palette-set-foreground '(255 255 255))
    (gimp-context-set-background '(0 0 0))
    (set! layer-one (car (gimp-layer-new image width height RGB-IMAGE "Bottom" 100 NORMAL-MODE)))
    (gimp-image-add-layer image layer-one -1)
    (gimp-image-lower-layer-to-bottom image layer-one)

    (gimp-drawable-fill layer-one 1)  ;0 FG, 1 BG, 2 white

    ; generating small stars
    (while (< ns smalls)
      (set! ns (+ ns 1))
      (set! xs (rand width))
      (set! ys (rand height))
      (set! lum (+ (rand 160) 32))
      (aset pixw 0 (+ lum (rand 64)))
      (aset pixw 1 (+ lum (rand 64)))
      (aset pixw 2 (+ lum (rand 64)))
      (gimp-drawable-set-pixel layer-one xs ys 3 pixw)

      ; preparing the exit of the loop
      (set! ii (+ ii 1))
      (if (> ii 10000) (set! ns smalls))
    ) ; end of loop

    ; generating medium stars
    (set! ii 0)
    (while (< nm mediums)
      (set! nm (+ nm 1))
      (set! xm (rand (- width 1)))
      (set! ym (rand (- height 1)))
      (set! lum (+ (rand 96) 128))
      (aset pixw 0 (+ lum (rand 32)))
      (aset pixw 1 (+ lum (rand 32)))
      (aset pixw 2 (+ lum (rand 32)))
      (gimp-drawable-set-pixel layer-one xm ym 3 pixw)
      (gimp-drawable-set-pixel layer-one (+ xm 1) ym 3 pixw)
      (gimp-drawable-set-pixel layer-one xm (+ ym 1) 3 pixw)
      (gimp-drawable-set-pixel layer-one (+ xm 1) (+ ym 1) 3 pixw)

      ; preparing the exit of the loop
      (set! ii (+ ii 1))
      (if (> ii 10000) (set! nm mediums))
    ) ; end of loop

    ; generating big stars
    (set! ii 0)
    (while (< nb bigs)
      (set! nb (+ nb 1))
      (set! xb (rand (- width 2)))
      (set! yb (rand (- height 2)))
      (set! lum (+ (rand 64) 160))
      (aset pixw 0 (+ lum (rand 32)))
      (aset pixw 1 (+ lum (rand 32)))
      (aset pixw 2 (+ lum (rand 32)))
      (gimp-drawable-set-pixel layer-one xb yb 3 pixw)
      (gimp-drawable-set-pixel layer-one (+ xb 1) yb 3 pixw)
      (gimp-drawable-set-pixel layer-one (+ xb 2) yb 3 pixw)
      (gimp-drawable-set-pixel layer-one xb (+ yb 1) 3 pixw)
      (gimp-drawable-set-pixel layer-one (+ xb 1) (+ yb 1) 3 pixw)
      (gimp-drawable-set-pixel layer-one (+ xb 2) (+ yb 1) 3 pixw)
      (gimp-drawable-set-pixel layer-one xb (+ yb 2) 3 pixw)
      (gimp-drawable-set-pixel layer-one (+ xb 1) (+ yb 2) 3 pixw)
      (gimp-drawable-set-pixel layer-one (+ xb 2) (+ yb 2) 3 pixw)

      ; preparing the exit of the loop
      (set! ii (+ ii 1))
      (if (> ii 10000) (set! nb bigs))
    ) ; end of loop

    (define layer-two (car (gimp-layer-copy layer-one 1)))
    (gimp-image-add-layer image layer-two -1)
    (gimp-image-set-active-layer image layer-two)
    (plug-in-gauss-rle 1 image layer-two 3 1 1)
    (plug-in-normalize 1 image layer-two)
    (gimp-layer-set-mode layer-two SCREEN-MODE)

    (define layer-three (car (gimp-layer-copy layer-one 1)))
    (gimp-image-add-layer image layer-three -1)
    (gimp-image-set-active-layer image layer-three)
    (plug-in-gauss-rle 1 image layer-three 6 1 1)
    (plug-in-normalize 1 image layer-three)
    (gimp-layer-set-mode layer-three SCREEN-MODE)

    (define layer-four (car (gimp-layer-copy layer-one 1)))
    (gimp-image-add-layer image layer-four -1)
    (gimp-image-set-active-layer image layer-four)
    (plug-in-gauss-rle 1 image layer-four 32 1 1)
    (gimp-levels layer-four 0 0 (- 44 bgcon) 1 0 255)
    (plug-in-gauss-rle 1 image layer-four 16 1 1)
    (gimp-colorize layer-four 236 64 bglum)
    (gimp-layer-set-mode layer-four SCREEN-MODE)

    (gimp-layer-set-name layer-one "Stars")
    (gimp-layer-set-name layer-two "Stars contour")
    (gimp-layer-set-name layer-three "Stars halo")
    (gimp-layer-set-name layer-four "Sky bg")
    
    (if (= keep-layers FALSE)                            
        (begin
          (set! layer-one (car (gimp-image-merge-down image layer-two 0)))
          (set! layer-one (car (gimp-image-merge-down image layer-three 0)))
          (set! layer-one (car (gimp-image-merge-down image layer-four 0)))
        )
     )

    (gimp-displays-flush)
   
;
; End Undo Group
;
    (gimp-undo-push-group-end image)

;
; Restore Context 
;
    (gimp-context-pop)

  )
)

(script-fu-register "script-fu-starry-sky"
                    "<Image>/Filters/Render/Starry Sky..."
                    "Creates a starry sky pattern."
                    "T. Demand <td-e.com>"
                    "T. Demand & GnuTux"
                    "2007.10.24"
 			        "RGB*"
		         	SF-IMAGE       "Image"        0
        			SF-DRAWABLE    "Drawable "    0
                    SF-ADJUSTMENT _"Small stars"  '(250 20 10000 10 10 0 1)
                    SF-ADJUSTMENT _"Medium stars" '(25 2 1000 1 10 0 1)
                    SF-ADJUSTMENT _"Big stars"    '(4 1 100 1 2 0 1)
                    SF-ADJUSTMENT _"Background luminosity" '(5 0 64 1 10 0 0)
                    SF-ADJUSTMENT _"Background contrast" '(20 0 40 1 1 0 0)
                    SF-TOGGLE     _"Keep Layers"          FALSE
)

