#include "Utility/RWTHVRClusterUtilities.h"

#include "DisplayClusterConfigurationTypes.h"
#include "DisplayClusterRootActor.h"
#include "IDisplayCluster.h"
#include "Cluster/IDisplayClusterClusterManager.h"
#include "Components/DisplayClusterCameraComponent.h"
#include "Config/IDisplayClusterConfigManager.h"
#include "Engine/Engine.h"
#include "Engine/LocalPlayer.h"
#include "Game/IDisplayClusterGameManager.h"

DEFINE_LOG_CATEGORY(RWTHVRCluster);

bool URWTHVRClusterUtilities::IsRoomMountedMode()
{
	return IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster;
}

bool URWTHVRClusterUtilities::IsCave()
{
	if (!IsRoomMountedMode())
		return false;

	const UDisplayClusterConfigurationData* ClusterConfig = IDisplayCluster::Get().GetConfigMgr()->GetConfig();
	return ClusterConfig->CustomParameters.Contains("Hardware_Platform") &&
		ClusterConfig->CustomParameters.Find("Hardware_Platform")->Equals("aixcave", ESearchCase::IgnoreCase);
}

bool URWTHVRClusterUtilities::IsRolv()
{
	if (!IsRoomMountedMode())
		return false;

	const UDisplayClusterConfigurationData* ClusterConfig = IDisplayCluster::Get().GetConfigMgr()->GetConfig();
	return ClusterConfig->CustomParameters.Contains("Hardware_Platform") &&
		ClusterConfig->CustomParameters.Find("Hardware_Platform")->Equals("ROLV", ESearchCase::IgnoreCase);
}

/* Return true on the Primary in cluster mode and in a normal desktop session. Otherwise false */
bool URWTHVRClusterUtilities::IsPrimaryNode()
{
	if (!IDisplayCluster::IsAvailable())
	{
		return true;
	}
	IDisplayClusterClusterManager* Manager = IDisplayCluster::Get().GetClusterMgr();
	if (Manager == nullptr)
	{
		return true; // if we are not in cluster mode, we are always the primary node
	}
	return Manager->IsPrimary() || !Manager->IsSecondary();
}

bool URWTHVRClusterUtilities::IsSecondaryNode() { return !IsPrimaryNode(); }

FString URWTHVRClusterUtilities::GetNodeName()
{
	return IsRoomMountedMode() ? IDisplayCluster::Get().GetClusterMgr()->GetNodeId() : FString(TEXT("Localhost"));
}

float URWTHVRClusterUtilities::GetEyeDistance()
{
	const ADisplayClusterRootActor* RootActor = IDisplayCluster::Get().GetGameMgr()->GetRootActor();
	return (RootActor) ? RootActor->GetDefaultCamera()->GetInterpupillaryDistance() : 0.0f;
}

EDisplayClusterEyeStereoOffset URWTHVRClusterUtilities::GetNodeEyeType()
{
	const ADisplayClusterRootActor* RootActor = IDisplayCluster::Get().GetGameMgr()->GetRootActor();
	return (RootActor) ? RootActor->GetDefaultCamera()->GetStereoOffset() : EDisplayClusterEyeStereoOffset::None;
}