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

#pragma once

#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "Common.h"
#include "Tangible.h"
#include "TangibleManager.generated.h"

UCLASS()
class INTEGRATION_API UlxTangibleManager : public UGameInstanceSubsystem
{
	GENERATED_BODY()

public:
	// Types used frequently.
	using IdView = LpxCommonTypes::IdView;
	using IdArray = LpxCommonTypes::IdArray;
	using TanArray = TArray<UlxTangible*>;

	virtual void Initialize(FSubsystemCollectionBase& Collection) override;

	// Given a tangible ID, look up the TangibleComponent of that actor.
	UPROPERTY()
	TMap<int64, UlxTangible*> IdToTangible;

	// The Tangible ID of the possessed tangible, if any.
	UlxTangible *PossessedTangible;
	
	// Get the tangible if it exists, otherwise return NULL
	//
	UlxTangible* GetTangible(int64 id) const;

	// Get the tangible if it exists, otherwise create it.
	//
	UlxTangible* MakeTangible(int64 id);

	// Delete the tangible.
	//
	void DeleteTangible(int64 id);

	// Get an array of all tangibles.
	//
    TanArray GetAllTangibles() const;
	
	// Get the currently-possessed tangible.
	//
	// This can be nullptr if no tangible is possessed.
	//
	UlxTangible *GetPossessedTangible() { return PossessedTangible; }

	// Set the currently-possessed tangible.
	//
	void SetPossessedTangible(UlxTangible *tan) { PossessedTangible = tan; }

	// Update the 'NearAccordingToLuprex' flags.
	//
	// Also creates stub tangibles for every Id in the list.
	//
	void UpdateNearAccordingToLuprex(IdView near);

	// Recalculate the 'NearAccordingToUnreal' flags.
	//
	void RecalcNearAccordingToUnreal(int64 player, double radius);
	
	// Delete Far Tangibles.
	//
	// Any tangible whose 'NearAccordingToLuprex' and 'NearAccordingToUnreal'
	// flags are both false is deleted.  You probably want to update both
	// flags by calling the two routines above before calling this.
	//
	void DeleteFarawayTangibles();

	// Given an array of tangibles, return an array of tangible Ids.
	//
	static IdArray GetIds(const TanArray &tans);
};

