#!/usr/bin/env python3

"""
32blit asset file format (extension always .blit)

12 byte common header

- 8: Type of file identifier ("SPRITE  ", "MAP     ", "SONG    ", "SFX     ")
- 4: Total file size

SPRITE header

- 2: Sprite width
- 2: Sprite height
- 2: Sprite columns
- 2: Sprite rows
- 1: Format (RGBA, RGB, 8-bit palette, 6-bit palette + 2-bit alpha)
- 1: Palette size (if relevant)
- 1: Palette transparent colour index
- X * 4: Pallete entries (where X = number of palette entries)
- Y: Image data

Unpaletted - RGB, RGBA
Paletted - packed 2bpp (4 colours), 3bpp (8 colours), 4bpp (16 colours), etc
"""

import argparse
import math
import sys

from bitstring import BitArray
from construct import this, Struct, Int8ul, Int16ul, Array, PrefixedArray, Computed, Switch, GreedyBytes, Enum, PaddedString
from PIL import Image, ImagePalette


def compute_bit_length(ctx):
    """Compute the required bit length for image data.

    Uses the count of items in the palette to determine how
    densely we can pack the image data.

    """
    if ctx.format == SpriteFormat.enum.p:
        return (len(ctx.palette.colours) - 1).bit_length()
    elif ctx.format == SpriteFormat.enum.rgba:
        return 8 * 4
    elif ctx.format == SpriteFormat.enum.rgb:
        return 8 * 3
    else:
        return 0


def compute_data_length(ctx):
    """Compute the required data length for palette based images.

    We need this computation here so we can use `math.ceil` and
    byte-align the result.

    """
    if ctx.format == SpriteFormat.enum.p:
        return math.ceil((ctx.width * ctx.height * ctx.bit_length) / 8)
    else:
        return ctx.width * ctx.height


class SmartEnum(Enum):
    """Fudge to support SpriteFormat.enum.p etc"""
    def __init__(self, *args, **kwargs):
        Enum.__init__(self, *args, **kwargs)

        class x():
            pass
        self.enum = x()
        for e in self.encmapping.keys():
            self.enum.__dict__[e] = e


AssetType = Enum(PaddedString(8, "utf8"), sprite='SPRITE', map='MAP', song='SONG', sfx='SFX')

SpriteFormat = SmartEnum(
    Int8ul,
    rgba=0,
    rgb=1,
    p=2
)

asset_rgba = Struct(
    'r' / Int8ul,
    'g' / Int8ul,
    'b' / Int8ul,
    'a' / Int8ul
)

asset_rgb = Struct(
    'r' / Int8ul,
    'g' / Int8ul,
    'b' / Int8ul
)

asset_sprite = Struct(
    'width' / Int16ul,
    'height' / Int16ul,
    'columns' / Int16ul,
    'rows' / Int16ul,
    'format' / SpriteFormat,
    'palette' / Struct(
        'colours' / PrefixedArray(Int8ul, asset_rgba),
    ),
    'bit_length' / Computed(compute_bit_length),
    'data_length' / Computed(compute_data_length),
    'data' / Switch(this.format, {
        'rgba': Array(this.data_length, asset_rgba),
        'rgb': Array(this.data_length, asset_rgb),
        'p': Array(this.data_length, Int8ul)
    })
)

asset = Struct(
    'header' / Struct(
        'type' / AssetType,
        'size' / Int16ul,
    ),
    'data' / GreedyBytes
)

typemap = {
    'sprite': asset_sprite
}


def unpack_asset(asset_data):
    unpacked = asset.parse(asset_data)
    builder = typemap[unpacked.header.type]
    return builder.parse(unpacked.data)


def build_asset(asset_type, asset_data):
    builder = typemap[asset_type]
    packed = builder.build(asset_data)
    return asset.build(dict(
        header=dict(
            type=asset_type,
            size=len(packed) + asset.header.sizeof(),
        ),
        data=packed
    ))


def color(r, g, b, a=None):
    a = 0xff if a is None else a
    return dict(r=r, g=g, b=b, a=a)


"""
class color():

    def __init__(self, r, g, b, a=None):
        a = 0xff if a is None else a
        self.r = r
        self.g = g
        self.b = b
        self.a = a

    def rgba(self):
        return (self.r, self.g, self.b, self.a)

    def rgba_dict(self):
        return {'r': self.r, 'g': self.g, 'b': self.b, 'a': self.a}

    def __eq__(self, other):
        return self.rgba() == other.rgba()

    def __iter__(self):
        return self.rgba_dict().__iter__()
"""


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--nowarn', action='store_true', help='Suppress deprecation warning')
    subparsers = parser.add_subparsers(help='Commands', dest='command')
    parser_sprite = subparsers.add_parser('sprite', help='Process an image file into a 32blit asset')
    parser_map = subparsers.add_parser('map', help='Process a map file into a 32blit asset')

    parser.add_argument('--out', type=str, help='set output filename (default <inputfile>.blit)', default=None)
    parser.add_argument('file', type=str, help='input file')

    # TODO: Right now unpacked data is ridiculously huge and probably impractical to use,
    # either we need a hard limit on the size of assets built in RGBA or RGB native formats (24/32bpp)
    # or drop output format altogether.
    parser_sprite.add_argument('--format', type=str, choices=('RGB', 'RGBA', 'P'), help='data output format (UNIMPLEMENTED)')

    # The engine presently only supports 8x8 tile sizes
    parser_sprite.add_argument('--tilesizex', type=int, help='tile size x', default=8)
    parser_sprite.add_argument('--tilesizey', type=int, help='tile size y', default=8)

    # A palette file should be a PNG file containing a series of pixels in the desired colours and order of the output palette.
    # If it's indexed, 8bpp colour then its palette will be used directly, otherwise the pixel data will be converted automatically.
    parser_sprite.add_argument('--palette', type=str, help='image or palette file', default=None)

    parser_map.add_argument('--sizex', type=int, help='map size x')
    parser_map.add_argument('--sizey', type=int, help='map size y')

    args = parser.parse_args()

    if not args.nowarn:
        print('''
This tool has been deprecated in favour of https://github.com/pimoroni/32blit-tools
Run with --nowarn to hide this message.
''')

    def load_palette(image):
        palette_colours = []

        if image.palette is None:
            # Divine the palette from the individual pixels in the image
            # they will be inserted into our target palette in the order
            # found in the palette image
            mode = image.mode
            w, h = image.size

            if mode in ['RGB', 'RGBA']:
                for y in range(h):
                    for x in range(w):
                        # The spread operator will take both RGB and RGBA
                        # tuples and pass them into color() properly.
                        c = color(*image.getpixel((x, y)))
                        if c not in palette_colours:
                            palette_colours.append(c)

            else:
                raise RuntimeError(f"Unsupported image mode: {mode}")

        else:
            mode, palette = image.palette.getdata()
            palette = list(palette)
            if mode == 'RGB':
                for x in range(len(palette) // 3):
                    r, g, b = palette[x * 3:(x * 3) + 3]
                    palette_colours.append(color(r, g, b))

            elif mode == 'RGBA':
                for x in range(len(palette) // 4):
                    r, g, b, a = palette[x * 4:(x * 4) + 4]
                    palette_colours.append(color(r, g, b, a))

        if len(palette_colours) > 255:
            raise RuntimeError(f"Too many colours in palette! ({len(palette_colours)})")

        return palette_colours

    if args.command == 'sprite':

        source_image = Image.open(args.file)
        target_image = source_image
        source_mode = source_image.mode
        source_palette_colours = load_palette(source_image)
        target_palette_colours = source_palette_colours

        bit_length = (len(source_palette_colours) - 1).bit_length()

        if source_mode == 'P':
            if args.palette is not None:
                palette_image = Image.open(args.palette)
                target_palette_colours = load_palette(palette_image)

                w, h = source_image.size
                for y in range(h):
                    for x in range(w):
                        p = source_image.getpixel((x, y))
                        c = source_palette_colours[p]
                        try:
                            new_p = target_palette_colours.index(c)
                            target_image.putpixel((x, y), new_p)
                        except ValueError:
                            raise RuntimeError("Colour {},{},{},{} not found in target palette!".format(*c.rgba()))

                source_palette_colours = target_palette_colours
        else:
            target_image = Image.new('P', source_image.size)
            w, h = source_image.size
            for y in range(h):
                for x in range(w):
                    if source_mode == 'RGBA':
                        r, g, b, a = source_image.getpixel((x, y))
                        c = color(r, g, b, a)
                    elif source_mode == 'RGB':
                        r, g, b = source_image.getpixel((x, y))
                        c = color(r, g, b)

                    try:
                        new_p = target_palette_colours.index(c)
                        target_image.putpixel((x, y), new_p)
                    except ValueError:
                        raise RuntimeError("Colour {},{},{},{} not found in target palette!".format(*c.rgba()))



        packed_image_data = BitArray().join(BitArray(uint=x, length=bit_length) for x in target_image.tobytes()).tobytes()

        packed = build_asset(
            'sprite',
            dict(
                width=target_image.width,
                height=target_image.height,
                columns=target_image.width // args.tilesizex,
                rows=target_image.height // args.tilesizey,
                format='p',
                palette=dict(
                    colours=source_palette_colours
                ),
                data=packed_image_data
            )
        )

        if args.out is not None:
            with open(args.out, 'wb+') as f:
                f.write(packed)
            sys.exit(0)

        def rgba_string(c):
            return "rgba({r}, {g}, {b}, {a})".format(**c)

        # formatted_data = []
        # row_width = image.width // 16
        # for x in range(0, len(packed_image_data) // row_width):
        #     offset = x * row_width
        #     current_row = packed_image_data[offset:offset + row_width]
        #     formatted_data.append(', '.join(['0x{:02x}'.format(x) for x in current_row]))

        packed = list(packed)
        formatted_data = []
        formatted_palette = []
        row_width = 16

        def format_hex(data):
            return ', '.join(['0x{:02x}'.format(x) for x in data])

        HEADER_SIZE = 20

        PALETTE_SIZE = len(source_palette_colours) * 4

        palette_data = packed[HEADER_SIZE:HEADER_SIZE + PALETTE_SIZE]
        for x in range(0, math.ceil(len(palette_data) / 4)):
            offset = x * 4
            current_row = palette_data[offset:offset + 4]
            formatted_palette.append(format_hex(current_row))

        packed_data = packed[HEADER_SIZE + PALETTE_SIZE:]
        for x in range(0, math.ceil(len(packed_data) / float(row_width))):
            offset = x * row_width
            current_row = packed_data[offset:offset + row_width]
            formatted_data.append(format_hex(current_row))

        print("""
uint8_t packed_data[] = {{
    {type}, // type: sprite
    {payload_size}, // payload size ({comment_payload_size})

    {width}, // width ({comment_width})
    {height}, // height ({comment_height})
    {cols}, // cols ({comment_cols})
    {rows}, // rows ({comment_rows})

    {format}, // format

    {colours}, // number of palette colours
//  r     g     b     a
    {palette},

    {data}
}};
""".format(
            type=format_hex(packed[0:8]),
            payload_size=format_hex(packed[8:10]),
            comment_payload_size=len(packed),
            width=format_hex(packed[10:12]),
            comment_width=target_image.width,
            height=format_hex(packed[12:14]),
            comment_height=target_image.height,
            cols=format_hex(packed[14:16]),
            comment_cols=target_image.width // args.tilesizex,
            rows=format_hex(packed[16:18]),
            comment_rows=target_image.height // args.tilesizey,
            format=format_hex(packed[18:19]),
            colours=format_hex(packed[19:20]),
            data=',\n    '.join(formatted_data),
            palette=',\n    '.join(formatted_palette)
        ))


#         print("""
# rgba palette_data[] = {{
#     {palette_data}
# }};
#
# uint8_t sprite_data[] = {{
#     {image_data}
# }};
# """.format(
#     palette_data=',\n    '.join([rgba_string(x) for x in palette_colours]),
#     image_data=',\n    '.join(formatted_data)
# ))
