#include "cSound.hpp"

/*** Custom Header Files ***/
#include "../UtilityEngine/cUtility.hpp"

using AudioEngine::cSound;
using UtilityEngine::cUtility;

cSound::cSound( const cString& dir /*= ""*/, const cString& filename /*= ""*/, const unsigned char volume /*= 255*/,
			const unsigned char distance /*= 100*/, const short int angle /*= 0*/, const long int channel /*= -1*/,
			const long int loops /*= -1*/ )
: mp_sound(nullptr), m_dir(dir), m_fileName(filename), m_volume(volume), m_distance(distance),
	m_angle(angle), m_channel(channel), m_loops(loops)
{
	if (m_fileName != "")
		LoadSound();
}

cSound::cSound( const cSound& copy )
: mp_sound(nullptr), m_dir(copy.getDir()), m_fileName(copy.getFileName()), m_volume(copy.getVolume()),
	m_distance(copy.getDistance()), m_angle(copy.getAngle()), m_channel(copy.getChannel()),
	m_loops(copy.getLoops())
{
	if (m_fileName != "")
		LoadSound();
}

cSound::~cSound()
{
	UnloadSound();
}

void cSound::PlaySound()
{
	if (mp_sound != nullptr) {
		if (Mix_Volume(m_channel, m_volume) < 0)
			cUtility::Inst().Message("Unable to set volume. Mix_Volume():", __AT__, cUtility::eTypeSDL::MIXER);
		if (Mix_SetPosition(m_channel, m_angle, m_distance) < 0)
			cUtility::Inst().Message("Unable to set position. Mix_SetPosition():", __AT__, cUtility::eTypeSDL::MIXER);
		if (Mix_PlayChannel(m_channel, mp_sound, m_loops) < 0)
			cUtility::Inst().Message("Unable to set channel. Mix_PlayChannel():", __AT__, cUtility::eTypeSDL::MIXER);
	}
}

void cSound::FadeIn( const unsigned int time /*= 1000*/ ) const
{
	if (Mix_FadeInChannel(m_channel, mp_sound, m_loops, time) < 0)
		cUtility::Inst().Message("Unable to fade in channel. Mix_FadeInChannel():", __AT__, cUtility::eTypeSDL::MIXER);
}

void cSound::FadeOut( const unsigned int time /*= 1000*/ ) const
{
	if (Mix_FadeOutChannel(m_channel, time) < 0)
		cUtility::Inst().Message("Unable to fade out channel. Mix_FadeOutChannel():", __AT__, cUtility::eTypeSDL::MIXER);
}

///Sets
void cSound::setDir( const cString& dir )
{
	m_dir = dir;
}

void cSound::setFileName( const cString& filename )
{
	m_fileName = filename;
	LoadSound();
}

void cSound::setFileNameandDir( const cString& filename, const cString& dir /*= ""*/ )
{
	setDir(dir);
	setFileName(filename);
}

void cSound::setVolume( const unsigned char volume /*= 255*/ )
{
	m_volume = volume;
}

void cSound::setDistance( const unsigned char distance /*= 100*/ )
{
	m_distance = distance;
}

void cSound::setAngle( const short int angle /*= 0*/ )
{
	m_angle = angle;
}

void cSound::setChannel( const long int channel /*= -1*/ )
{
	m_channel = channel;
}

void cSound::setLoops( const long int loops /*= -1*/ )
{
	m_loops = loops;
}

///Gets
const cString cSound::getDir() const
{
	return m_dir;
}

const cString cSound::getFileName() const
{
	return m_fileName;
}

const unsigned char cSound::getVolume() const
{
	return m_volume;
}

const unsigned char cSound::getDistance() const
{
	return m_distance;
}

const short int cSound::getAngle() const
{
	return m_angle;
}

const long int cSound::getChannel() const
{
	return m_channel;
}

const long int cSound::getLoops() const
{
	return m_loops;
}

///Private
///Functions
void cSound::LoadSound()
{
	UnloadSound();
	if (m_fileName != "")
		if (mp_sound == nullptr)
			if ((mp_sound = Mix_LoadWAV(((cString)(m_dir + m_fileName)).c_str())) == nullptr)
				cUtility::Inst().Message("Unable to load file. " + m_dir + m_fileName, "", cUtility::eTypeSDL::MIXER);
}

void cSound::UnloadSound()
{
	if (mp_sound != nullptr)
	{
		Mix_FreeChunk(mp_sound);
		mp_sound = nullptr;
	}
}