// Minimal harness: load <name>.TFX (TFMX module) + <name>.SAM (samples),
// bundle into a TFHD container (same layout as amiga_exotic_players'
// try_tfmx_bundle), run tfmx.h's player for N seconds, write a WAV file.
//
// Provenance: tfmx.h, paula.h and player_api.h in this directory are
// vendored, unmodified, from https://github.com/vtlmks/amiga_exotic_players
// (MIT License, itself a C99 port of the TFMX replayer from NostalgicPlayer,
// https://github.com/neumatho/NostalgicPlayer, also MIT). See LICENSE in
// this directory for both notices. This file (render_tfmx.c) and build.sh
// are original code written for the Kellogg's Remake project. Kellogg's
// Tony & Friends stores TFMX music as separate <NAME>.TFX (module/"mdat")
// and <NAME>.SAM (samples/"smpl") files inside PCKELL.DAT; this harness
// re-bundles that pair into the TFHD container tfmx.h expects, since the
// game's naming convention differs from TFMX's usual mdat.<name>/smpl.<name>
// convention.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#include "player_api.h"
#include "tfmx.h"

static uint8_t *load_file(const char *path, uint32_t *out_len) {
    FILE *f = fopen(path, "rb");
    if (!f) { perror(path); return 0; }
    fseek(f, 0, SEEK_END);
    long len = ftell(f);
    fseek(f, 0, SEEK_SET);
    uint8_t *buf = malloc(len);
    fread(buf, 1, len, f);
    fclose(f);
    *out_len = (uint32_t)len;
    return buf;
}

static void write_wav(const char *path, int16_t *pcm, int32_t frames, int32_t sample_rate) {
    FILE *f = fopen(path, "wb");
    uint32_t data_bytes = frames * 2 * sizeof(int16_t);
    uint32_t riff_size = 36 + data_bytes;
    fwrite("RIFF", 1, 4, f);
    fwrite(&riff_size, 4, 1, f);
    fwrite("WAVE", 1, 4, f);
    fwrite("fmt ", 1, 4, f);
    uint32_t fmt_size = 16;
    fwrite(&fmt_size, 4, 1, f);
    uint16_t audio_format = 1, num_channels = 2;
    fwrite(&audio_format, 2, 1, f);
    fwrite(&num_channels, 2, 1, f);
    fwrite(&sample_rate, 4, 1, f);
    uint32_t byte_rate = sample_rate * 2 * sizeof(int16_t);
    fwrite(&byte_rate, 4, 1, f);
    uint16_t block_align = 2 * sizeof(int16_t);
    fwrite(&block_align, 2, 1, f);
    uint16_t bits_per_sample = 16;
    fwrite(&bits_per_sample, 2, 1, f);
    fwrite("data", 1, 4, f);
    fwrite(&data_bytes, 4, 1, f);
    fwrite(pcm, 1, data_bytes, f);
    fclose(f);
}

int main(int argc, char **argv) {
    if (argc < 4) {
        fprintf(stderr, "usage: %s <mdat.tfx> <smpl.sam> <out.wav> [seconds]\n", argv[0]);
        return 1;
    }
    double seconds = argc > 4 ? atof(argv[4]) : 15.0;

    uint32_t mdat_len = 0, smpl_len = 0;
    uint8_t *mdat = load_file(argv[1], &mdat_len);
    uint8_t *smpl = load_file(argv[2], &smpl_len);
    if (!mdat || !smpl) return 1;

    uint32_t hdr_off = 18;
    uint32_t bundle_len = hdr_off + mdat_len + smpl_len;
    uint8_t *bundle = malloc(bundle_len);
    memset(bundle, 0, hdr_off);
    bundle[0] = 'T'; bundle[1] = 'F'; bundle[2] = 'H'; bundle[3] = 'D';
    bundle[4] = 0; bundle[5] = 0;
    bundle[6] = (uint8_t)(hdr_off >> 8); bundle[7] = (uint8_t)hdr_off;
    bundle[8] = 0; bundle[9] = 0;
    bundle[10] = (uint8_t)(mdat_len >> 24); bundle[11] = (uint8_t)(mdat_len >> 16);
    bundle[12] = (uint8_t)(mdat_len >> 8);  bundle[13] = (uint8_t)mdat_len;
    bundle[14] = (uint8_t)(smpl_len >> 24); bundle[15] = (uint8_t)(smpl_len >> 16);
    bundle[16] = (uint8_t)(smpl_len >> 8);  bundle[17] = (uint8_t)smpl_len;
    memcpy(bundle + hdr_off, mdat, mdat_len);
    memcpy(bundle + hdr_off + mdat_len, smpl, smpl_len);

    int32_t sample_rate = 44100;
    void *s = tfmx_api.init(bundle, bundle_len, sample_rate);
    if (!s) {
        fprintf(stderr, "tfmx_api.init failed (module not recognized)\n");
        return 2;
    }

    int32_t total_frames = (int32_t)(seconds * sample_rate);
    float *scratch = malloc(sizeof(float) * total_frames * 2);
    int16_t *pcm = malloc(sizeof(int16_t) * total_frames * 2);
    player_get_audio_s16(&tfmx_api, s, pcm, scratch, total_frames);

    write_wav(argv[3], pcm, total_frames, sample_rate);
    fprintf(stderr, "wrote %s: %d frames @ %d Hz (%.1fs)\n", argv[3], total_frames, sample_rate, seconds);

    tfmx_api.free(s);
    return 0;
}
