#!/usr/bin/env python
from __future__ import print_function
import os
import glob
import shutil
import subprocess
import json
import sys
import xml.etree.ElementTree as ET
from six import unichr

from PIL import Image, ImageDraw, ImageFont


class MissingGlyphError(Exception):
    pass


def color_font(code_point, code_point_to_fname_map):
    in_name = 'bitmaps/strike0/{}.png'.format(
        code_point_to_fname_map[int(code_point, 16)]
    )
    out_name = 'out/unicode/{}.png'.format(code_point)
    try:
        shutil.copyfile(in_name, out_name)
    except IOError:
        raise MissingGlyphError('code_point: %r' % (code_point))


def bw_font(name, code_point):
    char = unichr(int(code_point, 16))

    AA_SCALE = 8
    SIZE = (68, 68)
    BIG_SIZE = tuple([x * AA_SCALE for x in SIZE])

    # AndroidEmoji.ttf is from
    # https://android.googlesource.com/platform/frameworks/base.git/+/master/data/fonts/AndroidEmoji.ttf
    # commit 07912f876c8639f811b06831465c14c4a3b17663
    font = ImageFont.truetype('AndroidEmoji.ttf', 65 * AA_SCALE)
    image = Image.new('RGBA', BIG_SIZE)
    draw = ImageDraw.Draw(image)
    draw.text((0, 0), char, font=font, fill='black')
    image.resize(SIZE, Image.ANTIALIAS).save(
        'out/unicode/{}.png'.format(code_point), 'PNG'
    )


def code_point_to_file_name_map(ttx):
    """Given the NotoColorEmoji.ttx file, parse it to generate a map from
    codepoint to filename (a la glyph0****.png)
    """
    result = {}
    xml = ET.parse(ttx)
    for elem in xml.find("*cmap_format_12"): # type: ignore # https://github.com/python/typeshed/pull/254
        code_point = int(elem.attrib["code"], 16)
        fname = elem.attrib["name"]
        result[code_point] = fname
    return result


def main():
    # ttx is in the fonttools pacakge, the -z option is only on master
    # https://github.com/behdad/fonttools/

    # NotoColorEmoji.tff is from
    # https://android.googlesource.com/platform/external/noto-fonts/+/marshmallow-release/other/NotoColorEmoji.ttf
    # note that you have to run it though base64 -D before being able
    # to use it, since it downloads from that page base64 encoded

    # this is so we don't accidently leave ttx files from previous
    # runs of this script lying around
    for fname in glob.glob("*ttx*"):
        os.remove(fname)

    subprocess.call('ttx -v -z extfile NotoColorEmoji.ttf', shell=True)

    try:
        shutil.rmtree('out')
    except OSError:
        pass

    os.mkdir('out')
    os.mkdir('out/unicode')

    emoji_map = json.load(open('emoji_map.json'))

    # Fix data problem with red/blue cars being inaccurate.
    emoji_map['blue_car'] = emoji_map['red_car']
    emoji_map['red_car'] = emoji_map['oncoming_automobile']

    failed = False
    code_point_to_fname_map = code_point_to_file_name_map("NotoColorEmoji.ttx")
    for name, code_point in emoji_map.items():
        try:
            color_font(code_point, code_point_to_fname_map)
        except MissingGlyphError:
            try:
                bw_font(name, code_point)
            except Exception as e:
                print(e)
                print('Missing {}, {}'.format(name, code_point))
                failed = True
                continue

        os.symlink(
            'unicode/{}.png'.format(code_point),
            'out/{}.png'.format(name)
        )

    if failed:
        print("Errors dumping emoji!")
        sys.exit(1)


if __name__ == "__main__":
    main()
