#!/usr/bin/env python3
"""
dither.py — Retro photo processor for Dangerous Wonder

Converts JPGs in photos/ to palette-reduced, ordered-dithered PNGs
using the 216 web-safe color palette. Skips already-processed PNGs.

Usage:
    python3 dither.py              # process all unprocessed photos
    python3 dither.py --force      # re-process everything from backups
    python3 dither.py --help       # show usage
"""

import argparse
import os
import shutil
import sys
from PIL import Image

PALETTE_BYTES = []
for r in range(0, 256, 51):
    for g in range(0, 256, 51):
        for b in range(0, 256, 51):
            PALETTE_BYTES.extend([r, g, b])

PALETTE_IMG = Image.new("P", (1, 1))
PALETTE_IMG.putpalette(PALETTE_BYTES + [0, 0, 0] * (256 - 216))

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
PHOTOS_DIR = os.path.join(SCRIPT_DIR, "photos")
BACKUP_DIR = os.path.join(SCRIPT_DIR, "photos-backup")


def process_image(src_path, dst_path):
    img = Image.open(src_path).convert("RGB")
    quantized = img.quantize(palette=PALETTE_IMG, dither=Image.Dither.ORDERED)
    quantized.save(dst_path, "PNG", optimize=True)
    orig_kb = os.path.getsize(src_path) // 1024
    new_kb = os.path.getsize(dst_path) // 1024
    print(
        f"  {os.path.basename(src_path)} -> {os.path.basename(dst_path)}  "
        f"({orig_kb}KB -> {new_kb}KB)"
    )


def ensure_backup(src_path):
    os.makedirs(BACKUP_DIR, exist_ok=True)
    dst = os.path.join(BACKUP_DIR, os.path.basename(src_path))
    if not os.path.exists(dst):
        shutil.copy2(src_path, dst)


def main():
    parser = argparse.ArgumentParser(
        description="Convert photos to web-safe palette with ordered dithering"
    )
    parser.add_argument(
        "--force", action="store_true", help="Re-process all images from photos-backup/"
    )
    args = parser.parse_args()

    if args.force:
        jpgs = sorted(
            f for f in os.listdir(BACKUP_DIR) if f.lower().endswith((".jpg", ".jpeg"))
        )
        if not jpgs:
            print("No JPG files found in photos-backup/")
            sys.exit(1)
        src_dir = BACKUP_DIR
        print(f"Re-processing {len(jpgs)} images from backup...\n")
    else:
        jpgs = sorted(
            f for f in os.listdir(PHOTOS_DIR) if f.lower().endswith((".jpg", ".jpeg"))
        )
        if not jpgs:
            print("No new JPG files to process in photos/")
            sys.exit(0)
        src_dir = PHOTOS_DIR
        print(f"Processing {len(jpgs)} new image(s)...\n")

    for fname in jpgs:
        src = os.path.join(src_dir, fname)
        ensure_backup(src)

        png_name = os.path.splitext(fname)[0] + ".png"
        dst = os.path.join(PHOTOS_DIR, png_name)
        process_image(src, dst)

        if src_dir == PHOTOS_DIR:
            os.remove(src)

    print(f"\nDone. Originals in photos-backup/, dithered PNGs in photos/.")


if __name__ == "__main__":
    main()
