import os
import argparse
from PIL import Image, ImageEnhance

# Any alpha pixel <= this value counts as transparency.
# 254 means "anything not pure white".
ALPHA_THRESHOLD = 254

def alpha_has_transparency(alpha_img_l, threshold=ALPHA_THRESHOLD):
    """
    alpha_img_l: PIL Image in mode 'L'
    Returns True if any pixel is < 255 (or <= threshold), meaning real transparency exists.
    Uses extrema for speed.
    """
    mn, mx = alpha_img_l.getextrema()
    return mn <= threshold

def image_has_effective_alpha(img, threshold=ALPHA_THRESHOLD):
    """
    Returns True if the image has an alpha channel AND that alpha contains any transparency.
    """
    mode = img.mode

    if mode == "RGBA":
        a = img.getchannel("A")
        mn, mx = a.getextrema()
        return mn <= threshold

    if mode == "LA":
        a = img.getchannel("A")
        mn, mx = a.getextrema()
        return mn <= threshold

    if mode == "P" and 'transparency' in img.info:
        # Convert palette images with transparency to RGBA, then test alpha.
        rgba = img.convert("RGBA")
        a = rgba.getchannel("A")
        mn, mx = a.getextrema()
        return mn <= threshold

    return False

def scale_image(img, scale_factor, scale_type):
    """Scales the image by a given factor using the specified interpolation method."""
    width, height = img.size
    new_width = int(width * scale_factor)
    new_height = int(height * scale_factor)

    scale_methods = {
        'bilinear': Image.BILINEAR,
        'bicubic': Image.BICUBIC,
        'nearest': Image.NEAREST
    }

    interpolation = scale_methods.get(scale_type, Image.BILINEAR)
    return img.resize((new_width, new_height), interpolation)

def convert_image_to_tga(image_path, tga_path, bit_depth=24, alpha=True, compression=True,
                         darken=False, alpha_image_path=None, scale=1, scale_type='bilinear'):
    with Image.open(image_path) as img:
        if bit_depth == 32 and alpha:
            img = img.convert("RGBA")
        else:
            img = img.convert("RGB")

        if darken:
            enhancer = ImageEnhance.Brightness(img)
            img = enhancer.enhance(0.5)

        if alpha and alpha_image_path:
            with Image.open(alpha_image_path) as alpha_img:
                alpha_img = alpha_img.convert("L")

                # Safety check in case caller didn't filter:
                if alpha_has_transparency(alpha_img):
                    img.putalpha(alpha_img)
                else:
                    if bit_depth != 32:
                        # Fully white mask -> don't apply alpha
                        img = img.convert("RGB")

        if scale != 1:
            img = scale_image(img, scale, scale_type)

        save_params = {'format': 'TGA', 'compress': compression}
        img.save(tga_path, **save_params)

def batch_convert_images_to_tga(input_folder, output_folder=None, bit_depth=24, alpha=True,
                                compression=True, darken=False, scale=1, scale_type='bilinear',
                                allow_uppercase=False, allow_space=False):
    if output_folder is None:
        output_folder = input_folder

    extensions = ['.png', '.jpg', '.jpeg', '.pcx', '.tga', '.bmp']
    os.makedirs(output_folder, exist_ok=True)
    input_files = os.listdir(input_folder)

    for file_name in input_files:
        if os.path.splitext(file_name)[1].lower() in extensions:
            base_name, ext = os.path.splitext(file_name)
            is_alpha_image = any(base_name.endswith(suffix) for suffix in ['_a', '_alpha', ' a', ' alpha', 'mask'])

            if is_alpha_image:
                continue

            alpha_image_path = None
            for suffix in ['_a', '_alpha', ' a', ' alpha', 'mask']:
                alpha_base_name = base_name + suffix
                for alpha_ext in extensions:
                    candidate = alpha_base_name + alpha_ext
                    if candidate in input_files:
                        alpha_image_path = os.path.join(input_folder, candidate)
                        break
                if alpha_image_path:
                    break

            image_path = os.path.join(input_folder, file_name)
            output_file_name = os.path.splitext(file_name)[0] + '.tga'

            if not allow_space:
                output_file_name = output_file_name.replace(' ', '_')
            if not allow_uppercase:
                output_file_name = output_file_name.lower()

            tga_path = os.path.join(output_folder, output_file_name)

            # --- NEW: discard separate alpha masks that are fully white ---
            if alpha and alpha_image_path:
                with Image.open(alpha_image_path) as aimg:
                    aimg_l = aimg.convert("L")
                    if not alpha_has_transparency(aimg_l):
                        alpha_image_path = None  # treat as no alpha

            current_bit_depth = bit_depth

            if alpha and alpha_image_path:
                current_bit_depth = 32
            elif alpha:
                with Image.open(image_path) as img_check:
                    if image_has_effective_alpha(img_check):
                        current_bit_depth = 32

            convert_image_to_tga(
                image_path,
                tga_path,
                current_bit_depth,
                alpha,
                compression,
                darken,
                alpha_image_path,
                scale,
                scale_type
            )
            print(f'Converted: {file_name} -> {os.path.basename(tga_path)}')

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Convert image files to TGA format with optional scaling.")
    parser.add_argument("input_folder", nargs="?", default=os.getcwd(), help="Path to input folder. Defaults to current directory.")
    parser.add_argument("output_folder", nargs="?", help="Optional output folder. Defaults to input folder.")
    parser.add_argument("--bit-depth", type=int, choices=[24, 32], default=24, help="Bit depth (24 or 32). Default is 24.")
    parser.add_argument("--no-alpha", action="store_false", dest="alpha", help="Exclude alpha channel in the TGA file.")
    parser.add_argument("--no-compression", dest="compression", action="store_false", help="Disable compression.")
    parser.add_argument("--darken", action="store_true", help="Darken image by 50%.")
    parser.add_argument("--scale", type=float, default=1, help="Scale factor for resizing. Default is 1 (no scaling).")
    parser.add_argument("--scaletype", choices=['bilinear', 'bicubic', 'nearest'], default='bilinear', help="Scaling method. Default is bilinear.")
    parser.add_argument("--allowuppercase", action="store_true", help="Allow uppercase in filenames.")
    parser.add_argument("--allowspace", action="store_true", help="Allow spaces in filenames.")
    parser.add_argument("--kingpin", action="store_true", help="Use Kingpin preset settings.")

    args = parser.parse_args()

    if args.kingpin:
        args.bit_depth = 24
        args.compression = True
        args.darken = True
        args.alpha = True
        args.allowuppercase = False
        args.allowspace = False

    batch_convert_images_to_tga(
        args.input_folder,
        args.output_folder,
        args.bit_depth,
        args.alpha,
        args.compression,
        args.darken,
        args.scale,
        args.scaletype,
        args.allowuppercase,
        args.allowspace
    )
