#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "EGameplayElementType.h"
#include "ETileSpawnPointType.h"
#include "Templates/SubclassOf.h"
#include "UObject/SoftObjectPtr.h"
#include "GeneratedLevelData.h"
#include "UObject/NoExportTypes.h"
#include "SpawnInfo.h"
#include "GenerationParams.h"
#include "ProceduralLevelBuilder.generated.h"

class UPaperTileMap;
class ATile;
class UProceduralGenerationData;
class UDataTable;
class UDataAsset;
class UMapData;
class UAkAudioBank;
class UObjectLibrary;
class UTileMatrix;
class UTileBank;
class UActorSpawner;
class AProceduralLevelData;
class ADBDClientSyncer;
class UBlackboardComponent;
class UEdgeObjectHandlingStrategy;

UCLASS(Blueprintable)
class DEADBYDAYLIGHT_API AProceduralLevelBuilder : public AActor
{
	GENERATED_BODY()

public:
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString PathToMapDirectory;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString PathToTilesDirectory;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString PathToEventSpawnablesDirectory;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TArray<FString> EventSpawnablesParentDirectories;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float EventSpawnablePositionWeightCoefficient;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float EventSpawnablePositionWeightPowerBase;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TMap<EGameplayElementType, float> StaticActorSpawnerDecorationBudgets;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TMap<ETileSpawnPointType, float> StaticSpawnPointDecorationBudgets;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float KillerMinProximityFromCamper;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float SurvivorMinProximityFromOtherCamper;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float MinProximityBetweenGenerators;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	int32 ExtraGeneratorCount;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float MinProximityBetweenChests;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float MinProximityBetweenTotems;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float MinProximityBetweenHatches;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float SurvivorMinProximityFromGenerator;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float SurvivorMinProximityFromTotem;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float SurvivorMaxLineOfSightFromTotem;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float MinProximityBetweenSpecialBehaviourItems;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float SpecialBehaviourItemMinProximityFromSurvivor;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float SpecialBehaviourItemMinProximityFromKiller;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TSubclassOf<UPaperTileMap> DebugMap;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TArray<TSubclassOf<ATile>> DebugTiles;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float SmallMeatLockerMinProximityFromKillerLair;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float FactorToAdjustToWhenOutOfProximity;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float FactorToAdjustToWhenInLineOfSight;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float HeightAmplifier;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float HeightAmplifierActivationHeight;

	UPROPERTY(BlueprintReadWrite, Transient)
	UProceduralGenerationData* ProceduralGenerationData;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TSoftObjectPtr<UDataTable> AmbiancePriorities;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TSoftObjectPtr<UDataAsset> PerMapLightData;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float TileWeightRateOfDecay;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float QuadTileWeightRateOfDecay;

private:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	UClass* _tileClass;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	UMapData* _mapData;

	UPROPERTY(BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	TArray<ATile*> _outOfWorldTiles;

	UPROPERTY(BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	UAkAudioBank* _ambientAudioBank;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	UObjectLibrary* _availableTilesLibrary;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	UObjectLibrary* _availableEventSpawnablesLibrary;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	UObjectLibrary* _availableDerivedTileLibrary;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	FGeneratedLevelData _generatedData;

	UPROPERTY(BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	UTileMatrix* _tileMatrix;

	UPROPERTY(BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	UTileBank* _tileBank;

	UPROPERTY(BlueprintReadWrite, Transient, Instanced, meta=(AllowPrivateAccess=true))
	UActorSpawner* _killerLairSpawner;

	UPROPERTY(Transient)
	TArray<FSoftObjectPath> _preloadAssetReferences;

	UPROPERTY(BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	TArray<TSubclassOf<AActor>> _chestItemAssetReferences;

	UPROPERTY(BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	TArray<UClass*> _killerPawns;

	UPROPERTY(BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	TArray<ATile*> _tilesThatHaveBeenSpawned;

	UPROPERTY(BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	TArray<AActor*> _eventSpawnablesThatHaveBeenStreamed;

	UPROPERTY(BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	AProceduralLevelData* _debugProceduralDatas;

	UPROPERTY(BlueprintReadWrite, Replicated, Transient, meta=(AllowPrivateAccess=true))
	ADBDClientSyncer* _syncer;

	UPROPERTY(BlueprintReadWrite, Transient, Instanced, meta=(AllowPrivateAccess=true))
	UBlackboardComponent* _blackboardComp;

	UPROPERTY(BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	UEdgeObjectHandlingStrategy* _edgeObjectHandlingStrategy;

	UPROPERTY(BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	ATile* _backupKillerLairTile;

	UPROPERTY(BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	TMap<AActor*, FSpawnInfo> _spawnedActorAttachmentInfo;

private:
	UFUNCTION(BlueprintCallable)
	void SyncSeeds();

	UFUNCTION(BlueprintCallable)
	void StartGenerationOnSyncerReady();

public:
	UFUNCTION(BlueprintCallable)
	AActor* SpawnActor(UClass* actorClass, ETileSpawnPointType spawnPointType);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void RemoveMist();

private:
	UFUNCTION(BlueprintCallable, NetMulticast, Reliable)
	void Multicast_DebugShareGenerationData(FGenerationParams usedParams);

	UFUNCTION(BlueprintCallable)
	void BuildFromSeed();

public:
	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void ApplyMist(float modifier);

public:
	virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;

public:
	AProceduralLevelBuilder();
};

FORCEINLINE uint32 GetTypeHash(const AProceduralLevelBuilder) { return 0; }
