# radar_scope -- MPU half.
# Receives target pictures pushed from the MCU, reshapes them as JSON, and
# forwards them to the browser scope. Short on purpose: the MCU already did
# the hard part, and nothing here has to be timely.

import time

from arduino.app_utils import *                    # App, Bridge (see part 1)
from arduino.app_bricks.web_ui import WebUI

ui = WebUI()

MAX_TARGETS = 3


def parse(s):
    """ "x,y,v;;x,y,v" -> target dicts, with the SLOT INDEX preserved.

    Slot identity is the module's tracking output and the browser needs it
    to keep each target's colour and trail attached to the right person.
    """
    out = []
    for slot, chunk in enumerate(s.split(";")[:MAX_TARGETS]):
        chunk = chunk.strip()
        if not chunk:
            continue
        try:
            x, y, v = (int(n) for n in chunk.split(","))
        except ValueError:
            continue                              # torn field: skip this slot
        out.append({"slot": slot, "x": x, "y": y, "v": v})
    return out


def on_targets(raw):
    """Called from the sketch, once per radar frame."""
    ui.send_message("targets", {
        "targets": parse(raw or ""),
        "ts": time.time(),
    })


# Send the page a starting state as soon as a browser connects, so a scope
# opened during a quiet moment is empty rather than blank.
ui.on_connect(lambda sid: ui.send_message("targets", {"targets": [], "ts": time.time()}))

Bridge.provide("radar_targets", on_targets)


def loop():
    # Nothing to do here: the work is entirely event-driven. The loop exists
    # because App.run() expects one, and because it is the natural place to
    # add logging or a recording tap later.
    time.sleep(1.0)


App.run(user_loop=loop)
