// Project Lab - NHTV Igad

#include "UnrealProject.h"

#include "NetworkDoor.h"


ANetworkDoor::ANetworkDoor()
{
	PrimaryActorTick.bCanEverTick = true;
	debugColorCode = FColor::Red;

	doorCollider = CreateDefaultSubobject<UBoxComponent>(TEXT("Cube"));
	doorCollider->SetCollisionProfileName(TEXT("BlockAll"));
	RootComponent = doorCollider;

	meshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
	meshComponent->AttachTo(doorCollider);

	isDoorClosed = true;
	closeAfterTime = 0.0f;

	debugSinkDepth = 250;
}


void ANetworkDoor::BeginPlay()
{
	Super::BeginPlay();
	m_openTime = 0.0f;
}

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

	if (doorCollider)
	{
		// Enable or disable the door collider
		doorCollider->SetCollisionEnabled(isDoorClosed ? ECollisionEnabled::QueryAndPhysics : ECollisionEnabled::NoCollision);
	}

	if (meshComponent)
	{
		const FVector localPos = meshComponent->GetRelativeTransform().GetLocation();
		const FVector targetPos = FVector(0, 0, isDoorClosed ? 0.0f : -debugSinkDepth);
		
		const float distanceSqr = FVector::DistSquared(localPos, targetPos);
		if (distanceSqr > 0.01f)
		{
			FVector dif = targetPos - localPos;
			dif.Normalize();
			float speed = DeltaTime * 800 * (debugSinkDepth / 250.0f);
			const float distance = FMath::Sqrt(distanceSqr);
			if (speed > distance) speed = distance;
			dif *= speed;
			meshComponent->SetRelativeLocation(localPos + dif);
		}
	}

	if(Role == ROLE_Authority && !isDoorClosed && closeAfterTime > 0)
	{
		m_openTime += DeltaTime;
		if(m_openTime >= closeAfterTime)
		{
			SetDoorState(true);
			m_openTime = 0.0f;
		}
	}
}

void ANetworkDoor::ToggleDoor()
{
	// Server only function
	check(Role == ROLE_Authority);
	isDoorClosed = !isDoorClosed;
}

void ANetworkDoor::SetDoorState(bool NewState)
{
	// Server only function
	check(Role == ROLE_Authority);
	isDoorClosed = NewState;
}

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

	DOREPLIFETIME(ANetworkDoor, isDoorClosed);
}