// Copyright (c) 2024 Codemongous LLC. All Rights Reserved.

#include "SCW_UWorld.h"
#include "Engine/World.h"
#include "EngineUtils.h"
#include "SourcifyCoreUEWrapperModule.h"
#include "SCW_UClass.h"

using namespace Sourcify;

SCW_UWorld::SCW_UWorld(UWorld* InWorld) : SCW_UObject(InWorld), World(InWorld)
{

}

UWorld* SCW_UWorld::ToUWorld() const
{
	return World;
}

ISCW_UWorldPtr SCW_UWorld::ToUWorldPtr()
{
	return GetSharedThisAs<SCW_UWorld>();
}

ISCW_UWorldConstPtr SCW_UWorld::ToUWorldPtr() const
{
	return GetSharedThisAs<SCW_UWorld>();
}

void SCW_UWorld::DestroyWorld(bool bInformEngineOfWorld, shared_ptr<ISCW_UWorld> NewWorld/* = nullptr*/) const
{
	World->DestroyWorld(bInformEngineOfWorld, NewWorld ? dynamic_cast<SCW_UWorld*>(NewWorld.get())->ToUWorld() : nullptr);
}
		
ISCW_AActorPtr SCW_UWorld::SpawnActor_AActor(ISCW_UClassPtr ActorClass)
{
	AActor* Actor = World->SpawnActor<AActor>(dynamic_cast<SCW_UClass*>(ActorClass.get())->ToUClass());
	if (Actor)
	{
		return FSourcifyCoreUEWrapper::Get().Wrap(*Actor);
	}
	return nullptr;
}

vector<ISCW_AActorPtr> SCW_UWorld::GetActors(ISCW_UClassPtr ActorClass/* = nullptr*/) const
{
	UClass* UEClass = ActorClass ? dynamic_pointer_cast<SCW_UClass>(ActorClass)->ToUClass() : AActor::StaticClass();
	vector<ISCW_AActorPtr> Actors;
	for (AActor* UEActor : TActorRange<AActor>(World, UEClass))
	{
		if (IsValid(UEActor))
		{
			Actors.push_back(FSourcifyCoreUEWrapper::Get().Wrap(*UEActor));
		}
	}
	return Actors;
}

ISCW_ULevelPtr SCW_UWorld::GetPersistentLevel() const
{
	return World->PersistentLevel ? FSourcifyCoreUEWrapper::Get().Wrap(*World->PersistentLevel) : nullptr;
}
