// Project Lab - NHTV Igad

#include "UnrealProject.h"
#include "DefaultGameInstance.h"
#include "Prefs.h"
#include "MusicPlayer.h"


AMusicPlayer::AMusicPlayer()
{
	PrimaryActorTick.bCanEverTick = true;

	RootComponent = audioComponent = CreateDefaultSubobject<UAudioComponent>(TEXT("Audio"));

	bReplicates = true;

	m_setInCombat = false;
	m_isInCombat = false;
}

void AMusicPlayer::BeginPlay()
{
	Super::BeginPlay();

	float volume = Cast<UDefaultGameInstance>(GetGameInstance())->GetPrefs()->musicVolume;
	audioComponent->SetVolumeMultiplier(volume);

	if (generalMusic.Num() > 0)
	{
		m_currentTrack = FMath::Rand() % generalMusic.Num();

		audioComponent->SetSound(generalMusic[m_currentTrack]);
		audioComponent->Play();
	}
}

void AMusicPlayer::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );

	// Change the music combat state
	if (m_setInCombat != m_isInCombat)
	{
		// Fade out the volume
		m_changeTime += DeltaTime * 1.5f;
		if (m_changeTime >= 1)
		{
			// Set next state
			m_isInCombat = m_setInCombat;
			audioComponent->Stop();
			m_changeTime = 0;
		}
	}

	float volume = Cast<UDefaultGameInstance>(GetGameInstance())->GetPrefs()->musicVolume;
	audioComponent->SetVolumeMultiplier(volume * (1.0f - m_changeTime));

	if (!audioComponent->IsPlaying())
		m_SelectNextTrack();
}

void AMusicPlayer::m_SelectNextTrack()
{
	// Regenerate the array of music (in case any tracks are NULL)
	TArray<USoundBase*>& sampleFrom = (m_isInCombat ? combatMusic : generalMusic);
	if (sampleFrom.Num() == 0)
		return;
	TArray<USoundBase*> availableTracks;
	for (int32 i = 0; i < sampleFrom.Num(); i++)
	{
		if (sampleFrom[i])
			availableTracks.Add(sampleFrom[i]);
	}
	if (availableTracks.Num() == 0)
		return;

	// Only select a random playlist if there are plenty of tracks 
	const int32 trackCount = availableTracks.Num();
	if (trackCount > 5)
	{
		// Add the current track to the recently played list
		m_lastTracks.Add(m_currentTrack);
		while (m_lastTracks.Num() > 3)
			m_lastTracks.RemoveAt(0);

		// Select a random number
		m_currentTrack = FMath::Rand() % availableTracks.Num();
		while (true)
		{
			// Check in the array of recently played to see if we already played this
			bool found = false;
			for (int32 i = 0; i < m_lastTracks.Num(); i++)
			{
				if (m_currentTrack == m_lastTracks[i])
				{
					found = true;
					break;
				}
			}
			if (!found)
				break;

			// Pick the next track and see if we havent already played that
			m_currentTrack = (m_currentTrack + 1) % availableTracks.Num();
		}
	}
	else
		m_currentTrack = (m_currentTrack + 1) % availableTracks.Num();

	// Set the new track
	audioComponent->SetSound(availableTracks[m_currentTrack]);
	audioComponent->Play();
}

void AMusicPlayer::SetInCombat(bool inCombat)
{
	check(Role == ROLE_Authority);
	m_setInCombat = inCombat;
	m_changeTime = 0;
}

void AMusicPlayer::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);

	DOREPLIFETIME(AMusicPlayer, m_setInCombat);
}