"""
16x16 emerald sword on vanilla's own sword skeleton.

    python art/vanilla_sword_16.py art/emerald_sword_16_vanilla.png

Takes minecraft:item/diamond_sword straight out of the Minecraft client jar in the Gradle/Loom cache,
remaps its diamond tones to vanilla emerald tones (by brightness rank). Guard and pommel follow vanilla's
convention (same material as the blade); set IRON_GUARD = True for an iron guard. Result sits next to vanilla swords without looking like an import.
Note: this is a recolour of a Mojang texture. Fine for a private mod; if you publish, draw your own or
accept that most texture packs do exactly this.
"""
import glob
import io
import os
import sys
import zipfile

import numpy as np
from PIL import Image


def hx(h):
    return tuple(int(h[i:i + 2], 16) for i in (1, 3, 5))


# diamond_sword.png tone -> emerald.png tone, same brightness rank
BLADE = {hx("#082520"): hx("#002d00"), hx("#0e3f36"): hx("#005300"), hx("#156355"): hx("#007b18"),
         hx("#1e8a77"): hx("#00aa2c"), hx("#2bc7ac"): hx("#17dd62"), hx("#33ebcb"): hx("#41f384"),
         hx("#a4fdf0"): hx("#affdcd")}
# diamond tone -> iron_sword.png gray, same rank (used for guard + pommel)
IRON = {hx("#082520"): hx("#181818"), hx("#0e3f36"): hx("#444444"), hx("#156355"): hx("#6b6b6b"),
        hx("#1e8a77"): hx("#969696"), hx("#2bc7ac"): hx("#bebebe"), hx("#33ebcb"): hx("#d8d8d8"),
        hx("#a4fdf0"): hx("#ffffff")}
GEMS = {}   # tried gem pixels on the guard/pommel: at 16x16 a lone green pixel reads as a mistake, not a gem
IRON_GUARD = False   # vanilla makes the guard and pommel out of the blade material (diamond sword = diamond guard); follow that


def load_vanilla(name):
    jars = glob.glob(os.path.expanduser("~/.gradle/caches/fabric-loom/*/minecraft-client-only.jar"))
    if not jars:
        sys.exit("no minecraft-client-only.jar in ~/.gradle/caches/fabric-loom; run gradlew build once")
    with zipfile.ZipFile(sorted(jars)[-1]) as z:
        return np.asarray(Image.open(io.BytesIO(z.read(f"assets/minecraft/textures/item/{name}.png"))).convert("RGBA")).copy()


def is_blade(x, y):
    # the blade runs along the anti-diagonal (x + y ~ 13..17) down to row 9; below that it's guard and grip
    return (y <= 7 and 13 <= x + y <= 17) or (8 <= y <= 9 and x >= 6)


def main(out):
    img = load_vanilla("diamond_sword")
    for y in range(16):
        for x in range(16):
            c = tuple(int(v) for v in img[y, x, :3])
            if not img[y, x, 3] or c not in BLADE:      # transparent, or the wooden grip: leave alone
                continue
            img[y, x, :3] = BLADE[c] if (is_blade(x, y) or not IRON_GUARD) else IRON[c]
    for (x, y), col in GEMS.items():
        img[y, x, :3] = hx(col)
    Image.fromarray(img, "RGBA").save(out)
    print("wrote", out)


if __name__ == "__main__":
    main(sys.argv[1] if len(sys.argv) > 1 else "art/emerald_sword_16_vanilla.png")
