// Fill out your copyright notice in the Description page of Project Settings.
#include "OpenDoor.h"
#include "Components/AudioComponent.h"
#include "Components/PrimitiveComponent.h"
#include "Engine/World.h"
#include "GameFramework/Actor.h"
#include "GameFramework/PlayerController.h"

#define OUT

// Sets default values for this component's properties
UOpenDoor::UOpenDoor()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	PrimaryComponentTick.bCanEverTick = true;

	// ...
}

// Called when the game starts
void UOpenDoor::BeginPlay()
{
	Super::BeginPlay();

	InitialYaw = GetOwner()->GetActorRotation().Yaw;
	CurrentYaw = InitialYaw;
	TargetAngleOfOpenDoor += InitialYaw;
	
	FindPressurePlateComponent();

	FindAudioComponent();
	//ActorThatOpens = GetWorld()->GetFirstPlayerController()->GetPawn();
}

void UOpenDoor::FindAudioComponent()
{
	AudioComponent = GetOwner()->FindComponentByClass<UAudioComponent>(); //<> for function templates
	if(!AudioComponent) // same as if(PhysicsHandle == nullptr)
	{
	UE_LOG(LogTemp, Error, TEXT("No Audio component found on: %s !"), *GetOwner()->GetName());
	}
}

void UOpenDoor::FindPressurePlateComponent()
{
	if(!PressurePlate)
	{
		UE_LOG(LogTemp, Error, TEXT("%s has OpenDoor on it, but no PressurePlate set!"), *GetOwner()->GetName());
	}
}

// Called every frame
void UOpenDoor::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

	// ...
	//if(PressurePlate->IsOverlappingActor(ActorThatOpens)) // kann nullpointer + UE4 crash geben
	//if(PressurePlate && PressurePlate->IsOverlappingActor(ActorThatOpens)) //prüft erst, ob es ein actor gibt
	if(TotalMass() > MassToOpenDoor)
	{
		OpenDoor(DeltaTime);
		//DoorLastOpened When the door was opened
		DoorLastOpened = GetWorld()->GetTimeSeconds();;
	}

	else
	{
		//if door has been open longer than DoorCloseDelay
		//if(GetWorld()->GetTimeSeconds() > DoorLastOpened + DoorDelay)
		if(GetWorld()->GetTimeSeconds() - DoorLastOpened > DoorDelay)
		CloseDoor(DeltaTime);
	}
}

void UOpenDoor::OpenDoor(float DeltaTime)
{
	FRotator DoorRotation = GetOwner()->GetActorRotation();	
	//CurrentYaw = FMath::FInterpTo(CurrentYaw, TargetYaw, DeltaTime, 2.f);
	CurrentYaw = FMath::Lerp(CurrentYaw, TargetAngleOfOpenDoor, DeltaTime * OpenDoorRotationSpeed); //complex Interpolation
	DoorRotation.Yaw = CurrentYaw;
	GetOwner()->SetActorRotation(DoorRotation);

	CloseDoorSoundHasBeenPlayed = false;
	if(!AudioComponent){return;}
	if(!OpenDoorSoundHasBeenPlayed)
	{
		AudioComponent->Play();
		OpenDoorSoundHasBeenPlayed = true;
	}
}

void UOpenDoor::CloseDoor(float DeltaTime)
{
	FRotator DoorRotation = GetOwner()->GetActorRotation();
	CurrentYaw = FMath::Lerp(CurrentYaw, InitialYaw, DeltaTime * CloseDoorRotationSpeed);
	DoorRotation.Yaw = CurrentYaw;
	GetOwner()->SetActorRotation(DoorRotation);
	
	OpenDoorSoundHasBeenPlayed = false;
	if(!AudioComponent){return;}
	if(!CloseDoorSoundHasBeenPlayed)
	{
		AudioComponent->Play();
		CloseDoorSoundHasBeenPlayed = true;
	}
}

float UOpenDoor::TotalMass() const
{
	float TotalMass = 0.f;

	//find All Overlapping Actors
	TArray<AActor*> OverlapingActors;

	if (!PressurePlate){return TotalMass;}
	PressurePlate->GetOverlappingActors(OUT OverlapingActors);

	//Add Up Their Masses
	for(AActor* Actor : OverlapingActors)
	{
		TotalMass += Actor -> FindComponentByClass<UPrimitiveComponent>()->GetMass();
		UE_LOG(LogTemp, Warning, TEXT("%s is on the pressureplate"), *Actor->GetName());
	}

	return TotalMass;
}

//Notes
	//UE_LOG(LogTemp, Warning, TEXT("%f"), TargetYaw);
	// UE_LOG(LogTemp, Warning, TEXT("%s"), *GetOwner()->GetActorRotation().ToString());
	// UE_LOG(LogTemp, Warning, TEXT("The Yaw is: %f"), GetOwner()->GetActorRotation().Yaw);

	// FRotator CurrentRotation = GetOwner()->GetActorRotation();
	// FMath::Lerp(CurrentRotation, FRotator(0.f,90.f,0.f), 0.2f);
	
	// GetOwner()->SetActorRotation(CurrentRotation);
	// UE_LOG(LogTemp, Warning, TEXT("The Yaw is: %f"), CurrentRotation.Yaw);
	//TargetYaw = 90.f;
	// FRotator OpenDoor(0.f, 0.f, 0.f);
	// //OpenDoor.Yaw = FMath::Lerp(CurrentYaw, TargetYaw, 0.02f); //complex Interpolation
	// OpenDoor.Yaw = FMath::FInterpTo(CurrentYaw, TargetYaw, DeltaTime, 2.f);//complex Interpolation Framerate unabhängig wegen Deltatime
	// //OpenDoor.Yaw = FMath::FInterpConstantTo(CurrentYaw, TargetYaw, DeltaTime, 0.02f); //lineare interpolation
	// GetOwner()->SetActorRotation(OpenDoor);
	
	
	
	//float f = 10.f;
	//FRotator CurrentRotation = GetOwner()->GetActorRotation();
	//FRotator Rotation = FRotator(0.f, -90.f, 0.f);
	//FRotator OpenDoor={float,float,float}
	//FRotator OpenDoor{float,float,float}
	//FRotator OpenDoor(float,float,float)
	//CurrentRotation.Yaw = 90.f;

	//GetOwner()->SetActorRotation(CurrentRotation);