// Copyright CodeSpartan, 2022. All rights reserved.

#pragma once

#include "CoreMinimal.h"
#include "Engine/StreamableManager.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "Templates/SubclassOf.h"
#include "AsyncLoadAppearanceAssets.generated.h"

UDELEGATE(BlueprintAuthorityOnly)
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FAsyncLoadOutputPin, USkeletalMesh*, LoadedSkelMesh, TSubclassOf<UAnimInstance>, LoadedAnimBpClass, const TArray<UObject*>&, LoadedGearAssets);

UCLASS()
class MMOKITCODE_API UAsyncLoadAppearanceAssets : public UBlueprintAsyncActionBase
{
	GENERATED_UCLASS_BODY()
	
public:
	UPROPERTY(BlueprintAssignable)
	FAsyncLoadOutputPin LoadComplete;

	/* 
	* A Blueprint node that loads a couple of assets asynchronously.
	* The only reason it's in C++ is because doing it in blueprints would look like a big mess.
	*/
	UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true", WorldContext = "WorldContextObject"), Category = "Utilities")
	static UAsyncLoadAppearanceAssets* AsyncLoadAppearanceAssets(UObject* WorldContextObject, const TSoftObjectPtr<USkeletalMesh> SkelMesh, const TSoftClassPtr<UAnimInstance> AnimBpClass, const TArray<FPrimaryAssetId> GearAssets);

	// UBlueprintAsyncActionBase interface
	virtual void Activate() override;
	//~UBlueprintAsyncActionBase interface

private:
	UFUNCTION()
	void ExecuteLoadComplete();

	UFUNCTION()
	void OnSoftPointersLoaded();

	UFUNCTION()
	void OnPrimaryAssetsLoaded();

	UPROPERTY()
	TSoftObjectPtr<USkeletalMesh> SkelMeshInput;
	UPROPERTY()
	TSoftClassPtr<UAnimInstance> AnimBpClassInput;
	UPROPERTY()
	TArray<FPrimaryAssetId> GearAssetsInput;
	
	TSharedPtr<FStreamableHandle> gearAssetsHandle;

	UPROPERTY()
	USkeletalMesh* SkelMeshOutput;
	UPROPERTY()
	TSubclassOf<UAnimInstance> AnimBpClassOutput;
	UPROPERTY()
	TArray<UObject*> GearAssetsOutput;

	int32 assetsLoaded = 0;
};
