#!/usr/bin/env python3
"""gaf.py — list the entries inside a Total Annihilation GAF file.

Usage:
    python gaf.py file.gaf            # print entry names + frame counts
    python gaf.py file.gaf --count    # print only the number of entries

Format: header = uint32 IDVersion (0x00010100), int32 Entries, int32 Unknown1,
then `Entries` x int32 pointers to records: int16 Frames, int16 Unknown1,
int32 Unknown2, char Name[32].

MIT licence. https://ta-archive.com/tools/py/
"""
import struct
import sys


def gaf_entries(d):
    """Return {entry_name: frame_count}, or None if not a GAF v1.1 file."""
    ver, n, _u = struct.unpack('<3i', d[:12])
    if ver != 0x00010100:
        return None
    if len(d) < 12 + 4 * n:
        return None
    ptrs = struct.unpack('<%di' % n, d[12:12 + 4 * n])
    out = {}
    for p in ptrs:
        frames, _u1, _u2 = struct.unpack('<hhi', d[p:p + 8])
        name = d[p + 8:p + 40].split(b'\0')[0].decode('latin-1', 'replace')
        out[name] = frames
    return out


def main():
    if len(sys.argv) < 2:
        print(__doc__)
        sys.exit(1)
    data = open(sys.argv[1], 'rb').read()
    ents = gaf_entries(data)
    if ents is None:
        print('not a GAF v1.1 file')
        sys.exit(1)
    if '--count' in sys.argv:
        print(len(ents))
        return
    for name, frames in ents.items():
        print(f'{frames:>3}  {name}')


if __name__ == '__main__':
    main()
