#!/usr/bin/env python3
"""
Turn an Aseprite file into one or several png files.
"""
import argparse
import sys
from pathlib import Path

from aseprite import AsepriteImage
from imageops import pil_image_for_cel, render_frame
from PIL import Image


def trim(image: Image) -> Image:
    box = image.getbbox()
    return image.crop(box)


def transpose_method_from_angle(angle: int):
    angle %= 360
    while angle < 0:
        angle += 360

    if angle == 90:
        return Image.ROTATE_90
    elif angle == 180:
        return Image.ROTATE_180
    elif angle == 270:
        return Image.ROTATE_270
    return None


def main():
    parser = argparse.ArgumentParser()
    parser.description = __doc__

    parser.add_argument("ase_file")
    parser.add_argument(
        "format",
        default="{title}.png",
        help="Define the name of the generated files. Supported keywords:"
        " {title}, {layer}, {frame}, {slice}",
    )
    parser.add_argument("--split-layers", action="store_true")
    parser.add_argument("--split-slices", action="store_true")
    parser.add_argument("--trim", action="store_true")
    parser.add_argument(
        "--rotate",
        type=int,
        metavar="ANGLE",
        help="Rotate image by ANGLE degrees counter-clockwise",
    )
    parser.add_argument("--dry-run", action="store_true")

    args = parser.parse_args()

    if args.rotate is not None:
        transpose_method = transpose_method_from_angle(args.rotate)
        if transpose_method is None:
            parser.error("Invalid angle value")
    else:
        transpose_method = None

    ase_file = Path(args.ase_file)

    title = ase_file.stem
    ase_image = AsepriteImage(ase_file)

    def finish_image(image, context, **extra_context_args):
        if transpose_method is not None:
            image = image.transpose(transpose_method)
        if args.trim:
            image = trim(image)

        ctx = dict(context)
        ctx.update(extra_context_args)
        path = args.format.format(**ctx)
        if args.dry_run:
            print("Would create {}".format(path))
        else:
            print("Creating {}".format(path))
            image.save(path)

    for frame_idx, frame in enumerate(ase_image.frames):
        context = dict(frame=frame_idx, title=title)
        if args.split_layers:
            for layer_idx, layer in enumerate(ase_image.layers):
                image = pil_image_for_cel(frame.cels[layer_idx])
                finish_image(image, context, layer=layer.name)
        else:
            image = render_frame(frame)
            if args.split_slices:
                for slice_ in ase_image.slices:
                    x, y = slice_.position
                    w, h = slice_.size
                    box = [x, y, (x + w), (y + h)]
                    sliced_image = image.crop(box)
                    finish_image(sliced_image, context, slice=slice_.name)
            else:
                finish_image(image, context)

    return 0


if __name__ == "__main__":
    sys.exit(main())
# vi: ts=4 sw=4 et
