#include "tn_dsf.h"
#include "TN_DSF.bin_rev.h"
#include <stdlib.h>
#include <string.h>

const char verstag[] = VERSTAG;

struct ExecIFace *IExec;
struct Interface *INewlib;

static int32 dsf_open (struct TNDecHandle *handle, void *buf, uint32 len);
static void dsf_close (struct TNDecHandle *handle);
static int32 dsf_process (struct TNDecHandle *handle, void *buf, uint32 len);

dsfiface_t idsf = {
	dsf_open,
	dsf_close,
	dsf_process,
};

dsfiface_t *_start (char *argstr, int32 arglen, struct ExecBase *SysBase) {
	IExec = (struct ExecIFace *)SysBase->MainInterface;
	return &idsf;
}

static int32 dsf_open (struct TNDecHandle *handle, void *buf, uint32 len) {
	INewlib = handle->newlib;

	if (dsf_start(buf, len) != AO_SUCCESS) {
		return FALSE;
	}

	if (dsf_fill_info(&handle->info) != AO_SUCCESS) {
		return FALSE;
	}

	int i;
	for (i = 0; i < 9; i++) {
		char *title = &handle->info.title[i][0];
		char *info = &handle->info.info[i][0];
		if (info[0] && strnicmp(info, "n/a", 3)) {
			if (!strnicmp(title, "Name: ", 6)) {
				handle->title = info;
			} else
			if (!strnicmp(title, "Game: ", 6)) {
				handle->game = info;
			}
		}
	}

	handle->silence = 0;

	return TRUE;
}

static void dsf_close (struct TNDecHandle *handle) {
	dsf_stop();
	INewlib = NULL;
}

static BOOL detect_silence (int16 *buf, uint32 len) {
	while (len--) {
		if (*buf > 512 || *buf < -512) return FALSE;
		buf++;
		if (*buf > 512 || *buf < -512) return FALSE;
		buf++;
	}
	return TRUE;
}

static int32 dsf_process (struct TNDecHandle *handle, void *buf, uint32 len) {
	if (handle->silence > 100) return 0;

	if (dsf_gen(buf, len) == AO_SUCCESS) {
		if (detect_silence(buf, len))
			handle->silence++;
		else
			handle->silence = 0;
		return len;
	}
	return 0;
}
