#include "FModSystem.h"
#include "System/Config.h"
#include "DFunc/DController.h"
#include "DFunc/debug.h"
#include <sstream>

bool FModSystem::isFModOk(FMOD_RESULT &result) const
{
	if (result != FMOD_OK)
	{
#		ifdef DEBUG
		std::stringstream converter;
		converter << result << " - " << FMOD_ErrorString(result);
		LOG("FMod Error: " + converter.str());
#		endif
		std::cerr << "FMOD error!" << result << FMOD_ErrorString(result) << std::endl;
		return false;
	}
	return true;
}

FModSystem::FModSystem(int s_size)
{
	spectrum_size = s_size;
	input_channel_group_name = "Input";
	recorder_device_id = Config::Instance()->getRecordDevice();	//the ID number printed above (just using default for now, TODO: read from config)
	std::stringstream converter;
	result = FMOD_System_Create(&system); 
	if (isFModOk(result))
#		ifdef DEBUG
		LOG("FMod System Online.");
#		else
		;
#		endif

	
	result = FMOD_System_Init(system, Config::Instance()->getSoftwareChannels(), FMOD_INIT_NORMAL, 0);
#		ifdef DEBUG
		LOG("FMod System Initialized");
#		else
		;
#		endif
	result = FMOD_System_CreateChannelGroup(system, input_channel_group_name.c_str(), &input_channel_group);
#		ifdef DEBUG
		LOG("Input Channelgroup created");
#		else
		;
#		endif	
	result = FMOD_System_GetRecordNumDrivers(system, &num_record_drivers);
	{
#		ifdef DEBUG
		converter << num_record_drivers;
		LOG(converter.str() + " Sound Recording Drivers", (num_record_drivers==0) ? CL_ERROR : CL_LOG);
#		endif
	}

	if (num_record_drivers > 0)
	{
		if (recorder_device_id > num_record_drivers-1)
		{
			char name[256];
			std::stringstream converter;
			result = FMOD_System_GetRecordDriverName(system, 0, name, 256);
			if (!isFModOk(result))
			{
				converter << "Can't set recorder" << std::endl;
			}
			else
				converter << "Invalid recorder ID: " << recorder_device_id << ". Using default: 0 (" << name << ")";
			recorder_device_id = 0;
#			ifdef DEBUG
			LOG(converter.str(), CL_ERROR);
#			endif
			std::cerr << converter << std::endl;
		}
		result = FMOD_System_SetRecordDriver(system, recorder_device_id); 
		if (isFModOk(result))
		{
#			ifdef DEBUG
			std::string log_entry;
			char name[256];
			result = FMOD_System_GetRecordDriverName(system, recorder_device_id, name, 256);
			if (isFModOk(result))
			{
				log_entry = "Using Recorder Device: ";
				log_entry.append(name);
				LOG(log_entry);
			}
#			endif
		}
	}
	//setup spectrum datas
	spectrum_buffer = new float[spectrum_size];
	
	//sub-divided spectrum band
	band_sub_divisions 					= 64;

	e_mean.resize(band_sub_divisions, 0.0f);
	e_subband.resize(band_sub_divisions, 0.0f);
	e_variance.resize(band_sub_divisions);
	
	db_spectrum_buffer.resize(spectrum_size/2, 0.0f);	//we only compute decibels on 1/2 of the spectrum. we ignore 22050 and above.	
	

}

FModSystem::~FModSystem()
{
	delete []spectrum_buffer;	//I fucking hate arrays.
}
