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

(define (script-fu-indexed-decompose orig-image orig-layer)
  (gimp-image-undo-group-start orig-image)
  (gimp-context-push)
  (let* ((buffer (car (gimp-edit-named-copy orig-layer "temp")))
         (image (car (gimp-edit-named-paste-as-new buffer)))
         (layer (car (gimp-image-get-active-layer image))) )
    (gimp-buffer-delete buffer)
    (gimp-context-set-antialias TRUE) 
    (gimp-context-set-feather FALSE) 
    (gimp-context-set-feather-radius 0.0 0.0) 
    (gimp-context-set-sample-merged FALSE) 
    (gimp-context-set-sample-criterion SELECT-CRITERION-COMPOSITE) 
    (gimp-context-set-sample-threshold (/ 255)) 
    (gimp-context-set-sample-transparent FALSE) 
    (let ((offset-x (+ (car (gimp-drawable-offsets orig-layer))
                       (if (zero? (car (gimp-drawable-mask-intersect orig-layer)))
                         0
                         (cadr (gimp-drawable-mask-intersect orig-layer)) )))
          (offset-y (+ (cadr (gimp-drawable-offsets orig-layer))
                       (if (zero? (car (gimp-drawable-mask-intersect orig-layer)))
                         0
                         (caddr (gimp-drawable-mask-intersect orig-layer)) )))
          (parent (car (gimp-item-get-parent orig-layer)))
          (group (car (gimp-layer-group-new orig-image))) )
      (when (= parent -1)
        (set! parent 0) )
      (gimp-image-set-active-layer orig-image orig-layer)
      (gimp-image-insert-layer orig-image group parent -1)
      (gimp-item-set-name group "decomposed")
      (when (zero? (car (gimp-drawable-is-rgb layer)))
        (gimp-image-convert-rgb image) )
      (gimp-image-convert-indexed image NO-DITHER MAKE-PALETTE 256 0 TRUE "")
      (let* ((color-map (vector->list (cadr (gimp-image-get-colormap image))))
             (prog-max (length color-map)) )
        (let loop ((colors color-map)
                   (prog-cnt 0) )
          (gimp-progress-update (/ prog-cnt prog-max))
          (unless (null? colors)
            (let ((red (car colors))
                  (green (cadr colors))
                  (blue (caddr colors)) )
              (gimp-image-select-color image CHANNEL-OP-REPLACE layer (list red green blue))
              (let ((new-layer (car (gimp-layer-copy layer TRUE))))
                (gimp-image-insert-layer image new-layer 0 -1)
                (gimp-selection-invert image)
                (gimp-edit-clear new-layer)
                (let ((color-layer (car (gimp-layer-new-from-drawable new-layer orig-image))))
                  (gimp-layer-set-offsets color-layer offset-x offset-y)
                  (gimp-image-insert-layer orig-image color-layer group -1)
                  (gimp-drawable-set-name color-layer (string-append "RGB=[" 
                                                                     (number->string red) 
                                                                     ", " 
                                                                     (number->string green) 
                                                                     ", " 
                                                                     (number->string blue) 
                                                                     "]" )))
                (gimp-image-remove-layer image new-layer)
                (loop (cdddr colors) (+ 3 prog-cnt)) ))))))
    (gimp-context-pop)
    (gimp-progress-end)
    (gimp-image-delete image)
    (gimp-displays-flush)
    )
  (gimp-image-undo-group-end orig-image)
  )

(script-fu-register "script-fu-indexed-decompose"
 "Indexed Decompose"
 "Separate layer based on color"
 "Saul Goode"
 "Saul Goode"
 "April 2013"
 "*"
 SF-IMAGE    "Image"    0
 SF-DRAWABLE "Drawable" 0
 )
(script-fu-menu-register "script-fu-indexed-decompose"
  "<Image>/Filters/Colors"
  )
