import struct,sys

def rdU16(b,p): return struct.unpack_from('<H',b,p)[0]
def rdU32(b,p): return struct.unpack_from('<I',b,p)[0]
def rdF32(b,p): return struct.unpack_from('<f',b,p)[0]

TAGNAME={0x0003:'HEADER',0x0005:'BIZ_DONE',0x0040:'OBJECT',0x0041:'LOD',0x0042:'PATCH',
0x0046:'PMESH',0x0047:'CONN_LIST',0x0048:'SPHERE_LIST',0x004d:'PCONN_LIST',0x0070:'BOUND',
0x0080:'VTX_XYZ',0x0081:'VTX_XYZ_N',0x0082:'VTX_XYZ_RGBA',0x0088:'VTX_XYZ_UV',
0x0089:'VTX_XYZ_N_UV',0x008A:'VTX_XYZ_RGBA_UV',0x2030:'SV_F_MATERIAL',0x2037:'SV_SPECIAL',
0x0010:'TEXTURE',0x0011:'TEXTURE_MAP',0x0018:'BITSLICE',0x0020:'MATERIAL',
0x0021:'MAT_TEXTURE',0x0023:'AMBIENT',0x0024:'DIFFUSE',0x0026:'EMISSIVE',
0x0028:'RAMP_REF',0x0030:'RAMP',0x0031:'RAMP_DATA',0x2008:'NAME',
0x0043:'FACE',0x0044:'FACE?',0x0045:'FACE?'}
CONTAINERS={0x0003,0x0070,0x0040,0x0041,0x0042,0x0046,0x0048,0x0010,0x0020,0x0030}

def parse(b,p,end,depth,out):
    while p+3<=end:
        tw=rdU16(b,p); p+=2
        idv=tw & 0x2fff
        lw=4 if (tw&0x8000) else (2 if (tw&0x4000) else 1)
        if p+lw>end: break
        ln = b[p] if lw==1 else (rdU16(b,p) if lw==2 else rdU32(b,p))
        p+=lw
        if p+ln>end: break
        out.append((depth,idv,p,ln))
        if idv in CONTAINERS:
            parse(b,p,p+ln,depth+1,out)
        p+=ln
        if idv==0x0005: break
    return

fn=sys.argv[1]
b=open(fn,'rb').read()
assert b[:8]==b'DIV-BIZ2', b[:8]
out=[]
parse(b,8,len(b),0,out)
for depth,idv,p,ln in out:
    nm=TAGNAME.get(idv,'?%04x'%idv)
    extra=''
    if idv==0x2008 or idv==0x0011 or idv==0x0028:
        s=b[p:p+ln].split(b'\0')[0].decode('latin1',errors='replace')
        extra='  "%s"'%s
    if idv==0x2037: # SV_SPECIAL
        s=b[p:p+ln].split(b'\0')[0].decode('latin1',errors='replace')
        extra='  SPECIAL="%s"'%s
    if idv==0x2030: # SV_F_MATERIAL
        s=b[p:p+ln].split(b'\0')[0].decode('latin1',errors='replace')
        extra='  MAT="%s" (len %d)'%(s,ln)
    if idv==0x0018 and ln>=1: extra='  slice=%d'%b[p]
    print('  '*depth + '%-14s off=0x%04x len=%d%s'%(nm,p,ln,extra))
