#!/usr/bin/env python3
"""
Decode the composite block and first layer block from a pm4n file,
report pixel counts and first/last pixel values.
Run: python3 decode_rle_blocks.py output/pm4n/Flow_Controller_Panel-Front.pm4n
"""
import struct, sys

path = sys.argv[1]
data = open(path, 'rb').read()
fsize = len(data)
print(f"File: {path}  ({fsize} bytes)\n")

LAYE_HDR = 0x20
STRIDE   = 0x20

laye = data.find(b'LAYE')
n_entries    = struct.unpack_from('<I', data, laye + 0x10)[0]
composite_off = struct.unpack_from('<I', data, laye + 0x14)[0]
block_size   = struct.unpack_from('<I', data, laye + 0x18)[0]

print(f"LAYE n_entries={n_entries}  composite_off=0x{composite_off:06X}  block_size={block_size}")

def decode_rle(data, offset, max_bytes):
    """Decode RLE starting at offset, stop after max_bytes read. Returns pixel list."""
    pixels = []
    i = offset
    end = min(offset + max_bytes, len(data))
    while i + 1 < end:
        b0 = data[i]; b1 = data[i+1]
        nibble = (b0 >> 4) & 0xF
        colour = 255 if nibble == 0xF else 0
        run = ((b0 & 0x0F) << 8) | b1
        run += 1
        pixels.extend([colour] * run)
        i += 2
    return pixels, i - offset

def summarize_block(name, offset, size):
    print(f"\n{name} at 0x{offset:06X}, {size} bytes:")
    if offset + size > fsize:
        print(f"  *** PAST EOF (file ends at 0x{fsize:06X}) ***")
        size = max(0, fsize - offset)
    
    # Show first 16 bytes raw
    raw = data[offset:offset+16]
    print(f"  First 16 bytes: {raw.hex()}")
    
    # Decode RLE
    pixels, bytes_consumed = decode_rle(data, offset, size)
    print(f"  Decoded: {len(pixels)} pixels from {bytes_consumed} bytes")
    print(f"  Expected: {9024*5120} pixels ({9024}×{5120})")
    
    if pixels:
        whites = sum(1 for p in pixels if p >= 128)
        blacks = len(pixels) - whites
        print(f"  White px: {whites} ({100*whites/len(pixels):.1f}%)")
        print(f"  Black px: {blacks} ({100*blacks/len(pixels):.1f}%)")
        
        # Check if it decodes to correct pixel count
        if len(pixels) == 9024 * 5120:
            print(f"  ✓ Correct pixel count")
        else:
            print(f"  *** WRONG pixel count (off by {len(pixels) - 9024*5120})")
        
        # Show first few runs
        print(f"  First pixels: {pixels[:20]}")

# Composite block
summarize_block("Composite block (block 0)", composite_off, block_size)

# First entry block  
e0_base = laye + LAYE_HDR
e0_data_off = struct.unpack_from('<I', data, e0_base + 0x14)[0]
e0_data_sz  = struct.unpack_from('<I', data, e0_base + 0x18)[0]
summarize_block("Entry[0] block", e0_data_off, e0_data_sz)