"""Theora HUD emulator.

Represents the glasses display on a laptop: three lines, monochrome, fixed
width. No graphics, no colour, no animation, because the real thing has none.

Run it:      python3 hud.py
Push a card: python3 hud.py --push "09:41|Standup in 8 min|Room 2"
From code:   from hud import push; push(["09:41", "Standup in 8 min", "Room 2"])

The display holds whatever was pushed last until something replaces it.
"""
import argparse
import json
import os
import sys
import time

WIDTH = 24          # characters per line, fixed
LINES = 3           # the display is three lines, always
STATE = os.path.expanduser("~/.theora-starter/hud.json")


def _clip(text):
    """One line, never wrapped. Longer text is cut, not folded."""
    text = " ".join(str(text).split())
    return text[:WIDTH]


def push(lines):
    """Replace what is on the display. Fewer than three lines blanks the rest."""
    if isinstance(lines, str):
        lines = lines.split("|")
    lines = [_clip(l) for l in list(lines)[:LINES]]
    lines += [""] * (LINES - len(lines))
    os.makedirs(os.path.dirname(STATE), exist_ok=True)
    with open(STATE, "w") as f:
        json.dump({"lines": lines, "t": time.time()}, f)
    return lines


def read():
    if not os.path.exists(STATE):
        return [""] * LINES
    return json.load(open(STATE))["lines"]


def render(lines):
    bar = "+" + "-" * (WIDTH + 2) + "+"
    out = [bar]
    for l in lines:
        out.append("| " + l.ljust(WIDTH) + " |")
    out.append(bar)
    return "\n".join(out)


def watch():
    """Redraw when the card changes. Ctrl-C to stop."""
    last = None
    try:
        while True:
            cur = read()
            if cur != last:
                os.system("clear" if os.name != "nt" else "cls")
                print(render(cur))
                last = cur
            time.sleep(0.3)
    except KeyboardInterrupt:
        print()


if __name__ == "__main__":
    p = argparse.ArgumentParser(description="Theora HUD emulator")
    p.add_argument("--push", help='Card text, lines separated by "|"')
    p.add_argument("--once", action="store_true", help="Print once and exit")
    a = p.parse_args()
    if a.push:
        print(render(push(a.push)))
    elif a.once:
        print(render(read()))
    else:
        watch()
