#!/usr/bin/env python

from gimpfu import *
import glob
import os

class Tronify:
    def __init__(self):
        self.scale = False
        self.testMode = False
        self.chromaIn1 = (0, 0, 255)
        self.chromaIn2 = (23, 19, 207)
        self.chromaIn3 = (24, 20, 169)
        self.blueLines = (70, 172, 255)
        self.darkBlue = (47, 115, 237)
        self.greenLines = (0, 255, 0)
        self.orangeLines = (228, 188, 0)
        self.redLines = (255, 0, 0)
        self.whiteLines = (255, 255, 255)
        self.linesColor = self.blueLines
        self.linesFeather = 0
        self.monitorLines = self.orangeLines
        self.monitorFeather = 0
        # self.chromaOut = False
        self.chromaOut = (0, 0, 0)

    def tronifyImage(self, image, drawable, linesColor, chromaOut):
        self.linesColor = linesColor
        self.chromaOut = chromaOut
        if self.scale is False:
            w = pdb.gimp_image_width(image)
            h = pdb.gimp_image_height(image)
            if w == 1280: self.scale = 1 # 1280x720
            if w == 1920: self.scale = 1.5 # 1920x1080
            if w == 3840: self.scale = 3 # 3840x2160
            if self.scale is False: return
        s = self.scale
        c64Points = map(lambda x: s*x, (343, 553, 415, 570, 465, 608, 530, 720, 343, 720))

        # create channel: chroma key
        pdb.gimp_context_set_antialias(True)
        pdb.gimp_context_set_sample_criterion(SELECT_CRITERION_COMPOSITE)
        pdb.gimp_context_set_sample_threshold_int(25)
        pdb.gimp_image_select_color(image, CHANNEL_OP_REPLACE, drawable, self.chromaIn1)
        pdb.gimp_image_select_color(image, CHANNEL_OP_ADD, drawable, self.chromaIn2)
        pdb.gimp_image_select_color(image, CHANNEL_OP_ADD, drawable, self.chromaIn3)
        pdb.gimp_selection_grow(image, s*2) # encroach into the non-chroma some.
        # select-out bottom edge
        pdb.gimp_image_select_rectangle(image, CHANNEL_OP_SUBTRACT, 0, s*718, s*1280, s*2)
        channelChroma = pdb.gimp_selection_save(image)
        pdb.gimp_layer_add_alpha(drawable)
        pdb.gimp_drawable_edit_clear(drawable)

        # create channel: unitard
        pdb.gimp_context_set_antialias(False)
        pdb.gimp_context_set_sample_criterion(SELECT_CRITERION_S)
        pdb.gimp_context_set_sample_threshold_int(15)
        pdb.gimp_image_select_color(image, CHANNEL_OP_REPLACE, drawable, (255, 255, 255)) # full white
        pdb.gimp_context_set_sample_criterion(SELECT_CRITERION_H)
        pdb.gimp_context_set_sample_threshold_int(45)
        pdb.gimp_image_select_color(image, CHANNEL_OP_ADD, drawable, (206, 213, 248)) # cool white
        # shrink out face pinholes and grow past edge of unitard
        pdb.gimp_selection_shrink(image, s*3)
        pdb.gimp_selection_grow(image, s*4)
        # select out computer monitor area
        pdb.gimp_image_select_rectangle(image, CHANNEL_OP_SUBTRACT, 0, s*433, s*345, s*287)
        channelUnitard = pdb.gimp_selection_save(image)

        # # create channel: face
        # pdb.gimp_image_select_rectangle(image, CHANNEL_OP_REPLACE, 0, 0, s*1280, s*433)
        # pdb.gimp_image_select_item(image, CHANNEL_OP_SUBTRACT, channelChroma)
        # pdb.gimp_image_select_item(image, CHANNEL_OP_SUBTRACT, channelUnitard)
        # channelFace = pdb.gimp_selection_save(image)

        # create channel: lines
        # pdb.gimp_image_select_item(image, CHANNEL_OP_REPLACE, channelUnitard)
        pdb.gimp_context_set_antialias(True)
        pdb.gimp_context_set_sample_criterion(SELECT_CRITERION_V)
        pdb.gimp_context_set_sample_threshold_int(80)
        pdb.gimp_image_select_color(image, CHANNEL_OP_INTERSECT, drawable, (0, 0, 0))
        # select out the C64 keyboard
        pdb.gimp_image_select_polygon(image, CHANNEL_OP_SUBTRACT, len(c64Points), c64Points)
        # select-out bottom table edge (for some reason it gets "lined in")
        pdb.gimp_image_select_rectangle(image, CHANNEL_OP_SUBTRACT, s*503, s*718, s*777, s*2)
        # select-out right table end
        pdb.gimp_image_select_rectangle(image, CHANNEL_OP_SUBTRACT, s*1038, s*610, s*242, s*110)
        channelLines = pdb.gimp_selection_save(image)

        # create channel: remainder
        pdb.gimp_selection_all(image)
        pdb.gimp_image_select_item(image, CHANNEL_OP_SUBTRACT, channelChroma)
        # pdb.gimp_image_select_item(image, CHANNEL_OP_SUBTRACT, channelFace)
        pdb.gimp_image_select_item(image, CHANNEL_OP_SUBTRACT, channelUnitard)
        pdb.gimp_image_select_item(image, CHANNEL_OP_SUBTRACT, channelLines)
        # select-in bottom edge
        pdb.gimp_image_select_rectangle(image, CHANNEL_OP_ADD, 0, s*718, s*1280, s*2)
        channelRemainder = pdb.gimp_selection_save(image)

        # create channel: monitorLines
        pdb.gimp_context_set_antialias(True)
        pdb.gimp_context_set_sample_criterion(SELECT_CRITERION_V)
        pdb.gimp_context_set_sample_threshold_int(40)
        pdb.gimp_image_select_color(image, CHANNEL_OP_INTERSECT, drawable, (0, 0, 0))
        pdb.gimp_image_select_rectangle(image, CHANNEL_OP_SUBTRACT, s*345, 0, s*935, s*720)
        # select-out bottom edge
        pdb.gimp_image_select_rectangle(image, CHANNEL_OP_SUBTRACT, 0, s*718, s*1280, s*2)
        channelMonitorLines = pdb.gimp_selection_save(image)

        # apply chroma key mask
        if self.chromaOut is not False:
            pdb.gimp_image_select_item(image, CHANNEL_OP_REPLACE, channelChroma)
            pdb.gimp_context_set_foreground(self.chromaOut)
            pdb.gimp_edit_fill(drawable, 0)

        # apply remainder: add grainy noise and gray-ify
        pdb.gimp_image_select_item(image, CHANNEL_OP_REPLACE, channelRemainder)
        pdb.plug_in_hsv_noise(image, drawable, 4, 0, s*32, 0)
        pdb.gimp_hue_saturation(drawable, ALL_HUES, 0, -85, -100)

        # # apply face: add grainy noise and gray-ify
        # pdb.gimp_image_select_item(image, CHANNEL_OP_REPLACE, channelFace)
        # pdb.plug_in_hsv_noise(image, drawable, 4, 0, 32, 0)
        # pdb.gimp_hue_saturation(drawable, ALL_HUES, 0, -85, -100)

        # apply unitard: add grainy noise and gray-ify
        pdb.gimp_image_select_item(image, CHANNEL_OP_REPLACE, channelUnitard)
        pdb.plug_in_hsv_noise(image, drawable, 4, 0, s*64, s*64)
        pdb.gimp_colorize(drawable, 199, 11, -56)

        # lines: colorarization
        pdb.gimp_image_select_item(image, CHANNEL_OP_REPLACE, channelLines)
        pdb.gimp_context_set_foreground(self.linesColor)
        pdb.gimp_edit_fill(drawable, 0)
        pdb.script_fu_drop_shadow(image, drawable, 0, s*1, s*3.0, (0, 0, 0), 100, 0)
        pdb.gimp_selection_feather(image, s*self.linesFeather)
        pdb.gimp_edit_fill(drawable, 0)
        pdb.gimp_edit_fill(drawable, 0)

        # monitor lines: colorarization
        pdb.gimp_image_select_item(image, CHANNEL_OP_REPLACE, channelMonitorLines)
        pdb.gimp_context_set_foreground(self.monitorLines)
        pdb.gimp_edit_fill(drawable, 0)
        pdb.script_fu_drop_shadow(image, drawable, 0, s*1, s*3.0, (0, 0, 0), 100, 0)
        pdb.gimp_selection_feather(image, s*self.monitorFeather)
        pdb.gimp_edit_fill(drawable, 0)
        pdb.gimp_edit_fill(drawable, 0)

        # GUI-only stuff.
        pdb.gimp_selection_none(image)
        pdb.gimp_image_remove_channel(image, channelChroma)
        pdb.gimp_image_remove_channel(image, channelUnitard)
        # pdb.gimp_image_remove_channel(image, channelFace)
        pdb.gimp_image_remove_channel(image, channelLines)
        pdb.gimp_image_remove_channel(image, channelRemainder)
        pdb.gimp_image_remove_channel(image, channelMonitorLines)

def tronify_image(image, layerBase, r, g, b, c):
    linesColor = (r, g, b)
    chromaOut = False
    if c == 1: chromaOut = (0, 255, 0)
    if c == 2: chromaOut = (0, 0, 255)

    # GUI-only stuff.
    pdb.gimp_undo_push_group_start(image)

    # Tronify the image.
    drawable = pdb.gimp_image_get_active_layer(image)
    t = Tronify()
    t.tronifyImage(image, drawable, linesColor, chromaOut)

    # GUI-only stuff.
    pdb.gimp_undo_push_group_end(image)

register(
    "python_fu_tronify_image",
    "Tronify",
    "Create Tron-like effects",
    "David Fleming",
    "David Fleming",
    "2019",
    "Tronify...",
    "*",
    [
        (PF_IMAGE, "image", "Input image", None),
        (PF_DRAWABLE, "layerBase", "Input layer", None),
        (PF_INT, "r", "Circuits Red", 70),
        (PF_INT, "g", "Circuits Green", 172),
        (PF_INT, "b", "Circuits Blue", 255),
        (PF_INT, "c", "Chroma Out (0=none,1=green,2=blue)", 0),
    ],
    [],
    tronify_image, menu="<Image>/Filters")

main()
