#!/usr/bin/env python3
"""
Generate TGA texture assets for MonkeyGames WoW addon.
Creates card textures for Blackjack and chess piece textures.
WoW requires uncompressed 32-bit RGBA TGA files.
"""

import struct
import os
import math

# Output directory
OUT_DIR = os.path.dirname(os.path.abspath(__file__))

def write_tga(filename, width, height, pixels):
    """Write an uncompressed 32-bit RGBA TGA file."""
    filepath = os.path.join(OUT_DIR, filename)
    with open(filepath, 'wb') as f:
        # TGA header (18 bytes)
        f.write(struct.pack('<B', 0))      # ID length
        f.write(struct.pack('<B', 0))      # Color map type
        f.write(struct.pack('<B', 2))      # Image type (uncompressed true-color)
        f.write(struct.pack('<5B', 0,0,0,0,0))  # Color map spec
        f.write(struct.pack('<H', 0))      # X origin
        f.write(struct.pack('<H', 0))      # Y origin
        f.write(struct.pack('<H', width))  # Width
        f.write(struct.pack('<H', height)) # Height
        f.write(struct.pack('<B', 32))     # Bits per pixel
        f.write(struct.pack('<B', 8))      # Image descriptor (8 = top-left origin + 8 alpha bits)

        # Pixel data (BGRA format, top-to-bottom)
        for y in range(height):
            for x in range(width):
                r, g, b, a = pixels[y * width + x]
                f.write(struct.pack('<4B', b, g, r, a))

    print(f"  Created: {filename} ({width}x{height})")


def make_solid(width, height, color):
    """Create a solid color image."""
    return [color] * (width * height)


def blend_pixel(base, overlay):
    """Alpha-blend overlay onto base."""
    br, bg, bb, ba = base
    or_, og, ob, oa = overlay
    a = oa / 255.0
    return (
        int(br * (1-a) + or_ * a),
        int(bg * (1-a) + og * a),
        int(bb * (1-a) + ob * a),
        255
    )


def draw_rect(pixels, width, x1, y1, x2, y2, color):
    """Draw a filled rectangle."""
    for y in range(max(0, y1), min(len(pixels) // width, y2)):
        for x in range(max(0, x1), min(width, x2)):
            pixels[y * width + x] = color


def draw_border(pixels, width, height, thickness, color):
    """Draw a border around the image."""
    for y in range(height):
        for x in range(width):
            if x < thickness or x >= width - thickness or y < thickness or y >= height - thickness:
                pixels[y * width + x] = color


def draw_rounded_border(pixels, width, height, thickness, radius, color):
    """Draw a border with rounded corners."""
    for y in range(height):
        for x in range(width):
            # Check if pixel is in border region
            in_border = False
            if x < thickness or x >= width - thickness or y < thickness or y >= height - thickness:
                # Check rounded corners
                in_bounds = True
                for (cx, cy) in [(radius, radius), (width-1-radius, radius),
                                  (radius, height-1-radius), (width-1-radius, height-1-radius)]:
                    dx = abs(x - cx)
                    dy = abs(y - cy)
                    if dx > radius or dy > radius:
                        continue
                    dist = math.sqrt(dx*dx + dy*dy)
                    if dist > radius:
                        pixels[y * width + x] = (0, 0, 0, 0)  # transparent corner
                        in_bounds = False
                        break
                if in_bounds:
                    in_border = True
            if in_border:
                pixels[y * width + x] = color


def draw_circle(pixels, width, cx, cy, radius, color):
    """Draw a filled circle."""
    height = len(pixels) // width
    for y in range(max(0, cy - radius), min(height, cy + radius + 1)):
        for x in range(max(0, cx - radius), min(width, cx + radius + 1)):
            dx = x - cx
            dy = y - cy
            if dx*dx + dy*dy <= radius*radius:
                pixels[y * width + x] = blend_pixel(pixels[y * width + x], color)


def draw_diamond(pixels, width, cx, cy, size, color):
    """Draw a filled diamond shape."""
    height = len(pixels) // width
    for y in range(max(0, cy - size), min(height, cy + size + 1)):
        for x in range(max(0, cx - size), min(width, cx + size + 1)):
            if abs(x - cx) + abs(y - cy) <= size:
                pixels[y * width + x] = blend_pixel(pixels[y * width + x], color)


def draw_heart(pixels, width, cx, cy, size, color):
    """Draw a heart shape."""
    height = len(pixels) // width
    r = size * 0.5
    for y in range(max(0, cy - size), min(height, cy + size + 2)):
        for x in range(max(0, cx - size - 1), min(width, cx + size + 2)):
            dx = x - cx
            dy = y - cy
            # Top bumps (two circles)
            in_shape = False
            d1 = math.sqrt((dx + r*0.5)**2 + (dy + r*0.3)**2)
            d2 = math.sqrt((dx - r*0.5)**2 + (dy + r*0.3)**2)
            if d1 <= r or d2 <= r:
                in_shape = True
            # Bottom triangle
            if dy >= 0 and abs(dx) <= size * (1.0 - dy / (size * 1.2)):
                in_shape = True
            if in_shape:
                pixels[y * width + x] = blend_pixel(pixels[y * width + x], color)


def draw_spade(pixels, width, cx, cy, size, color):
    """Draw a spade shape (inverted heart + stem)."""
    height = len(pixels) // width
    r = size * 0.5
    for y in range(max(0, cy - size - 1), min(height, cy + size + 2)):
        for x in range(max(0, cx - size - 1), min(width, cx + size + 2)):
            dx = x - cx
            dy = y - cy
            in_shape = False
            # Bottom bumps (two circles, inverted from heart)
            d1 = math.sqrt((dx + r*0.5)**2 + (dy - r*0.2)**2)
            d2 = math.sqrt((dx - r*0.5)**2 + (dy - r*0.2)**2)
            if d1 <= r or d2 <= r:
                in_shape = True
            # Top triangle (inverted)
            if dy <= 0 and abs(dx) <= size * (1.0 + dy / (size * 1.2)):
                in_shape = True
            # Stem
            if dy > r * 0.2 and abs(dx) <= size * 0.15:
                in_shape = True
            if in_shape:
                pixels[y * width + x] = blend_pixel(pixels[y * width + x], color)


def draw_club(pixels, width, cx, cy, size, color):
    """Draw a club shape (three circles + stem)."""
    r = int(size * 0.4)
    # Three lobes
    draw_circle(pixels, width, cx, cy - int(size * 0.4), r, color)
    draw_circle(pixels, width, cx - int(size * 0.4), cy + int(size * 0.1), r, color)
    draw_circle(pixels, width, cx + int(size * 0.4), cy + int(size * 0.1), r, color)
    # Stem
    draw_rect(pixels, width, cx - int(size*0.12), cy + int(size*0.1),
              cx + int(size*0.12) + 1, cy + size, color)


# ========================================================================
# Card Back Texture (single card back design)
# ========================================================================

def generate_card_back():
    """128x128 card back with a decorative pattern."""
    w, h = 128, 128
    bg = (25, 15, 50, 255)        # Dark purple
    border_c = (80, 60, 120, 255)  # Purple border
    accent = (140, 100, 180, 200)  # Light purple accent
    inner = (35, 25, 70, 255)      # Slightly lighter inner

    pixels = make_solid(w, h, bg)
    draw_border(pixels, w, h, 3, border_c)
    draw_rect(pixels, w, 6, 6, w-6, h-6, inner)
    draw_border(pixels, w, h, 1, (60, 45, 90, 255))

    # Diamond pattern
    for y in range(8, h-8, 16):
        for x in range(8, w-8, 16):
            offset = 8 if (y // 16) % 2 == 1 else 0
            draw_diamond(pixels, w, x + offset, y, 4, accent)

    # Center diamond emblem
    draw_diamond(pixels, w, w//2, h//2, 18, (100, 70, 160, 255))
    draw_diamond(pixels, w, w//2, h//2, 12, (60, 40, 110, 255))
    draw_diamond(pixels, w, w//2, h//2, 6, accent)

    write_tga("card_back.tga", w, h, pixels)


# ========================================================================
# Suit Textures Atlas (4 suits in a 2x2 grid, 128x128 total)
# ========================================================================

def generate_suit_atlas():
    """128x128 atlas with 4 suits: hearts(TL), diamonds(TR), clubs(BL), spades(BR)."""
    w, h = 128, 128
    pixels = make_solid(w, h, (0, 0, 0, 0))  # transparent

    red = (220, 40, 40, 255)
    black = (30, 25, 20, 255)

    # Hearts (top-left quadrant, center at 32,32)
    draw_heart(pixels, w, 32, 32, 20, red)

    # Diamonds (top-right quadrant, center at 96,32)
    draw_diamond(pixels, w, 96, 32, 20, red)

    # Clubs (bottom-left quadrant, center at 32,96)
    draw_club(pixels, w, 32, 96, 20, black)

    # Spades (bottom-right quadrant, center at 96,96)
    draw_spade(pixels, w, 96, 96, 20, black)

    write_tga("suits.tga", w, h, pixels)


# ========================================================================
# Card Face Template (blank card with border, 64x96)
# ========================================================================

def generate_card_face():
    """64x96 blank card face template (cream with purple border)."""
    w, h = 64, 96
    cream = (242, 235, 220, 255)
    border_c = (70, 55, 100, 255)

    pixels = make_solid(w, h, cream)
    draw_border(pixels, w, h, 2, border_c)

    write_tga("card_face.tga", w, h, pixels)


# ========================================================================
# Chess Piece Textures (6 pieces x 2 colors = 12, in a 6x2 atlas, 384x128)
# Layout: Row 1 = White (K,Q,R,B,N,P), Row 2 = Black (K,Q,R,B,N,P)
# Each cell is 64x64
# ========================================================================

def generate_chess_atlas():
    """384x128 atlas with chess piece silhouettes."""
    cell = 64
    w, h = 6 * cell, 2 * cell
    bg = (0, 0, 0, 0)  # transparent

    pixels = make_solid(w, h, bg)

    white_color = (245, 238, 220, 255)
    white_outline = (60, 50, 40, 180)
    black_color = (35, 28, 22, 255)
    black_outline = (160, 150, 140, 180)

    piece_shapes = ['K', 'Q', 'R', 'B', 'N', 'P']

    for row, (fill, outline) in enumerate([(white_color, white_outline), (black_color, black_outline)]):
        for col, piece in enumerate(piece_shapes):
            cx = col * cell + cell // 2
            cy = row * cell + cell // 2

            if piece == 'K':
                # King: large circle with cross on top
                draw_circle(pixels, w, cx, cy + 6, 20, fill)
                draw_circle(pixels, w, cx, cy + 6, 17, outline)
                draw_circle(pixels, w, cx, cy + 6, 15, fill)
                # Cross
                draw_rect(pixels, w, cx - 2, cy - 24, cx + 3, cy - 8, fill)
                draw_rect(pixels, w, cx - 8, cy - 20, cx + 9, cy - 15, fill)
                # Base
                draw_rect(pixels, w, cx - 16, cy + 22, cx + 17, cy + 28, fill)

            elif piece == 'Q':
                # Queen: circle with crown points
                draw_circle(pixels, w, cx, cy + 4, 18, fill)
                draw_circle(pixels, w, cx, cy + 4, 15, outline)
                draw_circle(pixels, w, cx, cy + 4, 13, fill)
                # Crown points
                for dx in [-10, -5, 0, 5, 10]:
                    draw_circle(pixels, w, cx + dx, cy - 16, 4, fill)
                # Base
                draw_rect(pixels, w, cx - 16, cy + 20, cx + 17, cy + 26, fill)

            elif piece == 'R':
                # Rook: rectangle with battlements
                draw_rect(pixels, w, cx - 14, cy - 8, cx + 15, cy + 22, fill)
                draw_rect(pixels, w, cx - 11, cy - 5, cx + 12, cy + 19, outline)
                draw_rect(pixels, w, cx - 9, cy - 3, cx + 10, cy + 17, fill)
                # Battlements
                for dx in [-12, -4, 4, 12]:
                    draw_rect(pixels, w, dx + cx - 4, cy - 22, dx + cx + 3, cy - 8, fill)
                # Base
                draw_rect(pixels, w, cx - 18, cy + 22, cx + 19, cy + 28, fill)

            elif piece == 'B':
                # Bishop: tall oval with mitre point
                draw_circle(pixels, w, cx, cy + 2, 16, fill)
                draw_circle(pixels, w, cx, cy + 2, 13, outline)
                draw_circle(pixels, w, cx, cy + 2, 11, fill)
                # Mitre point
                for i in range(16):
                    px = cx - 8 + i
                    py = cy - 14 - abs(i - 8)
                    draw_rect(pixels, w, px, py, px + 1, cy - 10, fill)
                draw_circle(pixels, w, cx, cy - 24, 3, fill)
                # Base
                draw_rect(pixels, w, cx - 14, cy + 18, cx + 15, cy + 24, fill)

            elif piece == 'N':
                # Knight: offset shape suggesting horse head
                draw_circle(pixels, w, cx - 2, cy, 16, fill)
                draw_circle(pixels, w, cx - 2, cy, 13, outline)
                draw_circle(pixels, w, cx - 2, cy, 11, fill)
                # Head/snout
                draw_rect(pixels, w, cx - 14, cy - 18, cx + 2, cy - 4, fill)
                draw_circle(pixels, w, cx - 8, cy - 18, 7, fill)
                # Ear
                draw_rect(pixels, w, cx - 6, cy - 26, cx - 2, cy - 18, fill)
                # Base
                draw_rect(pixels, w, cx - 16, cy + 16, cx + 17, cy + 22, fill)

            elif piece == 'P':
                # Pawn: small circle on a base
                draw_circle(pixels, w, cx, cy - 4, 12, fill)
                draw_circle(pixels, w, cx, cy - 4, 9, outline)
                draw_circle(pixels, w, cx, cy - 4, 7, fill)
                # Neck
                draw_rect(pixels, w, cx - 4, cy + 6, cx + 5, cy + 16, fill)
                # Base
                draw_rect(pixels, w, cx - 12, cy + 16, cx + 13, cy + 24, fill)

    write_tga("chess_pieces.tga", w, h, pixels)


# ========================================================================
# Felt texture (green table cloth for blackjack)
# ========================================================================

def generate_felt():
    """128x128 green felt texture with subtle noise."""
    w, h = 128, 128
    import random
    random.seed(42)

    pixels = []
    for y in range(h):
        for x in range(w):
            noise = random.randint(-8, 8)
            r = max(0, min(255, 12 + noise))
            g = max(0, min(255, 48 + noise))
            b = max(0, min(255, 18 + noise))
            pixels.append((r, g, b, 255))

    write_tga("felt.tga", w, h, pixels)


# ========================================================================
# Main
# ========================================================================

if __name__ == "__main__":
    print("Generating MonkeyGames textures...")
    generate_card_back()
    generate_card_face()
    generate_suit_atlas()
    generate_chess_atlas()
    generate_felt()
    print("Done! All textures generated in:", OUT_DIR)
