#!/usr/bin/env python3
# Copyright 2022 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""PNG to rgb565 cc file converter."""

import argparse
import importlib.resources
import logging
import math
from pathlib import Path

from PIL import Image
from jinja2 import Environment, DictLoader, make_logging_undefined

jinja_templates = {
    f.name: f.read_text()
    for f in importlib.resources.files('pw_graphics.templates').iterdir()
    if f.name.endswith('.jinja')
}

jinja_env = Environment(
    # Load templates automatically from pw_graphics/templates
    loader=DictLoader(jinja_templates),
    # Raise errors if variables are undefined in templates
    undefined=make_logging_undefined(
        logger=logging.getLogger(__package__),
    ),
    # Trim whitespace in templates
    trim_blocks=True,
    lstrip_blocks=True,
)


def _arg_parser():
    """Setup argparse."""
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('IMAGE', type=Path, help="Input image. ")
    parser.add_argument(
        '-W', '--sprite-width', type=int, required=True, help='Sprite width.'
    )
    parser.add_argument(
        '-H', '--sprite-height', type=int, required=True, help='Sprite height.'
    )
    parser.add_argument(
        '--output-mode', default='rgb565', choices=['rgb565', 'font'], help=''
    )
    parser.add_argument(
        '--transparent-color',
        default='255,0,255',
        help='Comma separated r,g,b values to use as transparent.',
    )
    return parser.parse_args()


def rgb8888to565(rgba8888):
    red = (rgba8888 & 0xFF0000) >> 16
    green = (rgba8888 & 0xFF00) >> 8
    blue = rgba8888 & 0xFF
    return rgb565(red, green, blue)


def rgb565(red, green, blue) -> int:
    return ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | ((blue & 0xF8) >> 3)


def render_rgb565_header(
    alpha_composite: Image.Image,
    tile_width: int,
    tile_height: int,
    sprite_width: int,
    sprite_height: int,
) -> list:
    sprite_data: list[list[str]] = []
    for theight in range(0, tile_height):
        for twidth in range(0, tile_width):
            sprite_data.append([])
            for currenty in range(0, sprite_height):
                for currentx in range(0, sprite_width):
                    globalx = twidth * sprite_width + currentx
                    globaly = theight * sprite_height + currenty
                    pix = alpha_composite.getpixel((globalx, globaly))

                    hex_rgb565 = rgb565(pix[0], pix[1], pix[2])
                    hex_r = f"{pix[0]:02x}"
                    hex_g = f"{pix[1]:02x}"
                    hex_b = f"{pix[2]:02x}"
                    sprite_data[-1].append(
                        f"{hex_rgb565:#04x},  // #{hex_r}{hex_g}{hex_b}\n"
                    )
    return sprite_data


def render_font_header(
    alpha_composite: Image.Image,
    tile_width: int,
    tile_height: int,
    sprite_width: int,
    sprite_height: int,
) -> list:
    sprite_data: list[list[str]] = []
    for theight in range(0, tile_height):
        for twidth in range(0, tile_width):
            sprite_data.append([])
            for currenty in range(0, sprite_height):
                line = '0b'
                for currentx in range(0, sprite_width):
                    globalx = twidth * sprite_width + currentx
                    globaly = theight * sprite_height + currenty
                    pix = alpha_composite.getpixel((globalx, globaly))
                    if pix[0] + pix[1] + pix[2] == 0:
                        line += '0'
                    else:
                        line += '1'
                line += ',\n'
                sprite_data[-1].append(line)
    return sprite_data


def main() -> None:
    """Main."""
    args = _arg_parser()

    image_path = args.IMAGE
    file_name = image_path.stem.lower().replace(' ', '_')
    sprite_width = args.sprite_width
    sprite_height = args.sprite_height
    if not image_path.is_file():
        raise FileNotFoundError

    transparent_color = (255, 0, 255)
    if args.transparent_color:
        rgb = args.transparent_color.split(',')
        assert len(rgb) == 3
        transparent_color = (int(rgb[0]), int(rgb[1]), int(rgb[2]))

    out_path = Path(image_path.stem + '.h')

    img = Image.open(image_path).convert('RGBA')
    background = Image.new('RGBA', img.size, transparent_color)
    alpha_composite = Image.alpha_composite(background, img)
    transparent_color_int = rgb565(*transparent_color)

    image_width = img.size[0]
    image_height = img.size[1]
    tile_width = math.floor(image_width / sprite_width)
    tile_height = math.floor(image_height / sprite_height)
    tile_width = max(tile_width, 1)
    tile_height = max(tile_height, 1)

    if args.output_mode == 'rgb565':
        sprite_data = render_rgb565_header(
            alpha_composite,
            tile_width,
            tile_height,
            sprite_width,
            sprite_height,
        )
    elif args.output_mode == 'font':
        sprite_data = render_font_header(
            alpha_composite,
            tile_width,
            tile_height,
            sprite_width,
            sprite_height,
        )

    template = jinja_env.get_template(args.output_mode + '.jinja')
    out_path.write_text(
        template.render(
            file_name=file_name,
            sprite_data=sprite_data,
            sprite_width=sprite_width,
            sprite_height=sprite_height,
            transparent_color=f"{transparent_color_int:#04x}",
            count=len(sprite_data),
        )
    )


if __name__ == '__main__':
    main()
