#include "HyperTwistTraining/HyperTwistCoachDashboardPlayerController.h"

#include "EngineUtils.h"
#include "HyperTwistTraining/HyperTwistCoachDashboardActor.h"

AHyperTwistCoachDashboardPlayerController::AHyperTwistCoachDashboardPlayerController()
{
	bShowMouseCursor = true;
	bEnableClickEvents = true;
	bEnableMouseOverEvents = true;
}

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

	ApplyDashboardInputMode();

	if (bBootstrapCoachDashboardOnBeginPlay)
	{
		EnsureCoachDashboard();
	}
}

AHyperTwistCoachDashboardActor* AHyperTwistCoachDashboardPlayerController::EnsureCoachDashboard()
{
	if (ActiveDashboardActor == nullptr)
	{
		ActiveDashboardActor = FindExistingDashboardActor();
	}

	if (ActiveDashboardActor == nullptr)
	{
		ActiveDashboardActor = SpawnDashboardActor();
	}

	if (ActiveDashboardActor != nullptr)
	{
		ApplyDashboardDefaults(ActiveDashboardActor);
		ActiveDashboardActor->CreateAndShowDashboard();
	}

	return ActiveDashboardActor;
}

void AHyperTwistCoachDashboardPlayerController::RefreshCoachDashboard()
{
	if (EnsureCoachDashboard() != nullptr)
	{
		ActiveDashboardActor->RefreshDashboard();
	}
}

void AHyperTwistCoachDashboardPlayerController::ApplyDashboardInputMode()
{
	bShowMouseCursor = bShowCoachDashboardMouseCursor;
	bEnableClickEvents = bShowCoachDashboardMouseCursor;
	bEnableMouseOverEvents = bShowCoachDashboardMouseCursor;

	if (bUseGameAndUiInputMode)
	{
		FInputModeGameAndUI InputMode;
		InputMode.SetHideCursorDuringCapture(false);
		InputMode.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
		SetInputMode(InputMode);
	}
}

AHyperTwistCoachDashboardActor*
AHyperTwistCoachDashboardPlayerController::FindExistingDashboardActor() const
{
	if (GetWorld() == nullptr)
	{
		return nullptr;
	}

	for (TActorIterator<AHyperTwistCoachDashboardActor> ActorIt(GetWorld()); ActorIt; ++ActorIt)
	{
		return *ActorIt;
	}

	return nullptr;
}

AHyperTwistCoachDashboardActor*
AHyperTwistCoachDashboardPlayerController::SpawnDashboardActor()
{
	if (GetWorld() == nullptr)
	{
		return nullptr;
	}

	TSubclassOf<AHyperTwistCoachDashboardActor> ResolvedActorClass = DashboardActorClass;
	if (*ResolvedActorClass == nullptr)
	{
		ResolvedActorClass = AHyperTwistCoachDashboardActor::StaticClass();
	}
	if (*ResolvedActorClass == nullptr)
	{
		return nullptr;
	}

	FTransform SpawnTransform;
	AHyperTwistCoachDashboardActor* DashboardActor = GetWorld()->SpawnActorDeferred<AHyperTwistCoachDashboardActor>(
		ResolvedActorClass,
		SpawnTransform,
		nullptr,
		nullptr,
		ESpawnActorCollisionHandlingMethod::AlwaysSpawn
	);
	if (DashboardActor == nullptr)
	{
		return nullptr;
	}

	ApplyDashboardDefaults(DashboardActor);
	DashboardActor->FinishSpawning(SpawnTransform);
	return DashboardActor;
}

void AHyperTwistCoachDashboardPlayerController::ApplyDashboardDefaults(
	AHyperTwistCoachDashboardActor* DashboardActor) const
{
	if (DashboardActor == nullptr)
	{
		return;
	}

	DashboardActor->DashboardDefaultUserId = DashboardDefaultUserId;
	DashboardActor->DashboardDefaultSessionId = DashboardDefaultSessionId;
	DashboardActor->DashboardDefaultMode = DashboardDefaultMode;
	DashboardActor->DashboardDefaultCoachMaxCases = DashboardDefaultCoachMaxCases;
}
