from typing import Tuple
from PIL import Image
import sys
import shared

TEMPLATE = """
// generated code! be nice!
#include "sys/sys.h"
sys_sprite {{spritesheet_name}}[{{n_sprites}}] = {
    {% for sprite in sprites -%}
    { .pixels={ 
        {% for row in sprite -%}
        { {{ row|join(",") }} }{% if not loop.last %},{% endif %}
        {% endfor %}
    } }{% if not loop.last %},{% endif %}
    {%- endfor %}
};
""".lstrip()


def main(spritesheet_name, n_sprites, key_color, fname_png, fname_c):
    sprites = load_sprites(fname_png, key_color)
    assert(len(sprites) == n_sprites), f"must be exactly {n_sprites} sprites"

    with open(fname_c, "wt") as output:
        output.write(
            shared.templates.from_string(TEMPLATE).render(
                spritesheet_name=spritesheet_name,
                n_sprites=n_sprites,
                sprites=sprites,
            )
        )


def load_sprites(fname_png: str, key_color: int):
    width, height, data = shared.load_image(fname_png)

    sprites = []
    for gy in range(0, height, 8):
        for gx in range(0, width, 8):
            pixels = []
            for py in range(0, 8):
                row = []
                for px in range(0, 8):
                    x = gx + px
                    y = gy + py
                    pal = pixel_to_palette(data[y * width + x], key_color, x, y)
                    row.append(pal)
                pixels.append(row)
            sprites.append(pixels)

    return sprites


palette_colors = {
    (0, 0, 0): 0,
    (29, 43, 83): 1,
    (126, 37, 83): 2,
    (0, 135, 81): 3,
    (171, 82, 54): 4,
    (95, 87, 79): 5,
    (194, 195, 199): 6,
    (255, 241, 232): 7,
    (255, 0, 77): 8,
    (255, 163, 0): 9,
    (255, 236, 39): 10,
    (0, 228, 54): 11,
    (41, 173, 255): 12,
    (131, 118, 156): 13,
    (255, 119, 168): 14,
    (255, 204, 170): 15,
}


def pixel_to_palette(rgba, key_color, x, y):
    (r, g, b, a) = rgba

    if a < 128: 
        return 255

    rgb = (r, g, b)
    ix = palette_colors.get(rgb)
    if ix is None:
        raise ValueError(f"unrecognized color at ({x}, {y}): {rgb}")

    if ix == key_color:
        return 255

    return ix


if __name__ == "__main__":
    assert len(sys.argv) == 6, \
        "there must be five args (spritesheet name, n sprites, key color, src png, out c)"
    main(sys.argv[1], int(sys.argv[2]), int(sys.argv[3]), sys.argv[4], sys.argv[5])