#include "tn_s98.h"
#include <string.h>

#define S98_MAGIC_V0	(0x53393830)	/* 'S980' */
#define S98_MAGIC_V1	(0x53393831)	/* 'S981' */
#define S98_MAGIC_V2	(0x53393832)	/* 'S982' */
#define S98_MAGIC_V3	(0x53393833)	/* 'S983' */
#define VGM_MAGIC		(0x56676D20)	/* 'Vgm ' */
#define MYM_MAGIC_V0	(0x4D594D30)	/* 'MYM0' */
#define MYM_MAGIC_V1	(0x4D594D31)	/* 'MYM1' */
#define MYM_MAGIC_VC	(0x4D594D43)	/* 'MYMC' */

int32 TNPlug_TestPlayer (struct TNPlugIFace *Self, uint8 *testme, uint8 *testbuffer,
	uint32 totalsize, uint32 testsize)
{
	int32 res = 0;

	if (totalsize >= 4) {
		uint32 magic = *(uint32 *)testbuffer;
		if ((magic >= S98_MAGIC_V0 && magic <= S98_MAGIC_V3) ||
			magic == VGM_MAGIC ||
			(magic >= MYM_MAGIC_V0 && magic <= MYM_MAGIC_V1) || magic == MYM_MAGIC_VC)
		{
			res = PLM_FileLoad;
		}
	} else {
		char *p;
		p = strrchr((char *)testme, '.');
		if (p) {
			p++;
			if (!stricmp(p, "s98") || !stricmp(p, "vgm") || !stricmp(p, "mym")) {
				res = PLM_FileLoad;
			}
		}
	}

	return res;
}

BOOL TNPlug_OpenPlayer (struct TNPlugIFace *Self, uint8 *openme, struct TuneNet *inTuneNet) {
	BOOL res = FALSE;

	if (inTuneNet->playmode == PLM_FileLoad) {
		struct TNDecHandle *handle;

		handle = IExec->AllocVec(sizeof(*handle), MEMF_SHARED|MEMF_CLEAR);
		inTuneNet->handle = handle;
		if (!handle) goto out;

		dbug(("Opening s98 file: "));
		handle->s98 = S98_OpenFromBuffer((BYTE *)inTuneNet->in_file,
			inTuneNet->in_file_size, &handle->info);
		dbug((handle->s98 ? "success\n" : "failure\n"));
		if (!handle->s98) goto out;

		dbug(("Allocating buffer (%ld bytes)\n", handle->info.dwSamplesPerSec << 2));
		inTuneNet->pcm[0] = IExec->AllocVec(handle->info.dwSamplesPerSec << 2, MEMF_SHARED);
		if (!inTuneNet->pcm[0]) goto out;
		inTuneNet->pcm[1] = inTuneNet->pcm[0] + 1;

		res = TRUE;
out:
		if (res) {
			inTuneNet->DirectRender = ARender_InternalBuffer;
			inTuneNet->max_subsongs =
			inTuneNet->current_subsong = 0;

			inTuneNet->dec_frequency = handle->info.dwSamplesPerSec;
			inTuneNet->dec_channels = handle->info.dwChannels;
			inTuneNet->bitrate = 0;
			inTuneNet->mix_lr = TN_STEREO_50PER;

			inTuneNet->Tune[0] = 0;

			dbug(("Length: %ld\n", handle->info.dwLength));
			inTuneNet->ms_duration = handle->info.dwLength;

			inTuneNet->ST_Name[0] = 0;
			inTuneNet->ST_Url[0] = 0;
			inTuneNet->ST_Note[0] = 0;

			inTuneNet->songEOF = TRUE;
		} else {
			TNPlug_ClosePlayer(Self, inTuneNet);
		}
	}

	return res;
}

void TNPlug_ClosePlayer (struct TNPlugIFace *Self, struct TuneNet *inTuneNet) {
	struct TNDecHandle *handle = inTuneNet->handle;
	if (handle) {
		S98_Close(handle->s98);
		IExec->FreeVec(handle);
		inTuneNet->handle = NULL;
	}
	IExec->FreeVec(inTuneNet->pcm[0]);
	inTuneNet->pcm[0] =
	inTuneNet->pcm[1] = NULL;
}
