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

#include "swis.h"

#include "Options.h"
#include "SDswi.h"
#include "WimpLib:Utils.h"

#define SWI_DCDUtils_Version               0x052780
#define SWI_DCDUtils_RegisterPlayer        0x052781
#define SWI_DCDUtils_DeregisterPlayer      0x052782
#define SWI_DCDUtils_SetPlayerInfo         0x052785
#define SWI_DCDUtils_GetPlayerInfo         0x052786
#define SWI_DCDUtils_GetFullScreenPlugIn   0x052788
#define SWI_DCDUtils_StopPlugIns           0x05278A
#define SWI_DCDUtils_UpdatePlugInsPosition 0x05278B
#define SWI_DCDUtils_PlayerHasPlugIn       0x05278D
#define SWI_DCDUtils_PlayerInfo            0x05278F
#define SWI_DCDUtils_PlayerFindPlugIn      0x052793

const _kernel_oserror* DCDUtils_RegisterPlayer(int* player)
{
	return _swix(SWI_DCDUtils_RegisterPlayer, _IN(0)|_OUT(0), 0, player);
}

const _kernel_oserror* DCDUtils_DeregisterPlayer(int player)
{
	return _swix(SWI_DCDUtils_DeregisterPlayer, _IN(0), player);
}

bool DCDUtils_HasValidDriver(int hardwaretype)
{
	if ((hardwaretype < 0)
	||  (hardwaretype >= Options()->Samplers.Count))
		return false;

	return (SoundDriver_FindDriver(Options()->Samplers.Params[hardwaretype].Driver) >= 0);
}

void DCDUtils_SetInfo(int player, int count, int hardwaretype)
{
	const SamplerParams* pParams;
	int type = hardwaretype;

	if (type != 1)
	{
		if ((type >= 0) && (type < Options()->Samplers.Count))
			pParams = &(Options()->Samplers.Params[type]);
		else
			pParams = NULL;

		if (pParams)
		{
			type = SoundDriver_FindDriver(pParams->Driver);
			if (Options()->Samplers.bForceDriverConfig)
			{
				SoundDriver_Config(type
						, pParams->SourceLeft
						, pParams->SourceRight
						, pParams->SampleType
						, pParams->SampleRate);
			}
		}
		else type = -1;
		DCDUtils_SetIntInfo(player, 4, type);
	}

	DCDUtils_SetIntInfo(player, 1, count);
}

void DCDUtils_SetIntInfo(int player, int info, int value)
{
	_kernel_swi_regs regs;

	_kernel_swi(SWI_DCDUtils_Version, &regs, &regs);
	if (regs.r[0] > 20)
	{
		regs.r[0] = player;
		regs.r[1] = info + 0x80000000;
		regs.r[2] = value;
		_kernel_swi(SWI_DCDUtils_PlayerInfo, &regs, &regs);
	}
	else if (info < 4)
	{
		regs.r[0] = player;
		_kernel_swi(SWI_DCDUtils_GetPlayerInfo, &regs, &regs);
		regs.r[1+info] = value;
		_kernel_swi(SWI_DCDUtils_SetPlayerInfo, &regs, &regs);
	}
}

static const char StartDesktop[] = "DigitalCDRes:Plugins.Desktop.%s.!Run %d";

void DCDUtils_StartPlugIn(int player)
{
	HTask       dummy;
	int         hardware;
	const char* pCurrent;
	char*       pStar;

	if (_swix(SWI_DCDUtils_GetPlayerInfo, _IN(0)|_OUT(5), player, &hardware)) return;

	if ((hardware == -1)                        // Hardware not supported
	||  (DCDUtils_GetFullScreenPlugIn() != -1)) // Full screen plug-in active
		return;

	if (Options()->PlugIns.bDesktop)
	{
		pCurrent = Options()->PlugIns.pDesktop;
		while ((pStar = strchr(pCurrent, '*')) != NULL)
		{
			// dirty trick
			*pStar = 0;
			if (DCDUtils_PlayerFindPlugIn(player, pCurrent) == -1) // Plug-in is not yet started
				StartTask(&dummy, SPrintf(StartDesktop, pCurrent, player));
			*pStar = '*';
			pCurrent = pStar + 1;
		}
		if (pCurrent[0]
		&& (DCDUtils_PlayerFindPlugIn(player, pCurrent) == -1)) // Plug-in is not yet started
			StartTask(&dummy, SPrintf(StartDesktop, pCurrent, player));
	}
	else
	{
		pCurrent = Options()->PlugIns.pFullScreen;
		if (pCurrent[0])
			StartTask(&dummy, SPrintf("DigitalCDRes:Plugins.FullScreen.%s.!Run %d", pCurrent, player));
	}
}

void DCDUtils_StopPlugIns(int player)
{
	_swix(SWI_DCDUtils_StopPlugIns, _IN(0), player);
}

void DCDUtils_UpdatePlugInsPosition(int player)
{
	_swix(SWI_DCDUtils_UpdatePlugInsPosition, _IN(0), player);
}

int DCDUtils_GetFullScreenPlugIn(void)
{
	int val;

	if (_swix(SWI_DCDUtils_GetFullScreenPlugIn, _OUT(0), &val))
		return -1;
	else
		return val;
}

bool DCDUtils_PlayerHasPlugIn(int player)
{
	int val;

	if (_swix(SWI_DCDUtils_PlayerHasPlugIn, _IN(0)|_OUT(1), player, &val))
		return 0;
	else
		return (val != 0);
}

int DCDUtils_PlayerFindPlugIn(int player, const char* pName)
{
	int val;

	if (_swix(SWI_DCDUtils_PlayerFindPlugIn, _IN(0)|_IN(1)|_OUT(2), player, pName, &val))
		return -1;
	else
		return val;
}
