//// Defined to disable deprecated functions warning in Visual C++ 2005
//#define _CRT_SECURE_NO_DEPRECATE 1

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

typedef int			RADIOHANDLE;
typedef void		(__stdcall* RADIOHANDLERCALLBACK)(void* pTarget, void* pBuffer, DWORD dwSize, DWORD dwSamplingRate);

// G33WSB API function type declarations
typedef int		(__stdcall *FNCOpenRadioDevice)(int iDeviceNum);
typedef BOOL	(__stdcall *FNCCloseRadioDevice)(RADIOHANDLE hRadio);
typedef BOOL	(__stdcall *FNCSetFrequency)(RADIOHANDLE hRadio, DWORD iFreq);
typedef BOOL	(__stdcall *FNCSetRFAmp)(RADIOHANDLE hRadio, BOOL fPreamp);
typedef BOOL	(__stdcall *FNCSetAtten)(RADIOHANDLE hRadio, BOOL fAtten);
typedef BOOL	(__stdcall *FNCSetPower)(RADIOHANDLE hRadio, BOOL fPower);
typedef BOOL	(__stdcall *FNCSetAudioBandwidth)(RADIOHANDLE hRadio, DWORD BW);
typedef BOOL	(__stdcall *FNCSetVolume)(RADIOHANDLE hRadio, DWORD AudioGain);
typedef BOOL	(__stdcall *FNCInitializeDemodulator)(RADIOHANDLE hRadio, char* pszCalFilePath);
typedef BOOL	(__stdcall *FNCSetupStreams)(RADIOHANDLE hRadio, RADIOHANDLERCALLBACK IFHandler, void* IFTarget, RADIOHANDLERCALLBACK AudioHandler, void* AudioTarget);

FNCOpenRadioDevice			OpenRadioDevice			= NULL;
FNCCloseRadioDevice			CloseRadioDevice		= NULL;
FNCSetFrequency				SetFrequency			= NULL;
FNCSetPower					SetPower				= NULL;
FNCSetPower					SetAtten				= NULL;
FNCSetPower					SetRFAmp				= NULL;
FNCSetAudioBandwidth		SetAudioBandwidth		= NULL;
FNCSetVolume				SetVolume				= NULL;
FNCInitializeDemodulator	InitializeDemodulator	= NULL;
FNCSetupStreams				SetupStreams			= NULL;

HINSTANCE WRG39WSBAPI	= NULL;
DWORD WRG39WSBAPI_Count	= 0;

void __stdcall APIUnload(void)
{
	//  If the API has not been loaded it simply returns. Else if the API has been
	// loaded more than once, the special counter is decremented. Only if the
	// special counter drops back to 0 the library is actually freed.
	if (!WRG39WSBAPI_Count || --WRG39WSBAPI_Count != 0) 
		return;
	
	FreeLibrary(WRG39WSBAPI);
	WRG39WSBAPI				= NULL;

	OpenRadioDevice			= NULL;
	CloseRadioDevice		= NULL;
	SetFrequency			= NULL;
	SetPower				= NULL;
	SetAtten				= NULL;
	SetRFAmp				= NULL;
	SetAudioBandwidth		= NULL;
	SetVolume				= NULL;
	InitializeDemodulator	= NULL;
	SetupStreams			= NULL;
}

BOOL __stdcall APILoad(void)
{
	//  If the API has already been loaded, only increment the special counter and
	// return with success.
	if (WRG39WSBAPI_Count) 
	{ 
		WRG39WSBAPI_Count++;
		return TRUE; 
	}

	//  Tries to load the API. If this fails it returns with error.
	if ((WRG39WSBAPI=LoadLibrary("WRG39WSBAPI"))==NULL) 
		return FALSE;

	//  The API has been successfully loaded. Now it has to connect to its
	// exported functions.
	CloseRadioDevice		= (FNCCloseRadioDevice)GetProcAddress(WRG39WSBAPI,"CloseRadioDevice");
	OpenRadioDevice			= (FNCOpenRadioDevice)GetProcAddress(WRG39WSBAPI,"OpenRadioDevice");
	SetFrequency			= (FNCSetFrequency)GetProcAddress(WRG39WSBAPI,"SetFrequency");
	SetPower				= (FNCSetPower)GetProcAddress(WRG39WSBAPI,"SetPower");
	SetAtten				= (FNCSetAtten)GetProcAddress(WRG39WSBAPI,"SetAtten");
	SetRFAmp				= (FNCSetRFAmp)GetProcAddress(WRG39WSBAPI,"SetRFAmp");
	SetAudioBandwidth		= (FNCSetAudioBandwidth)GetProcAddress(WRG39WSBAPI,"SetAudioBandwidth");
	SetVolume				= (FNCSetVolume)GetProcAddress(WRG39WSBAPI,"SetVolume");
	InitializeDemodulator	= (FNCInitializeDemodulator)GetProcAddress(WRG39WSBAPI,"InitializeDemodulator");
	SetupStreams			= (FNCSetupStreams)GetProcAddress(WRG39WSBAPI,"SetupStreams");

	//  If all functions have been found it increments the special counter. If not
	// the library is unloaded.
	WRG39WSBAPI_Count++;
	if (CloseRadioDevice && OpenRadioDevice && InitializeDemodulator && SetFrequency && SetPower && 
		SetAtten && SetRFAmp && SetAudioBandwidth && SetVolume && SetupStreams)
		return TRUE;
	
	//  As the library has not been completely loaded, it clears any already
	// initialized data.
	APIUnload();
	return FALSE;
}

void __stdcall SamplesAudioHandler(void *Target, void *Buf, DWORD Size, DWORD SamplingRate)
{
	if (Target) 
		fwrite(Buf, 1, Size, (FILE *)Target);
}

int main(int argc, char* argv[])
{
	// load the G3 API library
	if (!APILoad()) 
	{
		puts("WRG39WSBAPI.DLL cannot be loaded!");
		return 0;
	}

	// open the first available radio
	RADIOHANDLE hRadio = OpenRadioDevice(0);
	if (!hRadio)
	{
		puts("No WR-G39WSB device could be opened !");
		APIUnload();
		return 0;
	}

	// configure the RF hardware
	if (SetPower(hRadio, TRUE)) 
		puts("The device is turned ON");
	else 
		puts("The device failed to turn ON");

	if (SetAtten(hRadio, FALSE)) 
		puts("The attenuator is OFF");
	else 
		puts("The attenuator failed to turn OFF");

	if (SetRFAmp(hRadio, TRUE)) 
		puts("The RFAmplifier is ON");
	else 
		puts("The RFAmplifier failed to turn ON");


	// start the advanced mode
	puts("Initializing demodulator..");
	if (InitializeDemodulator(hRadio, NULL)) 
		puts("The device is initialized");
	else 
		puts("The device failed to initialization");

	if (SetAudioBandwidth(hRadio, 5000)) 
		puts("The audio bandwidth is 5000 Hz");
	else 
		puts("The audio bandwidth setting is failed");

	if (SetVolume(hRadio, 20)) 
		puts("The volume is 20");
	else 
		puts("The volume setting is failed");

	Sleep(50);
	if (SetFrequency(hRadio, 136000000)) 
		puts("The frequency is on 136 MHz");
	else 
		puts("The frequency setting is failed");

	// configure the audio stream
	FILE *Audio;

	Audio	= fopen("c:\\Audio.pcm", "wb");
	puts("Starting streaming..");

	// Start stream 
	if (SetupStreams(hRadio, NULL, NULL, SamplesAudioHandler, Audio)) 
		puts("The stream is started");
	else 
		puts("The stream failed");


	//
	// main application body comes here, the following instructions just waits for a key to be pressed
	//


	puts("Press <Enter> to stop recording..");
	getc(stdin);

	// stop the streams
	if (SetupStreams(hRadio, NULL, NULL, NULL, NULL)) 
		puts("The stream is stoped");
	else 
		puts("The stream stop is failed");

	// close the samples files
	if (Audio) 
		fclose(Audio);

	// close the device handle
	if (CloseRadioDevice(hRadio)) 
		puts("The device is closed properly");
	else 
		puts("The device failed to close");

	// free the G3 API library
	APIUnload();

	puts("Press <Enter>");
	getchar();

	return 0;
}
