#include "FModSoundInput.h"
#include "DFunc/DController.h"
#include "DFunc/debug.h"

#include "windows.h"
#include <cstdio>
#include <cstdlib>
#include <ctime>

FModSoundInput::FModSoundInput()
{
	datalength = 0;
	system = FModSystem::Instance()->getSystem();
	if (system != NULL)
	{
		memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
		exinfo.cbsize           = sizeof(FMOD_CREATESOUNDEXINFO);
		exinfo.numchannels      = 1;
		exinfo.format           = FMOD_SOUND_FORMAT_PCM16;
		exinfo.defaultfrequency = 44100;
		exinfo.length           = exinfo.defaultfrequency * sizeof(short) * exinfo.numchannels * 2;
    
		result = FMOD_System_CreateSound(system, NULL, FMOD_2D | FMOD_LOOP_NORMAL | FMOD_SOFTWARE | FMOD_OPENUSER, &exinfo, &sound);
		if (!FModSystem::Instance()->isFModOk(result))
			system = NULL;

		result = FMOD_System_RecordStart(system, sound, true);
		
		if (!FModSystem::Instance()->isFModOk(result))
			system = NULL;
		else
		{
			Sleep(100);	//needed to put a break between recording and playing.

			FMOD_CHANNEL *input_channel;
	
			result = FMOD_System_PlaySound(system, FMOD_CHANNEL_FREE, sound, false, &input_channel);
			FModSystem::Instance()->isFModOk(result);
			
			FMOD_Channel_SetChannelGroup(input_channel, FModSystem::Instance()->getInputChannelGroup());
			FModSystem::Instance()->isFModOk(result);
		}
	}
#	ifdef DEBUG
	else
		LOG("SYSTEM IS NULL");
#	endif
}
void FModSoundInput::update()
{
	
}
void FModSoundInput::process()
{
}
void FModSoundInput::processEvent(Event *event)
{
	
}
void FModSoundInput::writeWavHeader(FMOD_SOUND *sound, int length)
{
    int             channels, bits;
    float           rate;

    if (!sound)
		return;

	fseek(audio_fp_out, 0, SEEK_SET);

	FMOD_Sound_GetFormat(sound, 0, 0, &channels, &bits);
	FMOD_Sound_GetDefaults(sound, &rate, 0, 0, 0);
	{
		#if defined(WIN32) || defined(_WIN64) || defined(__WATCOMC__) || defined(_WIN32) || defined(__WIN32__)
		#pragma pack(1)
		#endif

		//wav stucture
		typedef struct
		{
			signed char id[4];
			int 		size;
		} RiffChunk;

		struct
		{
			RiffChunk       chunk           __PACKED;
			unsigned short	wFormatTag      __PACKED;    // format type
			unsigned short	nChannels       __PACKED;    // number of channels (i.e. mono, stereo...)
			unsigned int	nSamplesPerSec  __PACKED;    // sample rate
			unsigned int	nAvgBytesPerSec __PACKED;    // for buffer estimation
			unsigned short	nBlockAlign     __PACKED;    // block size of data
			unsigned short	wBitsPerSample  __PACKED;    // number of bits per sample of mono data
		} FmtChunk  = { {{'f','m','t',' '}, sizeof(FmtChunk) - sizeof(RiffChunk) }, 1, channels, (int)rate, (int)rate * channels * bits / 8, 1 * channels * bits / 8, bits } __PACKED;

		struct
		{
			RiffChunk   chunk;
		} DataChunk = { {{'d','a','t','a'}, length } };

		struct
		{
			RiffChunk   chunk;
			signed char rifftype[4];
		} WavHeader = { {{'R','I','F','F'}, sizeof(FmtChunk) + sizeof(RiffChunk) + length }, {'W','A','V','E'} };

		#if defined(WIN32) || defined(_WIN64) || defined(__WATCOMC__) || defined(_WIN32) || defined(__WIN32__)
		#pragma pack()
		#endif
      
		//    Write out the WAV header.
		fwrite(&WavHeader, sizeof(WavHeader), 1, audio_fp_out);
		fwrite(&FmtChunk, sizeof(FmtChunk), 1, audio_fp_out);
		fwrite(&DataChunk, sizeof(DataChunk), 1, audio_fp_out);
	}
}

FModSoundInput::~FModSoundInput()
{

}
