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

#include "SCW_UBlueprint.h"

#include "Engine/Blueprint.h"
#include "Engine/BlueprintGeneratedClass.h"
#include "ISCW_UBlueprintGeneratedClass.h"
#include "SourcifyCoreUEWrapperModule.h"
#include "SCW_UClass.h"
#include "SCW_USimpleConstructionScript.h"

using namespace Sourcify;

SCW_UBlueprint::SCW_UBlueprint(UBlueprint* InBlueprint) : SCW_UObject(InBlueprint), Blueprint(InBlueprint)
{

}

ISCW_UBlueprintPtr SCW_UBlueprint::ToUBlueprintPtr()
{
	return GetSharedThisAs<SCW_UBlueprint>();
}

ISCW_UBlueprintConstPtr SCW_UBlueprint::ToUBlueprintPtr() const
{
	return GetSharedThisAs<SCW_UBlueprint>();
}

ISCW_UClassPtr SCW_UBlueprint::GetParentClass() const
{
	return FSourcifyCoreUEWrapper::Get().Wrap(*Blueprint->ParentClass.Get());
}

SCW_EBlueprintStatus SCW_UBlueprint::GetStatus() const
{
	return static_cast<SCW_EBlueprintStatus>(Blueprint->Status.GetIntValue());
}

void SCW_UBlueprint::DeleteComponentTemplates() const
{
	Blueprint->ComponentTemplates.Empty();
}

void SCW_UBlueprint::DeleteNewVariables() const
{
	Blueprint->NewVariables.Empty();
}

ISCW_UBlueprintGeneratedClassPtr SCW_UBlueprint::GeneratedClass() const
{
	return FSourcifyCoreUEWrapper::Get().Wrap(*Cast<UBlueprintGeneratedClass>(Blueprint->GeneratedClass.Get()));
}

UBlueprint* SCW_UBlueprint::ToUBlueprintRawPtr() const
{
	return Blueprint;
}

void SCW_UBlueprint::GetAllGraphs(vector<ISCW_UEdGraphPtr>& OutGraphs) const
{
	TArray<UEdGraph*> Graphs;
	Blueprint->GetAllGraphs(Graphs);
	for (UEdGraph* Graph : Graphs)
	{
		OutGraphs.push_back(FSourcifyCoreUEWrapper::Get().Wrap(*Graph));
	}
}

vector<ISCW_UEdGraphPtr> SCW_UBlueprint::GetEventGraphs() const
{
	vector<ISCW_UEdGraphPtr> WrappedGraphs;
	for (UEdGraph* Graph : Blueprint->EventGraphs)
	{
		WrappedGraphs.push_back(FSourcifyCoreUEWrapper::Get().Wrap(*Graph));
	}

	return WrappedGraphs;
}

vector<ISCW_UEdGraphPtr> SCW_UBlueprint::GetFunctionGraphs() const
{
	vector<ISCW_UEdGraphPtr> WrappedGraphs;
	for (UEdGraph* Graph : Blueprint->FunctionGraphs)
	{
		WrappedGraphs.push_back(FSourcifyCoreUEWrapper::Get().Wrap(*Graph));
	}

	return WrappedGraphs;
}

vector<ISCW_FBPInterfaceDescriptionPtr> SCW_UBlueprint::GetImplementedInterfaces() const
{
	vector<ISCW_FBPInterfaceDescriptionPtr> WrappedInterfaces;
	for (FBPInterfaceDescription& Graph : Blueprint->ImplementedInterfaces)
	{
		WrappedInterfaces.push_back(FSourcifyCoreUEWrapper::Get().Wrap(Graph));
	}

	return WrappedInterfaces;
}

ISCW_UInheritableComponentHandlerPtr SCW_UBlueprint::GetInheritableComponentHandler(bool bCreateIfNecessary) const
{
	return FSourcifyCoreUEWrapper::Get().Wrap(*Blueprint->GetInheritableComponentHandler(bCreateIfNecessary));
}

SCW_EBlueprintType SCW_UBlueprint::GetBlueprintType() const
{
	return static_cast<SCW_EBlueprintType>(Blueprint->BlueprintType.GetIntValue());
}

wstring SCW_UBlueprint::GetBlueprintNamespace() const
{
	return *Blueprint->BlueprintNamespace;
}

vector<ISCW_UActorComponentPtr> SCW_UBlueprint::GetComponentTemplates() const
{
	vector<ISCW_UActorComponentPtr> WrappedComponents;
	for (UActorComponent* Component : Blueprint->ComponentTemplates)
	{
		WrappedComponents.push_back(FSourcifyCoreUEWrapper::Get().Wrap(*Component));
	}

	return WrappedComponents;
}

bool SCW_UBlueprint::GetDeprecate() const
{
	return Blueprint->bDeprecate;
}

bool SCW_UBlueprint::GetGenerateConstClass() const
{
	return Blueprint->bGenerateConstClass;
}

bool SCW_UBlueprint::GetGenerateAbstractClass() const
{
	return Blueprint->bGenerateAbstractClass;
}

vector<wstring> SCW_UBlueprint::GetHideCategories() const
{
	vector<wstring> HideCategories;
	for (const FString& Category : Blueprint->HideCategories)
	{
		HideCategories.push_back(*Category);
	}
	return HideCategories;
}

vector<ISCW_FBPVariableDescriptionPtr> SCW_UBlueprint::NewVariables() const
{
	vector<ISCW_FBPVariableDescriptionPtr> WrappedVariables;
	for (FBPVariableDescription& Variable : Blueprint->NewVariables)
	{
		WrappedVariables.push_back(FSourcifyCoreUEWrapper::Get().Wrap(Variable));
	}

	return WrappedVariables;
}

vector<ISCW_UEdGraphPtr> SCW_UBlueprint::GetUbergraphPages() const
{
	vector<ISCW_UEdGraphPtr> WrappedGraphs;
	for (UEdGraph* Graph : Blueprint->UbergraphPages)
	{
		WrappedGraphs.push_back(FSourcifyCoreUEWrapper::Get().Wrap(*Graph));
	}

	return WrappedGraphs;
}

void SCW_UBlueprint::SetSimpleConstructionScript(ISCW_USimpleConstructionScriptPtr SCS) const 
{
	Blueprint->SimpleConstructionScript = dynamic_cast<SCW_USimpleConstructionScript*>(SCS.get())->ToUSimpleConstructionScript();
}

ISCW_USimpleConstructionScriptPtr SCW_UBlueprint::SimpleConstructionScript() const
{
	return Blueprint->SimpleConstructionScript ? FSourcifyCoreUEWrapper::Get().Wrap(*Blueprint->SimpleConstructionScript) : nullptr;
}

void SCW_UBlueprint::SetParentClass(ISCW_UClassPtr Parent) const 
{
	Blueprint->ParentClass = dynamic_cast<SCW_UClass*>(Parent.get())->ToUClass();
}