"""Install the puck-only critical flash; does not modify shared palette entries."""
import struct

ORIGIN = 0x2FF500
TILES = 0x2FFE00


def install(data, assemble, patch):
    code = assemble('critical_flash', ORIGIN)
    assert ORIGIN+len(code) <= 0x2FF800, 'critical flash overlaps ratings'
    patch(ORIGIN, b'\xFF'*len(code), code)
    # Existing critical.s entry offsets stay unchanged, allowing exact old-profile
    # reconstruction with --no-crit-flash. Guard every replaced instruction.
    patch(0x2FF43E, bytes.fromhex('7200122b0066'), bytes.fromhex('4eb9002ff500'))
    patch(0x2FF472, bytes.fromhex('303900ffbede'), bytes.fromhex('4eb9002ff504'))
    patch(0x2FF39C, bytes.fromhex('08aa00000062'), bytes.fromhex('4eb9002ff508'))
    patch(0x167F8, bytes.fromhex('302b0006024007ff'), bytes.fromhex('4ef9002ff50c4e71'))
    patch(0x1686A, bytes.fromhex('06820005de84'), bytes.fromhex('4eb9002ff510'))
    patch(0x168FC, bytes.fromhex('8433500ad46b0012'), bytes.fromhex('4eb9002ff5144e71'))
    # Native puck frames $18B..$194 each use one 8x8 tile; $18A is the shadow.
    # Keep the exact transparency/shape and its white glint. Palette 0 index A
    # is the fixed reddish rink colour, independent of either team's uniforms.
    table = 0x5DE7A + struct.unpack_from('>I', data, 0x5DE7E)[0]
    for frame in range(0x18B, 0x195):
        begin, end = struct.unpack_from('>HH', data, table+2*frame)
        assert end-begin == 8
        _, _, tile, flags = struct.unpack_from('>hhHH', data, table+begin)
        assert 0xF25 <= tile < 0xF2D and flags & 255 == 0
    original = data[0x7C324:0x7C424]
    assert len(original) == 256
    def red(n):
        return 0 if n == 0 else 1 if n == 9 else 10
    pixels = bytes((red(b >> 4) << 4) | red(b & 15) for b in original)
    assert all((a >> 4 == 0) == (b >> 4 == 0) and (a & 15 == 0) == (b & 15 == 0)
               for a,b in zip(original, pixels)), 'changed puck transparency'
    patch(TILES, b'\xFF'*len(pixels), pixels)
    # r11 (jdc: "fully red"): palette 0 index A ($064C) is the dull rink-line red and every
    # palette-0 entry is visible on the ice. Rink palette 1 index A ($0062, dark green) only
    # shows a few edge pixels; make it pure red $000E and draw the red puck with palette 1
    # (index 1 = light grey glint).
    patch(0x59958, bytes.fromhex('0062'), bytes.fromhex('000E'))
