// Fill out your copyright notice in the Description page of Project Settings.

#include "ShelfComponent.h"

#include "Engine/StaticMeshActor.h"
#include "Faye/System/FayeDeveloperSettings.h"


UShelfComponent::UShelfComponent()
{
	PrimaryComponentTick.bCanEverTick = true;
}

void UShelfComponent::GenerateBookRow()
{
	if (!TransparentBookMaterial || TransparentBookMaterial_Highlighted)
	{
		LoadMaterials();
	}
	
	const UFayeDeveloperSettings* DeveloperSettings = GetDefault<UFayeDeveloperSettings>();
	check(DeveloperSettings);
		
	float ShelfWidth = GetScaledBoxExtent().X * 2;
	const float BookOffset = 1.f;
	
	for (int32 i = ShelfStaticMeshes.Num() - 1; i > 0; --i)
	{
		ShelfStaticMeshes[i]->Destroy();
	}
	ShelfStaticMeshes.Empty();
	ShelfSizesStack.Empty();
	// while (ShelfWidth >= DeveloperSettings->BookShelfVariations[1].BookWidth)
	// {
	// 	int32 ChosenSize;
	// 	if (ShelfWidth <= DeveloperSettings->BookShelfVariations[2].BookWidth && ShelfWidth > DeveloperSettings->BookShelfVariations[1].BookWidth)
	// 	{
	// 		ChosenSize = FMath::RandBool() + 1;
	// 		ShelfWidth -= (DeveloperSettings->BookShelfVariations[ChosenSize].BookWidth * FinalScale) - BookOffset;
	// 		ShelfSizesStack.Add(ChosenSize);
	// 		continue;
	// 	}
	// 	if (ShelfWidth <= DeveloperSettings->BookShelfVariations[1].BookWidth)
	// 	{
	// 		ChosenSize = 1;
	// 		ShelfWidth -= (DeveloperSettings->BookShelfVariations[1].BookWidth * FinalScale) - BookOffset;
	// 		ShelfSizesStack.Add(ChosenSize);
	// 		continue;
	// 	}
	// 		
	// 	ChosenSize = FMath::RandRange(1, 3);
	// 	ShelfWidth -= (DeveloperSettings->BookShelfVariations[ChosenSize].BookWidth * FinalScale) - BookOffset;
	// 	ShelfSizesStack.Add(ChosenSize);
	// }
		
	const float xStart = GetScaledBoxExtent().X;
	float xPos = xStart;
	const int32 NumBooks = ShelfWidth / ((DeveloperSettings->BookShelfVariations[1].BookWidth * FinalScale) + BookOffset);
	for (int32 i = 0; i < NumBooks; i++)
	{
		if (i == 0)
		{
			xPos -= (DeveloperSettings->BookShelfVariations[1].BookWidth * FinalScale) / 2;
		}
		else
		{
			xPos -= (DeveloperSettings->BookShelfVariations[1].BookWidth * FinalScale) + BookOffset;
		}
		UE_LOG(LogTemp, Warning, TEXT("Generate xPos: %f"), xPos);
		
		AStaticMeshActor* MeshActor = Cast<AStaticMeshActor>(GetWorld()->SpawnActor(DeveloperSettings->DefaultBookStaticMeshClass));
		MeshActor->SetMobility(EComponentMobility::Type::Movable);
		MeshActor->AttachToActor(GetOwner(), FAttachmentTransformRules::KeepRelativeTransform);
		
		const float FinalZScale = FMath::RandRange(FinalScale * 0.8f, FinalScale * 1.2f);
		FVector BookPosition = GetComponentLocation();
		MeshActor->SetActorScale3D(FVector(FinalScale, FinalScale, FinalScale));

		//const FBoxSphereBounds NewBounds = MeshComp->Bounds;
		//const float HalfHeight = NewBounds.BoxExtent.Z;
		//BookPosition.Z += HalfHeight;
		BookPosition.Y += xPos;
		BookPosition.Z -= 5;
		MeshActor->SetActorLocation(BookPosition);
		MeshActor->SetActorRelativeRotation(FRotator(0, 90, 0));
		UE_LOG(LogTemp, Warning, TEXT("Spawn mesh xPos: %f"), xPos);
	}
}

void UShelfComponent::SpawnStaticMesh(const FSoftObjectPath& Path, UObject* Object, float BookXOffset)
{
	if (UStaticMesh* Mesh = Cast<UStaticMesh>(Object))
	{
		AStaticMeshActor* MeshActor = Cast<AStaticMeshActor>(GetWorld()->SpawnActor(AStaticMeshActor::StaticClass()));
		MeshActor->SetMobility(EComponentMobility::Type::Movable);
		MeshActor->AttachToActor(GetOwner(), FAttachmentTransformRules::KeepRelativeTransform);
		MeshActor->GetStaticMeshComponent()->SetStaticMesh(Mesh);
		MeshActor->GetStaticMeshComponent()->SetMaterial(0, TransparentBookMaterial);
					
		const UFayeDeveloperSettings* DeveloperSettings = GetDefault<UFayeDeveloperSettings>();
		check(DeveloperSettings);
		
		const float FinalZScale = FMath::RandRange(FinalScale * 0.8f, FinalScale * 1.2f);
		FVector BookPosition = GetComponentLocation();
		MeshActor->SetActorScale3D(FVector(FinalScale, FinalScale, FinalScale));

		//const FBoxSphereBounds NewBounds = MeshComp->Bounds;
		//const float HalfHeight = NewBounds.BoxExtent.Z;
		//BookPosition.Z += HalfHeight;
		BookPosition.Y += BookXOffset;
		BookPosition.Z -= 5;
		MeshActor->SetActorLocation(BookPosition);
		UE_LOG(LogTemp, Warning, TEXT("Spawn mesh xPos: %f"), BookXOffset);
	}
}

void UShelfComponent::BeginPlay()
{
	Super::BeginPlay();
	LoadMaterials();
}

void UShelfComponent::LoadMaterials()
{
	const UFayeDeveloperSettings* DeveloperSettings = GetDefault<UFayeDeveloperSettings>();
	check(DeveloperSettings);
	
	DeveloperSettings->TransparentBookMaterial.LoadAsync(FLoadSoftObjectPathAsyncDelegate::CreateLambda([&](const FSoftObjectPath& Path, UObject* Object)
	{
		TransparentBookMaterial = Cast<UMaterialInterface>(Object);
	}));
	DeveloperSettings->TransparentBookMaterial_Highlighted.LoadAsync(FLoadSoftObjectPathAsyncDelegate::CreateLambda([&](const FSoftObjectPath& Path, UObject* Object)
	{
		TransparentBookMaterial_Highlighted = Cast<UMaterialInterface>(Object);
	}));
}
