# Convert PNG/JPG icons to custom RGB565 raw format with header
# Output file format (little-endian): [uint16 width][uint16 height][pixels: width*height*2 bytes]
# Usage: python tools/convert_icons.py --src assets/icons_src --dst data/icons --size 48 48

import argparse
import os
from PIL import Image


def rgb888_to_rgb565(r, g, b):
    # Swap r/b to match display byte order used in utils::rgbTo565
    r, b = b, r
    r5 = (r * 31) // 255
    g6 = (g * 63) // 255
    b5 = (b * 31) // 255
    return (r5 << 11) | (g6 << 5) | b5


def convert_one(src_path, dst_path, out_w, out_h):
    img = Image.open(src_path).convert('RGBA')
    img = img.resize((out_w, out_h), Image.LANCZOS)

    # Premultiply against black background for simple alpha handling
    bg = Image.new('RGBA', (out_w, out_h), (0, 0, 0, 255))
    img = Image.alpha_composite(bg, img)

    # Write header + pixels
    os.makedirs(os.path.dirname(dst_path), exist_ok=True)
    with open(dst_path, 'wb') as f:
        f.write(bytes([out_w & 0xFF, (out_w >> 8) & 0xFF, out_h & 0xFF, (out_h >> 8) & 0xFF]))
        px = img.load()
        for y in range(out_h):
            for x in range(out_w):
                r, g, b, a = px[x, y]
                c = rgb888_to_rgb565(r, g, b)
                f.write(bytes([c & 0xFF, (c >> 8) & 0xFF]))
    print(f"Converted: {src_path} -> {dst_path}")


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--src', default='assets/icons_src', help='Source icon folder')
    parser.add_argument('--dst', default='data/icons', help='Destination folder in LittleFS data')
    parser.add_argument('--size', nargs=2, type=int, default=[48, 48], help='Output icon size WxH')
    args = parser.parse_args()

    out_w, out_h = args.size

    mapping = {
        'timer': 'timer.r565',
        'web': 'web.r565',
        'game': 'game.r565',
    }

    for name, out_file in mapping.items():
        src_file = os.path.join(args.src, f'{name}.png')
        if not os.path.exists(src_file):
            print(f"WARN: missing {src_file}, skip")
            continue
        dst_file = os.path.join(args.dst, out_file)
        convert_one(src_file, dst_file, out_w, out_h)

    print('Done. You can now upload FS: pio run -t uploadfs')


if __name__ == '__main__':
    main()
