// Project Lab - NHTV Igad

#include "UnrealProject.h"
#include "NetworkPossessable.h"
#include "DefaultPlayerController.h"


// Sets default values
ANetworkPossessable::ANetworkPossessable()
{
	
}

// Called every frame
void ANetworkPossessable::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );

	m_UpdateCamera();
}


void ANetworkPossessable::AddMovementInput(FVector WorldDirection, float ScaleValue /*= 1.0f*/, bool bForce /*= false*/)
{
	check(!WorldDirection.ContainsNaN());
	check(!FMath::IsNaN(ScaleValue));
	if(m_AllowedToMove())
		Super::AddMovementInput(WorldDirection, ScaleValue, bForce);
}
void ANetworkPossessable::SetCharacterRotation(FRotator rotator)
{
	if (m_AllowedToRotate())
		SetActorRotation(rotator);
	if(Role != ROLE_Authority)
	{
		m_SetCharacterRotation_Server(rotator.Yaw);
	}
}
void ANetworkPossessable::AddControllerYawInput(float Val)
{
	if(m_AllowedToRotate())
		Super::AddControllerYawInput(Val);
}

bool ANetworkPossessable::m_SetCharacterRotation_Server_Validate(float rotation)
{
	return true;
}
void ANetworkPossessable::m_SetCharacterRotation_Server_Implementation(float rotation)
{
	SetActorRotation(FRotator(0.0f, rotation, 0.0f));
}


bool ANetworkPossessable::m_AllowedToMove()
{
	return true;
}
bool ANetworkPossessable::m_AllowedToRotate()
{
	return true;
}


void ANetworkPossessable::m_SetupCamera()
{
	// Create a camera boom
	CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
	CameraBoom->AttachTo(RootComponent);
	CameraBoom->bAbsoluteRotation = true;
	CameraBoom->TargetArmLength = 1500.f;
	CameraBoom->RelativeRotation = FRotator(-60.f, 45.f, 0.f);
	CameraBoom->bDoCollisionTest = false;
	CameraBoom->bInheritPitch = false;
	CameraBoom->bInheritYaw = false;
	CameraBoom->bInheritRoll = false;

	// Create a camera
	TopDownCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("TopDownCamera"));
	TopDownCamera->AttachTo(CameraBoom, USpringArmComponent::SocketName);
	TopDownCamera->bUsePawnControlRotation = false;

	// Don't rotate character to camera direction
	bUseControllerRotationPitch = false;
	bUseControllerRotationYaw = false;
	bUseControllerRotationRoll = false;
}
void ANetworkPossessable::m_UpdateCamera()
{
	if (!IsValid(CameraBoom)) return;

	ADefaultPlayerController* const controller = Cast<ADefaultPlayerController>(GetController());
	if (IsValid(controller))
	{
		// Ensure the camera does not fall under the ground
		const FVector playerCoord = GetActorLocation();
		if (playerCoord.Z < 0)
			CameraBoom->SetRelativeLocation(FVector(0, 0, -playerCoord.Z));
		else if (CameraBoom->GetComponentLocation().Z < 0)
			CameraBoom->SetRelativeLocation(FVector());

		// Update last position
		if (GetCharacterMovement()->IsMovingOnGround())
			controller->UpdatePlayerPosition(GetActorLocation(), GetActorRotation());
	}
}