from PIL import Image, ImageSequence
from Point2D import generate_point_array_from_image, interpolate_point_pairs, generate_image_from_point_array, pair_points, mirror_points

# Load the two small images
image1 = Image.open("/home/cisco/CiscoTheProot/faces/eyeLeftOpen.png")
image2 = Image.open("/home/cisco/CiscoTheProot/faces/eyeLeftStunned.png")

# Generate point arrays from the images
points1 = generate_point_array_from_image(image1)
points2 = generate_point_array_from_image(image2)

# Pair the points from the two images
point_pairs = pair_points(points1, points2)

# Generate ten frames of animation
num_frames = 10
frames = []

for i in range(num_frames):
    # Interpolate the points based on the frame number
    percentage = i / (num_frames - 1)
    interpolated_points = interpolate_point_pairs(point_pairs, percentage)
    
    # Generate the image from the interpolated points
    width, height = image1.size
    frame_image = generate_image_from_point_array(interpolated_points, width, height)
    
    # Append the frame image to the list of frames
    frames.append(frame_image)

# Save the frames as separate images
for i, frame_image in enumerate(frames):
    frame_image.save(f"/home/cisco/CiscoTheProot/animations/frame_{i}.png")

# Save the frames as a GIF
gif_filename = f"/home/cisco/CiscoTheProot/animations/animation.gif"
frames[0].save(
    gif_filename,
    save_all=True,
    append_images=frames[1:]+frames[::-1],
    duration=200,  # Specify the duration between frames (in milliseconds)
    loop=0  # Set loop to 0 for an infinite loop
)

print("GIF animation saved as", gif_filename)


def generate_eye_images(emote_eye_png):
    eye_frames = []
    points_left_eye_open = generate_point_array_from_image(Image.open("faces/eyeLeftOpen.png"))
    if emote_eye_png != "faces/eyeLeftOpen.png":
        left_eye_pairs = pair_points(points_left_eye_open, generate_point_array_from_image(Image.open(emote_eye_png)))
        for i in range(11):
            eye_frames.append(interpolate_point_pairs(left_eye_pairs, i/10))
    else:
        for i in range(11):
            eye_frames.append(points_left_eye_open)
    return eye_frames


def generate_mouth_images(emote_mouth_png):
    mouth_frames = []
    points_left_mouth = generate_point_array_from_image(Image.open("faces/mouthLeft.png"))
    if emote_mouth_png != "faces/mouthLeft.png":
        left_mouth_pairs = pair_points(points_left_mouth, generate_point_array_from_image(Image.open(emote_mouth_png)))
        for i in range(11):
            mouth_frames.append(interpolate_point_pairs(left_mouth_pairs, i/10))
    else:
        for i in range(11):
            mouth_frames.append(points_left_mouth)
    return mouth_frames


def generate_nose_images(emote_nose_png):
    nose_frames = []
    points_left_nose = generate_point_array_from_image(Image.open("faces/noseLeft.png"))
    if emote_nose_png != "faces/noseLeft.png":
        left_nose_pairs = pair_points(points_left_nose, generate_point_array_from_image(Image.open(emote_nose_png)))
        for i in range(11):
            nose_frames.append(interpolate_point_pairs(left_nose_pairs, i/10))
    else:
        for i in range(11):
            nose_frames.append(points_left_nose)
    return nose_frames


def generate_face_images(emote_eye_png, emote_mouth_png, emote_nose_png):
    eye_frames = generate_eye_images(emote_eye_png)
    mouth_frames = generate_mouth_images(emote_mouth_png)
    nose_frames = generate_nose_images(emote_nose_png)
    face_images = []
    
    for frame_number in range(11):
        eyes = eye_frames[frame_number] + mirror_points(eye_frames[frame_number])
        mouth = mouth_frames[frame_number] + mirror_points(mouth_frames[frame_number])
        nose = nose_frames[frame_number] + mirror_points(nose_frames[frame_number])
        face = eyes + mouth + nose
        
        face_image = generate_image_from_point_array(face, 128, 32)
        
        face_images.append(face_image)
    
    return face_images

def save_animation_frames(animation_frames, output_file_prefix, animation_type):
    for i, frame_image in enumerate(animation_frames):
        frame_image.save(f"/home/cisco/CiscoTheProot/animations/frames/{output_file_prefix}_{i}.png")
    
    gif_filename = f"/home/cisco/CiscoTheProot/animations/gifs/{animation_type}_animation.gif"
    animation_frames[0].save(
        gif_filename,
        save_all=True,
        append_images=animation_frames[1:]+animation_frames[-1:]*10+animation_frames[::-1]+animation_frames[0:1]*10,
        duration=20,  # Specify the duration between frames (in milliseconds)
        loop=0  # Set loop to 0 for an infinite loop
    )

def animate():
    blink_animation_FrameCanvases = []
    angry_animation_FrameCanvases = []
    stun_animation_FrameCanvases = []
    
    for emote_FrameCanvasses, emote_eye_png, emote_mouth_png, emote_nose_png in [
            (blink_animation_FrameCanvases, "faces/eyeLeftClosed.png", "faces/mouthLeft.png", "faces/noseLeft.png"),
            (angry_animation_FrameCanvases, "faces/eyeLeftAngry.png", "faces/mouthLeft.png", "faces/noseLeft.png"),
            (stun_animation_FrameCanvases, "faces/eyeLeftStunned.png", "faces/mouthLeftSad.png", "faces/noseLeft.png")
            ]:
        print("generating face with features: " + emote_eye_png +" "+ emote_mouth_png +" "+ emote_nose_png)
        face_frames = generate_face_images(emote_eye_png, emote_mouth_png, emote_nose_png)
        emote_FrameCanvasses.extend(face_frames)
    
    save_animation_frames(blink_animation_FrameCanvases, "blink", "blink")
    save_animation_frames(angry_animation_FrameCanvases, "angry", "angry")
    save_animation_frames(stun_animation_FrameCanvases, "stunned", "stunned")
    
    
animate()