#!/usr/bin/env python3
"""Extract verified PCM samples from PCMDATA.WLK and write .wav files.

Format (little-endian):
  offset 0x00: 8 bytes  magic "WLKF0200"
  offset 0x08: u16      sample count (e.g. 54)
  offset 0x0A: u16      archive flags
  offset 0x0C: entries, 22 bytes each:
      [ 1] u8   status (usually 0xFF)
      [ 1] u8   flags (bit 5 -> loop playback, bit 6 -> stereo, bit 7 -> 16-bit signed PCM;
                       bit 7 clear -> 8-bit unsigned PCM)
      [ 4] u32  offset (absolute)
      [ 4] u32  size (bytes)
      [ 4] u32  sample rate (0x2b11 = 11025, 0x5622 = 22050)
      [ 4] i32  gain metadata from the verified table (0, -200, -500, -1800, ...)
      [ 4] u32  reserved (0)
  Body: raw mono PCM, starting at 0x0C + count*22.

The output filenames use the same zero-based EXE ids used by the game:
`00.wav`..`53.wav`.
"""
import os, sys, wave
from pathlib import Path

from audio_archive_manifest import load_wlk_archive

def extract(src, dst):
    path = Path(src)
    d = path.read_bytes()
    manifest = load_wlk_archive(path)
    os.makedirs(dst, exist_ok=True)
    for entry in manifest["entries"]:
        i = entry["exeIndex"]
        off = entry["offset"]
        size = entry["payloadBytes"]
        sr = entry["sampleRate"]
        pcm = d[off:off+size]
        channels = entry["channels"]
        sample_width = entry["bitDepth"] // 8
        path = os.path.join(dst, f'{i:02d}.wav')
        with wave.open(path, 'wb') as w:
            w.setnchannels(channels); w.setsampwidth(sample_width); w.setframerate(sr)
            w.writeframes(pcm)
    print(
        f'extracted {manifest["count"]} verified wav files -> {dst}/ '
        f'(archive flags={manifest["archiveFlagsHex"]})'
    )

if __name__ == '__main__':
    src = sys.argv[1] if len(sys.argv) > 1 else 'PCMDATA.WLK'
    dst = sys.argv[2] if len(sys.argv) > 2 else 'extract_wlk'
    extract(src, dst)
