"""
Convert Powerups_005.png (shotgun pickup) to VB format for use as a pickup sprite.
Output: pickup_shotgun.c / pickup_shotgun.h (4x3 tiles = 32x24 pixels)
"""
import os
from PIL import Image

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
INPUT = os.path.join(SCRIPT_DIR, "make_into_4_colors_2", "converted", "frames",
                     "Powerups", "Powerups_005.png")
OUTPUT_DIR = os.path.join(SCRIPT_DIR, "src", "vbdoom", "assets", "images",
                          "sprites", "pickups")
PREVIEW_DIR = os.path.join(SCRIPT_DIR, "pickup_previews")

TILE_W, TILE_H = 4, 3
PX_W, PX_H = 32, 24
TILE_SIZE = 8

VB_PAL = {0: (0, 0, 0, 0), 1: (80, 0, 0, 255), 2: (170, 0, 0, 255), 3: (255, 0, 0, 255)}


def luminance(r, g, b):
    return int(0.299 * r + 0.587 * g + 0.114 * b)


def is_bg(r, g, b, a):
    if a < 128:
        return True
    if r < 15 and g < 15 and b < 15:
        return True
    return False


def tile_to_vb_2bpp(tile):
    """VB 2bpp sequential: each row u16 (LE), pixel 0 at bits[1:0]. Matches wall/fireball/particle pipeline."""
    data = []
    for y in range(TILE_SIZE):
        u16_val = 0
        for x in range(TILE_SIZE):
            u16_val |= (tile[y][x] << (x * 2))
        data.append(u16_val & 0xFF)
        data.append((u16_val >> 8) & 0xFF)
    return data


def bytes_to_u32(data):
    words = []
    for i in range(0, len(data), 4):
        w = data[i] | (data[i+1] << 8) | (data[i+2] << 16) | (data[i+3] << 24)
        words.append(w)
    return words


def main():
    img = Image.open(INPUT).convert('RGBA')
    w, h = img.size
    print(f"Loaded {INPUT}: {w}x{h}")

    # Find bounding box
    pix = img.load()
    min_x, min_y, max_x, max_y = w, h, 0, 0
    for y in range(h):
        for x in range(w):
            r, g, b, a = pix[x, y]
            if not is_bg(r, g, b, a):
                min_x = min(min_x, x)
                min_y = min(min_y, y)
                max_x = max(max_x, x)
                max_y = max(max_y, y)

    crop = img.crop((min_x, min_y, max_x + 1, max_y + 1))
    cw, ch = crop.size
    print(f"Bounding box: {cw}x{ch}")

    # Scale to fit 32x24
    scale = min(PX_W / cw, PX_H / ch)
    nw = max(1, int(cw * scale))
    nh = max(1, int(ch * scale))
    resized = crop.resize((nw, nh), Image.LANCZOS)

    # Center on 32x24 canvas
    canvas = [[0] * PX_W for _ in range(PX_H)]
    off_x = (PX_W - nw) // 2
    off_y = (PX_H - nh) // 2

    rpix = resized.load()
    for y in range(nh):
        for x in range(nw):
            r, g, b, a = rpix[x, y]
            dx, dy = off_x + x, off_y + y
            if dx < PX_W and dy < PX_H:
                if is_bg(r, g, b, a):
                    canvas[dy][dx] = 0
                else:
                    if r < 43:
                        canvas[dy][dx] = 1
                    elif r < 127:
                        canvas[dy][dx] = 2
                    else:
                        canvas[dy][dx] = 3

    # Save preview
    os.makedirs(PREVIEW_DIR, exist_ok=True)
    prev = Image.new('RGBA', (PX_W * 4, PX_H * 4), (0, 0, 0, 255))
    pp = prev.load()
    for y in range(PX_H):
        for x in range(PX_W):
            c = VB_PAL[canvas[y][x]]
            for sy in range(4):
                for sx in range(4):
                    pp[x*4+sx, y*4+sy] = c
    prev.save(os.path.join(PREVIEW_DIR, "pickup_shotgun.png"))

    # Slice into tiles
    all_u32 = []
    for tr in range(TILE_H):
        for tc in range(TILE_W):
            tile = []
            for y in range(TILE_SIZE):
                row = []
                for x in range(TILE_SIZE):
                    row.append(canvas[tr * TILE_SIZE + y][tc * TILE_SIZE + x])
                tile.append(row)
            all_u32.extend(bytes_to_u32(tile_to_vb_2bpp(tile)))

    # Write C file
    os.makedirs(OUTPUT_DIR, exist_ok=True)
    c_path = os.path.join(OUTPUT_DIR, "pickup_shotgun.c")
    with open(c_path, 'w') as f:
        f.write("/* Shotgun pickup sprite -- auto-generated */\n\n")
        f.write(f"const unsigned int pickup_shotgunTiles[{len(all_u32)}]"
                f" __attribute__((aligned(4))) =\n{{\n")
        for i in range(0, len(all_u32), 8):
            chunk = all_u32[i:i+8]
            s = ",".join(f"0x{w:08X}" for w in chunk)
            comma = "," if i + 8 < len(all_u32) else ""
            f.write(f"\t{s}{comma}\n")
        f.write("};\n")
    print(f"Wrote {c_path}")

    h_path = os.path.join(OUTPUT_DIR, "pickup_shotgun.h")
    with open(h_path, 'w') as f:
        f.write("#ifndef __PICKUP_SHOTGUN_H__\n#define __PICKUP_SHOTGUN_H__\n\n")
        f.write(f"extern const unsigned int pickup_shotgunTiles[{len(all_u32)}];\n\n")
        f.write("#endif\n")
    print(f"Wrote {h_path}")


if __name__ == "__main__":
    main()
