"""Faces and letters for a 5x5 grid of lights.

The micro:bit screen is 25 lights in a 5 by 5 grid. A picture for it is
five numbers, one for each row. Numbers are hard to read, so here you
draw each picture with dots and hashes instead.

This draws in your terminal. It needs no robot and no Bluetooth, so it
works on any computer.

    python faces.py                  # a smile
    python faces.py heart            # one picture
    python faces.py HELLO            # spell a word
    python faces.py font             # show everything

Run it:
    Windows:  python faces.py heart
    Mac:      python3 faces.py heart
"""
import sys


def icon(*rows):
    """Five strings of dots and hashes -> five numbers.

    One number for each row. Bit 4 is the LEFT light, bit 0 the right one.
    """
    out = bytearray()
    for row in rows:
        value = 0
        for i, ch in enumerate(row[:5]):
            if ch not in ". 0_":
                value |= 1 << (4 - i)
        out.append(value)
    return bytes(out)


FACES = {
    "smile": icon(".#.#.", ".#.#.", ".....", "#...#", ".###."),
    "sad":   icon(".#.#.", ".#.#.", ".....", ".###.", "#...#"),
    "wink":  icon(".#...", ".#.##", ".....", "#...#", ".###."),
    "flat":  icon(".#.#.", ".#.#.", ".....", "#####", "....."),
    "heart": icon(".#.#.", "#####", "#####", ".###.", "..#.."),
    "yes":   icon(".....", "....#", "...#.", "#.#..", ".#..."),
    "no":    icon("#...#", ".#.#.", "..#..", ".#.#.", "#...#"),
    "up":    icon("..#..", ".###.", "#.#.#", "..#..", "..#.."),
    "down":  icon("..#..", "..#..", "#.#.#", ".###.", "..#.."),
}

FONT = {
    " ": icon(".....", ".....", ".....", ".....", "....."),
    "A": icon(".###.", "#...#", "#####", "#...#", "#...#"),
    "B": icon("####.", "#...#", "####.", "#...#", "####."),
    "C": icon(".####", "#....", "#....", "#....", ".####"),
    "D": icon("####.", "#...#", "#...#", "#...#", "####."),
    "E": icon("#####", "#....", "####.", "#....", "#####"),
    "F": icon("#####", "#....", "####.", "#....", "#...."),
    "G": icon(".####", "#....", "#..##", "#...#", ".###."),
    "H": icon("#...#", "#...#", "#####", "#...#", "#...#"),
    "I": icon("#####", "..#..", "..#..", "..#..", "#####"),
    "J": icon("#####", "..#..", "..#..", "#.#..", ".##.."),
    "K": icon("#...#", "#..#.", "###..", "#..#.", "#...#"),
    "L": icon("#....", "#....", "#....", "#....", "#####"),
    "M": icon("#...#", "##.##", "#.#.#", "#...#", "#...#"),
    "N": icon("#...#", "##..#", "#.#.#", "#..##", "#...#"),
    "O": icon(".###.", "#...#", "#...#", "#...#", ".###."),
    "P": icon("####.", "#...#", "####.", "#....", "#...."),
    "Q": icon(".###.", "#...#", "#...#", "#..#.", ".##.#"),
    "R": icon("####.", "#...#", "####.", "#..#.", "#...#"),
    "S": icon(".####", "#....", ".###.", "....#", "####."),
    "T": icon("#####", "..#..", "..#..", "..#..", "..#.."),
    "U": icon("#...#", "#...#", "#...#", "#...#", ".###."),
    "V": icon("#...#", "#...#", "#...#", ".#.#.", "..#.."),
    "W": icon("#...#", "#...#", "#.#.#", "##.##", "#...#"),
    "X": icon("#...#", ".#.#.", "..#..", ".#.#.", "#...#"),
    "Y": icon("#...#", ".#.#.", "..#..", "..#..", "..#.."),
    "Z": icon("#####", "...#.", "..#..", ".#...", "#####"),
    "0": icon(".###.", "#..##", "#.#.#", "##..#", ".###."),
    "1": icon("..#..", ".##..", "..#..", "..#..", ".###."),
    "2": icon("###..", "...#.", "..#..", ".#...", "#####"),
    "3": icon("####.", "....#", "..##.", "....#", "####."),
    "4": icon("#...#", "#...#", "#####", "....#", "....#"),
    "5": icon("#####", "#....", "####.", "....#", "####."),
    "6": icon(".###.", "#....", "####.", "#...#", ".###."),
    "7": icon("#####", "....#", "...#.", "..#..", ".#..."),
    "8": icon(".###.", "#...#", ".###.", "#...#", ".###."),
    "9": icon(".###.", "#...#", ".####", "....#", ".###."),
    "!": icon("..#..", "..#..", "..#..", ".....", "..#.."),
    "?": icon(".###.", "#...#", "...#.", ".....", "..#.."),
}


def render(bitmap, label=""):
    """Print a picture in the terminal."""
    if label:
        print(f"  {label}")
    for row in bitmap:
        line = "".join("#" if (row >> (4 - i)) & 1 else "." for i in range(5))
        print("   ", line.replace("#", "[]").replace(".", " ."))
    print("    numbers:", " ".join(str(b) for b in bitmap))
    print()


def show(what):
    """Draw a face, a letter, or a whole word."""
    if what.lower() == "font":
        for name, bm in list(FACES.items()) + list(FONT.items()):
            render(bm, name)
        return

    if what.lower() in FACES:
        render(FACES[what.lower()], what.lower())
        return

    for ch in what.upper():
        bm = FONT.get(ch)
        if bm is None:
            print(f"  I have no picture for {ch!r}\n")
        else:
            render(bm, ch)


if __name__ == "__main__":
    show(" ".join(sys.argv[1:]) or "smile")
