//-----------------------------------------------------
// Name, first name: Hoet, Guntran
// Group: 1DAE3
//-----------------------------------------------------

//---------------------------
// Includes
//---------------------------
#include "Sound.h"

//---------------------------
// Defines
//---------------------------
#define GAME_ENGINE (GameEngine::GetSingleton())
Sound* Sound::m_SoundPtr = nullptr;
//---------------------------
// Constructor & Destructor
//---------------------------
Sound::Sound()
	// tracks
	:m_OverworldPtr(nullptr)
	,m_OverworldHurryPtr(nullptr)
	,m_UndergroundPtr(nullptr)
	,m_UndergroundHurryPtr(nullptr)
	,m_PowerUpPtr(nullptr)
	,m_StarmanPtr(nullptr)
	,m_DeadPtr(nullptr)
	,m_GameOverPtr(nullptr)
	,m_FlagPtr(nullptr)
	,m_PipePtr(nullptr)
	,m_CastleCompletePtr(nullptr)
	// ints
	,m_CoinTrackCounter()
	,m_KillTrackCounter()
	,m_JumpTrackCounter()
	,m_FireballThrowCounter()
	,m_BlockBreakTrackCounter()
	,m_BlockBumpTrackCounter()
{
	m_OverworldPtr = new Audio("./Resources/Sound/Overworld.mp3");
	m_OverworldHurryPtr = new Audio("Resources/Sound/OverworldHurry.mp3");
	m_UndergroundPtr = new Audio("Resources/Sound/Underworld.mp3");
	m_UndergroundHurryPtr = new Audio("Resources/Sound/UnderworldHurry.mp3");
	m_CastleCompletePtr = new Audio("Resources/Sound/CastleComplete.mp3");

	m_TestPtr = new Audio("Resources/Sound/Test.mp3");
	m_PipePtr = new Audio("Resources/Sound/Pipe.mp3");
	m_PowerUpPtr = new Audio("Resources/Sound/PowerUp.mp3");
	m_StarmanPtr = new Audio("Resources/Sound/Starman.mp3");

	m_DeadPtr = new Audio("Resources/Sound/Dead.mp3");
	m_GameOverPtr = new Audio("Resources/Sound/GameOver.mp3");
	m_FlagPtr = new Audio("Resources/Sound/Flag.mp3");

	// coin array
	for (int i = 0; i < COIN_TRACKS; ++i)
	{
		m_CoinPtrArr[i] = new Audio("Resources/Sound/Coin.mp3");
	}

	// jump array
	for (int i = 0; i < JUMP_TRACKS; ++i)
	{
		m_JumpPtrArr[i] = new Audio("Resources/Sound/Jump.mp3");
	}

	// kill array
	for (int i = 0; i < KILL_TRACKS; ++i)
	{
		m_KillEnemyPtrArr[i] = new Audio("Resources/Sound/KillEnemy.mp3");
	}
	// fireball throw array
	for (int i = 0; i < FIREBALL_THROW_TRACKS; ++i)
	{
		m_FireballThrowPtrArr[i] = new Audio("Resources/Sound/FireballThrow.mp3");
	}
	// block bump
	for (int i = 0; i < BLOCK_BUMP_TRACKS; ++i)
	{
		m_BlockBumpPtrArr[i] = new Audio("Resources/Sound/BlockBump.mp3");
	}
	// block break
	for (int i = 0; i < BLOCK_BREAK_TRACKS; ++i)
	{
		m_BlockBreakPtrArr[i] = new Audio("Resources/Sound/BlockBreak.mp3");
	}
}

Sound::~Sound()
{
	delete m_OverworldPtr;
	m_OverworldPtr = nullptr;

	delete m_OverworldHurryPtr;
	m_OverworldHurryPtr = nullptr;

	delete m_UndergroundPtr;
	m_UndergroundPtr = nullptr;

	delete m_UndergroundHurryPtr;
	m_UndergroundHurryPtr = nullptr;

	delete m_TestPtr;
	delete m_PowerUpPtr;
	delete m_StarmanPtr;
	delete m_DeadPtr;
	delete m_GameOverPtr;
	delete m_FlagPtr;
	delete m_PipePtr;
	delete m_CastleCompletePtr;

	m_TestPtr = nullptr;
	m_PowerUpPtr = nullptr;
	m_StarmanPtr = nullptr;
	m_DeadPtr = nullptr;
	m_GameOverPtr = nullptr;
	m_FlagPtr = nullptr;
	m_PipePtr = nullptr;
	m_CastleCompletePtr = nullptr;

	// coin array
	for (int i = 0; i < COIN_TRACKS; ++i)
	{
		delete m_CoinPtrArr[i];
		m_CoinPtrArr[i] = nullptr;
	}
	// delete kill array
	for (int i = 0; i < KILL_TRACKS; i++)
	{
		delete m_KillEnemyPtrArr[i];
		m_KillEnemyPtrArr[i] = nullptr;
	}
	// jump array
	for (int i = 0; i < JUMP_TRACKS; ++i)
	{
		delete m_JumpPtrArr[i];
		m_JumpPtrArr[i] = nullptr;
	}
	// fireball throw array
	for (int i = 0; i < FIREBALL_THROW_TRACKS; ++i)
	{
		delete m_FireballThrowPtrArr[i];
		m_FireballThrowPtrArr[i] = nullptr;
	}
	// block break
	for (int i = 0; i < BLOCK_BREAK_TRACKS; ++i)
	{
		delete m_BlockBreakPtrArr[i];
		m_BlockBreakPtrArr[i] = nullptr;
	}
	// block bump
	for (int i = 0; i < BLOCK_BUMP_TRACKS; ++i)
	{
		delete m_BlockBumpPtrArr[i];
		m_BlockBumpPtrArr[i] = nullptr;
	}
}

Sound* Sound::GetSingleton()
{
	if (m_SoundPtr == nullptr)
	{
		m_SoundPtr = new Sound();
	}
	return m_SoundPtr;
}

//---------------------------
// Methods - Member functions
//---------------------------
void Sound::Tick(double deltaTime)
{
	m_OverworldPtr->Tick();
	m_OverworldHurryPtr->Tick();
	m_UndergroundPtr->Tick();
	m_UndergroundHurryPtr->Tick();

	m_TestPtr->Tick();
	m_PowerUpPtr->Tick();
	m_StarmanPtr->Tick();
	m_DeadPtr->Tick();
	m_GameOverPtr->Tick();
	m_FlagPtr->Tick();

	// coin tick
	for (int i = 0; i < COIN_TRACKS; ++i)
	{
		m_CoinPtrArr[i]->Tick();
	}
	// jump tick
	for (int i = 0; i < JUMP_TRACKS; ++i)
	{
		m_JumpPtrArr[i]->Tick();
	}
	// kill tick
	for (int i = 0; i < KILL_TRACKS; ++i)
	{
		m_KillEnemyPtrArr[i]->Tick();
	}
	// fireball throw tick
	for (int i = 0; i < FIREBALL_THROW_TRACKS; ++i)
	{
		m_FireballThrowPtrArr[i]->Tick();
	}
	// block break
	for (int i = 0; i < BLOCK_BREAK_TRACKS; ++i)
	{
		m_BlockBreakPtrArr[i]->Tick();
	}
	// block bump
	for (int i = 0; i < BLOCK_BUMP_TRACKS; ++i)
	{
		m_BlockBumpPtrArr[i]->Tick();;
	}
}

void Sound::Theme(int track, int command, int volume)
{
	// tracks
	Audio *audioPtr = nullptr;
	switch (track)
	{
	case 0:
		audioPtr = m_OverworldPtr;
		break;

	case 1:
		audioPtr = m_OverworldHurryPtr;
		break;

	case 2:		
		audioPtr = m_UndergroundPtr;
		break;

	case 3:
		audioPtr = m_UndergroundHurryPtr;
		break;

	case 4:
		audioPtr = m_CastleCompletePtr;
		break;

	case 5:
		audioPtr = m_StarmanPtr;
		break;

	default:
		break;
	}

	// Commands
	switch (command)
	{
	case 0:
		audioPtr->Stop();
		break;

	case 1:
		audioPtr->Play();
		if (audioPtr != m_OverworldPtr)			m_OverworldPtr->Pause();
		if (audioPtr != m_OverworldHurryPtr)	m_OverworldHurryPtr->Pause();
		if (audioPtr != m_UndergroundPtr)		m_UndergroundPtr->Pause();
		if (audioPtr != m_UndergroundHurryPtr)	m_UndergroundHurryPtr->Pause();
		if (audioPtr != m_CastleCompletePtr)	m_CastleCompletePtr->Pause();
		if (audioPtr != m_StarmanPtr)			m_StarmanPtr->Stop();
		break;

	case 2:
		audioPtr->Pause();
		break;

	default:
		break;
	}

	// volume
	if (volume >= 0 && volume <= 100)
	{
		m_OverworldPtr->SetVolume(volume);
		m_OverworldHurryPtr->SetRepeat(true);
	}
}

void Sound::SFX(int track = 0, int command, int volume)	
{
	Audio *audioPtr = nullptr;

	// audio track
	switch (track)
	{
	case 0:
		audioPtr = m_TestPtr;
		break;

	case 1:
		audioPtr = m_JumpPtrArr[m_JumpTrackCounter++];
		m_JumpTrackCounter %= JUMP_TRACKS;
		break;

	case 2:
		audioPtr = m_BlockBumpPtrArr[m_BlockBumpTrackCounter++];
		m_BlockBumpTrackCounter %= BLOCK_BUMP_TRACKS;
		break;

	case 3:
		audioPtr = m_PipePtr;
		break;

	case 4:
		audioPtr = m_CoinPtrArr[m_CoinTrackCounter++];
		m_CoinTrackCounter %= COIN_TRACKS;
		break;

	case 5:
		audioPtr = m_PowerUpPtr;
		break;

	case 6:
		audioPtr = m_StarmanPtr;
		break;

	case 7:
		audioPtr = m_KillEnemyPtrArr[m_KillTrackCounter++];
		m_KillTrackCounter %= KILL_TRACKS;

		break;

	case 8:
		audioPtr = m_DeadPtr;
		break;

	case 9:
		audioPtr = m_GameOverPtr;
		break;

	case 10:
		audioPtr = m_BlockBreakPtrArr[m_BlockBreakTrackCounter++];
		m_BlockBreakTrackCounter %= BLOCK_BREAK_TRACKS;
		break;

	case 11:
		audioPtr = m_FireballThrowPtrArr[m_FireballThrowCounter++];
		m_FireballThrowCounter %= FIREBALL_THROW_TRACKS;
		break;

	case 12:
		audioPtr = m_FlagPtr;
		break;

	default:
		break;
	}

	// command
	switch (command)
	{
	case 0:
		audioPtr->Stop();
		break;

	case 1:
		audioPtr->Play();
		break;

	case 2:
		audioPtr->Pause();
		break;

	default:
		break;
	}

	// volume
	if (volume >= 0 && volume <= 100)
	{
		audioPtr->SetVolume(volume);
	}
}
