#!/usr/bin/env python3
"""
apply_colony_translations.py — Overlay Hungarian text on Rogue Colonies tile PNGs.

Colony tiles are landscape-oriented boards (approx. 750 x 500 px at print resolution).
Layout regions are estimated based on the standard TFM colony tile design:
  - Name band:         top strip, full width
  - Placement bonus:   left column, upper half
  - Colony bonus:      left column, lower half
  - Trade income:      right column / bottom strip
  - Flavor text:       bottom strip

Source tiles: source/High_Orbit/Rogue_Colonies_v2/*.png
Output:       output/colonies/

Usage:
    python apply_colony_translations.py              # process all colonies
    python apply_colony_translations.py --test       # one colony -> output/colonies/test/
    python apply_colony_translations.py --colony "Titania"  # single colony by name
"""

import os
import sys
import glob
import json
import argparse
from PIL import Image, ImageDraw, ImageFont

# ---------------------------------------------------------------------------
# Paths
# ---------------------------------------------------------------------------
BASE_DIR          = r"C:\progik\forditsunk"
SOURCE_DIR        = os.path.join(BASE_DIR, "source", "High_Orbit", "Rogue_Colonies_v2")
OUTPUT_DIR        = os.path.join(BASE_DIR, "output", "colonies")
FONTS_DIR         = r"C:\Windows\Fonts"
TRANSLATIONS_FILE = os.path.join(BASE_DIR, "translations", "colonies.json")

FONT_TITLE  = os.path.join(FONTS_DIR, "arialbd.ttf")    # Arial Bold — name
FONT_BODY   = os.path.join(FONTS_DIR, "calibri.ttf")    # Calibri — body text
FONT_FLAVOR = os.path.join(FONTS_DIR, "georgiaz.ttf")   # Georgia Bold Italic — flavor

# ---------------------------------------------------------------------------
# Colony tile geometry
# These are estimates based on typical TFM colony tile dimensions (~750x500 px).
# If source tiles are a different size, adjust the regions proportionally.
# Region format: (x1, y1, x2, y2)
# ---------------------------------------------------------------------------

# Name band — top strip
REGION_NAME           = (10,   8,  740,  52)

# Placement bonus — upper-left text area (below icon zone)
REGION_PLACEMENT      = (10,  180,  340, 310)

# Colony bonus — lower-left text area
REGION_COLONY         = (10,  320,  340, 420)

# Trade income — right-side label above the income track
REGION_TRADE          = (360, 200,  740, 310)

# Special rule — bottom-left strip (used for Psyche only)
REGION_SPECIAL        = (10,  430,  740, 480)

# Flavor text — bottom strip
REGION_FLAVOR         = (10,  430,  740, 490)

# Colors
BG_NAME     = (60,  60,  90)    # dark blue-gray — typical colony name band
BG_BODY     = (200, 200, 200)   # light gray body areas
BG_FLAVOR   = (180, 180, 180)   # slightly darker flavor strip
COLOR_NAME  = (240, 240, 240)   # light text on dark name band
COLOR_DARK  = (25,  25,  25)    # near-black body text

# Font sizes
SIZE_NAME   = 26
SIZE_BODY   = 16
SIZE_FLAVOR = 15


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

def load_font(path, size):
    try:
        return ImageFont.truetype(path, size)
    except Exception as e:
        print(f"  Warning: could not load {path}: {e}. Using default font.")
        return ImageFont.load_default()


def wrap_to_lines(text, font, max_px, draw):
    """Word-wrap text to fit within max_px. Returns list of strings."""
    words = text.split()
    lines = []
    current = []
    for word in words:
        test = " ".join(current + [word])
        bb = draw.textbbox((0, 0), test, font=font)
        if bb[2] <= max_px:
            current.append(word)
        else:
            if current:
                lines.append(" ".join(current))
            current = [word]
    if current:
        lines.append(" ".join(current))
    return lines


def draw_region(img, region, paragraphs, font, bg_color, text_color,
                halign="center", valign="center", pad_x=8, pad_y=5, line_gap=3):
    """Fill region with bg_color, then render wrapped paragraphs of text."""
    x1, y1, x2, y2 = region
    draw = ImageDraw.Draw(img)
    draw.rectangle([x1, y1, x2, y2], fill=bg_color)

    if not paragraphs or all(not p for p in paragraphs):
        return

    max_w = x2 - x1 - 2 * pad_x
    sample_bb = draw.textbbox((0, 0), "Ag", font=font)
    line_h = (sample_bb[3] - sample_bb[1]) + line_gap

    all_lines = []
    for i, para in enumerate(paragraphs):
        if not para:
            continue
        wrapped = wrap_to_lines(para, font, max_w, draw)
        all_lines.extend(wrapped)
        if i < len(paragraphs) - 1:
            all_lines.append("")

    if not all_lines:
        return

    total_h = len(all_lines) * line_h
    region_h = y2 - y1 - 2 * pad_y

    if valign == "center":
        y = y1 + pad_y + max(0, (region_h - total_h) // 2)
    else:
        y = y1 + pad_y

    for line in all_lines:
        if not line:
            y += line_h
            continue
        bb = draw.textbbox((0, 0), line, font=font)
        tw = bb[2] - bb[0]
        if halign == "center":
            x = x1 + (x2 - x1 - tw) // 2
        else:
            x = x1 + pad_x
        draw.text((x, y), line, font=font, fill=text_color)
        y += line_h


def find_source_files(file_glob):
    """Return sorted list of PNGs matching the glob pattern in SOURCE_DIR."""
    pattern = os.path.join(SOURCE_DIR, file_glob)
    return sorted(glob.glob(pattern))


# ---------------------------------------------------------------------------
# Main processing
# ---------------------------------------------------------------------------

def process_colony(colony_name, data, out_dir, test_mode=False):
    files = find_source_files(data["file_glob"])
    if not files:
        print(f"  [WARN] No files found for: {colony_name} (glob: {data['file_glob']})")
        return 0

    if test_mode:
        files = files[:1]

    font_name   = load_font(FONT_TITLE,  SIZE_NAME)
    font_body   = load_font(FONT_BODY,   SIZE_BODY)
    font_flavor = load_font(FONT_FLAVOR, SIZE_FLAVOR)

    count = 0
    for src_path in files:
        img = Image.open(src_path).convert("RGBA")

        # --- Colony name ---
        draw_region(
            img, REGION_NAME,
            [data["name"].upper()],
            font_name, BG_NAME, COLOR_NAME,
            halign="center", valign="center",
        )

        # --- Placement bonus ---
        if data.get("placement_bonus"):
            draw_region(
                img, REGION_PLACEMENT,
                [data["placement_bonus"]],
                font_body, BG_BODY, COLOR_DARK,
                halign="left", valign="top",
            )

        # --- Colony bonus ---
        if data.get("colony_bonus"):
            draw_region(
                img, REGION_COLONY,
                [data["colony_bonus"]],
                font_body, BG_BODY, COLOR_DARK,
                halign="left", valign="top",
            )

        # --- Trade income ---
        if data.get("trade_income"):
            draw_region(
                img, REGION_TRADE,
                [data["trade_income"]],
                font_body, BG_BODY, COLOR_DARK,
                halign="center", valign="center",
            )

        # --- Special rule (Psyche) — overlays the flavor region ---
        if data.get("special_rule"):
            draw_region(
                img, REGION_SPECIAL,
                [data["special_rule"]],
                font_body, BG_BODY, COLOR_DARK,
                halign="left", valign="top",
            )
        elif data.get("flavor"):
            # --- Flavor text ---
            draw_region(
                img, REGION_FLAVOR,
                [data["flavor"]],
                font_flavor, BG_FLAVOR, COLOR_DARK,
                halign="center", valign="center",
            )

        # Save
        fname = os.path.basename(src_path)
        out_path = os.path.join(out_dir, fname)
        img.save(out_path, "PNG")
        count += 1
        print(f"    -> saved: {fname}")

    return count


def main():
    # Gracefully handle missing source directory
    if not os.path.isdir(SOURCE_DIR):
        print(f"Source directory not found: {SOURCE_DIR}")
        print("Place the Rogue_Colonies_v2 tile PNGs there and re-run.")
        sys.exit(0)

    parser = argparse.ArgumentParser(
        description="Overlay Hungarian text on Rogue Colonies tile PNGs"
    )
    parser.add_argument("--test", action="store_true",
                        help="Test mode: process one file per colony -> output/colonies/test/")
    parser.add_argument("--colony", type=str, default=None,
                        help="Process only one colony by name (e.g. 'Titania')")
    args = parser.parse_args()

    translations = json.load(open(TRANSLATIONS_FILE, encoding="utf-8"))

    out_dir = os.path.join(OUTPUT_DIR, "test") if args.test else OUTPUT_DIR
    os.makedirs(out_dir, exist_ok=True)

    to_process = translations
    if args.colony:
        key = args.colony
        if key not in translations:
            matches = [k for k in translations if k.lower() == key.lower()]
            if matches:
                key = matches[0]
            else:
                print(f"Colony '{args.colony}' not found in translations.")
                print(f"Available: {list(translations.keys())}")
                sys.exit(1)
        to_process = {key: translations[key]}

    total = 0
    for colony_name, data in to_process.items():
        print(f"Processing: {colony_name}...")
        n = process_colony(colony_name, data, out_dir, test_mode=args.test)
        print(f"  -> {n} file(s) saved")
        total += n

    print(f"\nDone. {total} tile(s) saved to: {out_dir}")


if __name__ == "__main__":
    main()
