#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import numpy as np
from PIL import Image, ImageDraw, ImageFont
import cv2
from time import time
import re

file = "./input.txt"
Y_TALL = 103
X_WIDE = 101
SOLUTION = 6516
#file = "./ex.txt"
#Y_TALL = 7
#X_WIDE = 11

start_time = time()
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
fps = 30
frame_size = (X_WIDE, Y_TALL)
out = cv2.VideoWriter('./solution2.mp4', fourcc, fps, frame_size)

def parse_and_go(input_file:str, seconds) -> list[list[int]]:
    global Y_TALL, X_WIDE
    field = []
    for i in range(Y_TALL):
        temp = []
        for j in range(X_WIDE):
            temp.append(0)
        field.append(temp)
    with open(input_file, 'r') as d:
        datei = d.read()
    pat = r'p\=(-?\d+),(-?\d+) v\=(-?\d+),(-?\d+)'
    match = re.findall(pat, datei)
    for m in match:
        x, y, vx, vy = map(int, m)
        # move X seconds
        x = (x + (seconds * vx)) % X_WIDE
        y = (y + (seconds * vy)) % Y_TALL
        field[y][x] += 1
    return field

def array_to_image(ar):
    # Konvertiere das Array in ein NumPy-Array
    np_array = np.array(ar)
    # Erstelle ein leeres RGB-Bild
    height, width = np_array.shape
    image = Image.new('RGB', (width, height))
    # Fülle das Bild mit Pixeln basierend auf den Array-Werten
    for y in range(height):
        for x in range(width):
            if np_array[y, x] == 0:
                image.putpixel((x, y), (0, 0, 0))  # Schwarz
            else:
                image.putpixel((x, y), (0, 255, 0))  # Grün
    return image

def add_text_to_image(image, num):
    draw = ImageDraw.Draw(image)
    font = ImageFont.truetype("arial.ttf", 20)  # Wählen Sie eine Schriftart und Größe
    draw.text((5,5), f"{num:04d}", fill=(255, 255, 255), font=font)  # Weißer Text
    return image

def pil_to_cv2(pil_image):
    return cv2.cvtColor(np.array(pil_image), cv2.COLOR_RGB2BGR)

if __name__ == "__main__":
    gif_anim=[]
    for sec in range(SOLUTION-200, SOLUTION+1): #my solution 6516
        field_s = parse_and_go(file, sec)
        img = array_to_image(field_s)
        img_with_num=add_text_to_image(img, sec)
        if sec == SOLUTION:
            for _ in range(SOLUTION, SOLUTION+200):
                gif_anim.append(img_with_num)
                cv2_image = pil_to_cv2(img_with_num)
                out.write(cv2_image)
            break
        elif sec > SOLUTION-15:
            for _ in range(sec-(SOLUTION-15)):
                gif_anim.append(img_with_num)
                cv2_image = pil_to_cv2(img_with_num)
                out.write(cv2_image)
        else:
            gif_anim.append(img_with_num)
            cv2_image = pil_to_cv2(img_with_num)
            out.write(cv2_image)
    out.release()
    gif_anim[0].save('./solution2.gif', save_all=True, append_images=gif_anim[1:],
                       optimize=False, duration=30, loop=0)
    print(f'Runtime: {time()-start_time:.2f} s')