#!/usr/bin/env python

from gimpfu import *
import os

def create_neon_animation(input_path, output_path, neon_color=(0, 255, 255), frame_delay=100, trail_count=5, trail_offset=5, blur_radius=20):
    # Load the logo image
    image = pdb.gimp_file_load(input_path, input_path)
    drawable = pdb.gimp_image_get_active_layer(image)

    # Ensure the image has an alpha channel
    if not pdb.gimp_layer_has_alpha(drawable):
        pdb.gimp_layer_add_alpha(drawable)

    # Duplicate the original layer for tracing
    trace_layer = pdb.gimp_layer_copy(drawable, True)
    pdb.gimp_image_insert_layer(image, trace_layer, None, -1)

    # Create a path from the visible layer
    pdb.gimp_selection_all(image)
    pdb.gimp_edit_clear(trace_layer)  # Clear duplicate layer
    pdb.gimp_path_new_from_selection(image)
    path = pdb.gimp_image_get_last_path(image)

    # Create a new layer for the neon stroke
    stroke_layer = pdb.gimp_layer_new(image, image.width, image.height, RGBA_IMAGE, "Neon Stroke", 100, NORMAL_MODE)
    pdb.gimp_image_insert_layer(image, stroke_layer, None, -1)

    # Set foreground color to neon_color
    pdb.gimp_context_set_foreground(neon_color)

    # Stroke the path onto the stroke_layer
    pdb.gimp_context_set_brush("Small (05px)")  # Ensure a soft brush is selected
    pdb.gimp_edit_stroke_path(stroke_layer, path)

    # Apply glow effect by adding a drop shadow (without offset)
    glow_layer = pdb.gimp_layer_copy(stroke_layer, True)
    pdb.gimp_image_insert_layer(image, glow_layer, None, -1)
    pdb.plug_in_drop_shadow(image, glow_layer, 0, 0, neon_color[0], neon_color[1], neon_color[2], blur_radius, 1, True, True, 0)

    # Optional: Merge stroke and glow layers for clarity
    pdb.gimp_image_merge_down(image, glow_layer, EXPAND_AS_NECESSARY)

    # Create light trails by duplicating and offsetting the glow layer
    for i in range(1, trail_count + 1):
        trail = pdb.gimp_layer_copy(glow_layer, True)
        pdb.gimp_image_insert_layer(image, trail, None, -1)
        # Offset the trail
        pdb.gimp_layer_set_offsets(trail, i * trail_offset, i * trail_offset)
        # Apply motion blur to simulate light trails
        pdb.plug_in_motion_blur(image, trail, 0, 45, blur_radius)  # Angle 45 degrees
        # Adjust opacity to create fading effect
        pdb.gimp_layer_set_opacity(trail, 100 - (i * (100 / (trail_count + 1))))

    # Organize layers for animation frames
    # Each frame will include one more trail layer
    frames = []
    base_layers = [layer for layer in image.layers if layer.name.startswith("Neon Stroke") or layer.name.startswith("Drop Shadow")]

    # Gather trail layers in order
    trail_layers = [layer for layer in image.layers if layer.name.startswith("Neon Stroke") == False and layer.name.startswith("Drop Shadow") == False]
    trail_layers = sorted(trail_layers, key=lambda l: l.offsets[0] + l.offsets[1])  # Sort by offset

    # Create frames by progressively adding trails
    for i in range(trail_count + 1):
        # Show base stroke and first i trails
        pdb.gimp_image_set_active_layer(image, stroke_layer)
        pdb.gimp_item_set_visible(stroke_layer, True)
        pdb.gimp_item_set_visible(glow_layer, True)
        for j, trail in enumerate(trail_layers):
            if j < i:
                pdb.gimp_item_set_visible(trail, True)
            else:
                pdb.gimp_item_set_visible(trail, False)
        # Duplicate visible layers into a new frame
        frame = pdb.gimp_image_duplicate(image)
        frames.append(frame)
    
    # Merge frames into one image with layers as frames
    final_image = pdb.gimp_image_new(image.width, image.height, RGB)
    for idx, frame in enumerate(frames):
        for layer in frame.layers[::-1]:  # Reverse to maintain order
            new_layer = pdb.gimp_layer_new_from_drawable(layer, final_image)
            pdb.gimp_image_insert_layer(final_image, new_layer, None, -1)
            pdb.gimp_item_set_visible(new_layer, True)
            new_layer.name = f"Frame {idx + 1} ({frame_delay}ms)"
    
    # Export as animated GIF
    pdb.file_gif_save(final_image, final_image.layers[0], output_path, output_path, 0, 0, 1, frame_delay, 1, 0)

    # Clean up
    pdb.gimp_image_delete(image)
    pdb.gimp_image_delete(final_image)

register(
    "python_fu_create_neon_animation",
    "Create Neon Sign Animation with Light Trails",
    "Automates the creation of a neon sign with light trails and tracing animation.",
    "Your Name",
    "Your Name",
    "2023",
    "<Toolbox>/Xtns/Languages/Python-Fu/Create Neon Animation...",
    "",
    [
        (PF_FILE, "input_path", "Input Logo Path", ""),
        (PF_FILE, "output_path", "Output GIF Path", ""),
        (PF_COLOR, "neon_color", "Neon Color (R, G, B)", (0, 255, 255)),
        (PF_INT, "frame_delay", "Frame Delay (ms)", 100),
        (PF_INT, "trail_count", "Number of Light Trails", 5),
        (PF_INT, "trail_offset", "Offset per Trail (px)", 5),
        (PF_INT, "blur_radius", "Blur Radius for Glow (px)", 20),
    ],
    [],
    create_neon_animation)

main()
(venv) daddy@DESKTOP-PQLPS4F:/mnt/c/Users/Jeff/logo$ python3 create_neon_animation.py
Traceback (most recent call last):
  File "/mnt/c/Users/Jeff/logo/create_neon_animation.py", line 3, in <module>
    from gimpfu import *
ModuleNotFoundError: No module named 'gimpfu'