# define errors (-1)
# define no_errors 0

# include <windows.h>
# include <mmsystem.h>
# include <stdio.h>

# include "emulate.h"

HWAVEOUT hWO; 

# define NBUFFERS 10
WAVEHDR whdr0 [NBUFFERS];

char old = 0;

void play (char * buffer, int len)
{ 
	len=len;


	char * memory = (char *) malloc(len);

	for (int i=0; i<len; i++)
		memory[i] =  buffer [i];

	///Приготавливаем и пихаем новый

	WAVEHDR * whdr;
	WAVEHDR * whdrold;

	whdr = &whdr0[old];

	if (old != (NBUFFERS-1)) 
		whdrold = &whdr0[old+1];
	else
		whdrold = &whdr0[0];

	ZeroMemory(whdr, sizeof(WAVEHDR));

	whdr->lpData = memory; 
	whdr->dwBufferLength = len; 
	whdr->dwFlags = 0; 
	whdr->dwLoops = 0; 

	waveOutPrepareHeader(hWO, whdr, sizeof(WAVEHDR));

	waveOutWrite(hWO, whdr, sizeof(WAVEHDR));


	///Ждём завершения проигрывания старого
	while(waveOutUnprepareHeader(hWO, whdrold, sizeof(WAVEHDR)) == WAVERR_STILLPLAYING)
	{
		printf("W  %d %d \n", old, whdrold );
		Sleep(15);
	}
	free(whdrold->lpData);

	old ++;

	if (old == NBUFFERS)
		old = 0;
}

int init_card(char * arg)
{
	WAVEFORMATEX wfx;

	ZeroMemory(&wfx, sizeof(wfx));

	wfx.wFormatTag = WAVE_FORMAT_PCM;   
    wfx.nChannels = 2; 
    wfx.nSamplesPerSec = 44100; 
    wfx.wBitsPerSample = 16; 
	wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8;
	wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;
	wfx.cbSize = sizeof(wfx);
 
    if(waveOutOpen(&hWO, atoi(arg), &wfx, 0, 0, CALLBACK_NULL) == MMSYSERR_NOERROR)
    {
        return no_errors;
    }
    else
	{
         return errors;
	}
}

char Joy(void)
{
	JOYINFO ji;
	
	char rv = 0; 


	if (joyGetPos(JOYSTICKID1,  &ji) == JOYERR_NOERROR) 
	{
		if (ji.wXpos<16384)
			rv |= 1;
	
		if (ji.wXpos>49152)
			rv |= 2;

		if (ji.wYpos<16384)
			rv |= 8;
	
		if (ji.wYpos>49152)
			rv |= 4;

		if (ji.wButtons)
			rv |= 16;
	}
	else
	{
		rv = -1;
	}

	return rv;
}

char * unicode_to_utf8(wchar_t * unicode_string)
{
	int err;
	char * res = (char *) malloc (100);

	err = WideCharToMultiByte
		(
		CP_UTF8,				
		0,					
		unicode_string,		
		-1,					
		res,				
		100,			
		NULL,				
		NULL				
		);

	if (err == 0)
	{
		printf("Failed to convert from unicode\n");
	}

	return res;
}

# define MAXCARDS 20
char *** cardslist;

char *** cards_list(void)
{
	WAVEOUTCAPS woc;


	if (cardslist) free(cardslist);

	cardslist = (char ***) malloc(MAXCARDS * sizeof (char **));

	for (int i=0; i<MAXCARDS; i++)
		cardslist[i]= (char**) malloc (2 * sizeof (char *));	
	
	for (int i=0; i<MAXCARDS; i++)
	{
		for (int j=0; j<2; j++)
		{
			cardslist[i][j]= (char*) malloc (101 * sizeof (char));
			memset(cardslist[i][j], 0, 100);
		}
	}

	int n = waveOutGetNumDevs(); 

	sprintf(cardslist[0][0], "%d", -1);
	sprintf(cardslist[0][1], "%s", "Default device");

	for (int i=0; i<n; i++)
	{
		waveOutGetDevCaps(i, &woc, sizeof(woc)); 
		sprintf (cardslist[i+1][0], "%d", i);
		strcpy (cardslist[i+1][1], unicode_to_utf8((wchar_t *)woc.szPname));
	}

	return ((char ***)cardslist);
}
