"""Read the documented AC3D/Speed Dreams mesh structure, preserving author geometry.
No road/vehicle geometry is synthesized by this importer.
"""
from pathlib import Path
import re,shlex,json

def read_ac(path):
 lines=Path(path).read_text(errors='replace').splitlines();i=1;materials=[];objects=[]
 while i<len(lines) and lines[i].startswith('MATERIAL'):
  parts=shlex.split(lines[i]);materials.append({'name':parts[1],'rgb':list(map(float,parts[parts.index('rgb')+1:parts.index('rgb')+4])),'trans':float(parts[parts.index('trans')+1])});i+=1
 def obj(parentloc=(0,0,0)):
  nonlocal i
  assert lines[i].startswith('OBJECT'),(i,lines[i]);o={'name':'','texture':None,'v':[],'f':[],'loc':list(parentloc),'children':[]};i+=1
  while i<len(lines):
   line=lines[i];i+=1
   if not line:continue
   p=shlex.split(line);k=p[0]
   if k=='name':o['name']=p[1]
   elif k=='loc':o['loc']=[parentloc[j]+float(p[j+1]) for j in range(3)]
   elif k=='texture' and (len(p)<3 or p[-1]=='base'):o['texture']=p[1] if p[1]!='empty_texture_no_mapping' else None
   elif k=='numvert':
    for _ in range(int(p[1])):o['v'].append(list(map(float,lines[i].split())));i+=1
   elif k=='numsurf':
    for _ in range(int(p[1])):
     surf=0;mat=0
     while True:
      q=lines[i].split();i+=1
      if q[0]=='SURF':surf=int(q[1],0)
      elif q[0]=='mat':mat=int(q[1])
      elif q[0]=='refs':break
     refs=[]
     for _ in range(int(q[1])):r=lines[i].split();i+=1;refs.append([int(r[0]),float(r[1]),float(r[2])])
     if surf&0xf==4:
      triangles=[([refs[j],refs[j+1],refs[j+2]] if j%2==0 else [refs[j+1],refs[j],refs[j+2]]) for j in range(len(refs)-2)]
     else:triangles=[[refs[0],refs[j],refs[j+1]] for j in range(1,len(refs)-1)]
     for tri in triangles:
      if len(set(r[0] for r in tri))==3:o['f'].append((mat,tri))
   elif k=='data':i+=1
   elif k=='kids':
    objects.append(o)
    return o
  return o
 while i<len(lines):
  if lines[i].startswith("OBJECT"):obj()
  else:i+=1
 return materials,objects
if __name__=='__main__':
 import sys
 m,o=read_ac(sys.argv[1]);print('objects',len(o),'vertices',sum(len(x['v']) for x in o),'triangles',sum(len(x['f']) for x in o));
 for x in sorted([x for x in o if re.fullmatch(r'TKMN\d+',x['name'])],key=lambda x:int(x['name'][4:]))[:3]:print(x['name'],x['v'][:8],x['f'][:3])
