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

#include "SCW_UEdGraph.h"
#include "EdGraph/EdGraph.h"
#include "K2Node_AddComponent.h"
#include "K2Node_AddDelegate.h"
#include "K2Node_AssignDelegate.h"
#include "K2Node_ComponentBoundEvent.h"
#include "K2Node_CustomEvent.h"
#include "K2Node_FunctionEntry.h"
#include "K2Node_Variable.h"
#include "SCW_UEdGraphNode.h"
#include "SourcifyCoreUEWrapperModule.h"

using namespace Sourcify;

SCW_UEdGraph::SCW_UEdGraph(UEdGraph* InEdGraph) : SCW_UObject(InEdGraph), EdGraph(InEdGraph)
{

}

UEdGraph* SCW_UEdGraph::ToUEdGraph() const
{
	return EdGraph;
}

ISCW_UEdGraphPtr SCW_UEdGraph::ToUEdGraphPtr()
{
	return GetSharedThisAs<SCW_UEdGraph>();
}

ISCW_UEdGraphConstPtr SCW_UEdGraph::ToUEdGraphPtr() const
{
	return GetSharedThisAs<SCW_UEdGraph>();
}

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

vector<ISCW_UEdGraphNodePtr> SCW_UEdGraph::GetNodes() const
{
	vector<ISCW_UEdGraphNodePtr> WrappedNodes;
	for (UEdGraphNode* Node : EdGraph->Nodes)
	{
		WrappedNodes.push_back(FSourcifyCoreUEWrapper::Get().Wrap(*Node));
	}
	return WrappedNodes;
}

void SCW_UEdGraph::GetNodesOfClass_UK2Node_AddComponent(vector<ISCW_UK2Node_AddComponentPtr>& OutNodes) const
{
	TArray<UK2Node_AddComponent*> Nodes;
	EdGraph->GetNodesOfClassEx<UK2Node_AddComponent>(Nodes);
	for (UK2Node_AddComponent* Node : Nodes)
	{
		OutNodes.push_back(FSourcifyCoreUEWrapper::Get().Wrap(*Node));
	}
}

void SCW_UEdGraph::GetNodesOfClass_UK2Node_AddDelegate(vector<ISCW_UK2Node_AddDelegatePtr>& OutNodes) const
{
	TArray<UK2Node_AddDelegate*> Nodes;
	EdGraph->GetNodesOfClassEx<UK2Node_AddDelegate>(Nodes);
	for (UK2Node_AddDelegate* Node : Nodes)
	{
		OutNodes.push_back(FSourcifyCoreUEWrapper::Get().Wrap(*Node));
	}
}

void SCW_UEdGraph::GetNodesOfClass_UK2Node_AssignDelegate(vector<ISCW_UK2Node_AssignDelegatePtr>& OutNodes) const
{
	TArray<UK2Node_AssignDelegate*> Nodes;
	EdGraph->GetNodesOfClassEx<UK2Node_AssignDelegate>(Nodes);
	for (UK2Node_AssignDelegate* Node : Nodes)
	{
		OutNodes.push_back(FSourcifyCoreUEWrapper::Get().Wrap(*Node));
	}
}
		
void SCW_UEdGraph::GetNodesOfClass_UK2Node_CallFunction(vector<ISCW_UK2Node_CallFunctionPtr>& OutNodes) const
{
	TArray<UK2Node_CallFunction*> Nodes;
	EdGraph->GetNodesOfClassEx<UK2Node_CallFunction>(Nodes);
	for (UK2Node_CallFunction* Node : Nodes)
	{
		OutNodes.push_back(FSourcifyCoreUEWrapper::Get().Wrap(*Node));
	}
}
		
void SCW_UEdGraph::GetNodesOfClass_UK2Node_ComponentBoundEvent(vector<ISCW_UK2Node_ComponentBoundEventPtr>& OutNodes) const
{
	TArray<UK2Node_ComponentBoundEvent*> Nodes;
	EdGraph->GetNodesOfClassEx<UK2Node_ComponentBoundEvent>(Nodes);
	for (UK2Node_ComponentBoundEvent* Node : Nodes)
	{
		OutNodes.push_back(FSourcifyCoreUEWrapper::Get().Wrap(*Node));
	}
}

void SCW_UEdGraph::GetNodesOfClass_UK2Node_CustomEvent(vector<ISCW_UK2Node_CustomEventPtr>& OutNodes) const
{
	TArray<UK2Node_CustomEvent*> Nodes;
	EdGraph->GetNodesOfClassEx<UK2Node_CustomEvent>(Nodes);
	for (UK2Node_CustomEvent* Node : Nodes)
	{
		OutNodes.push_back(FSourcifyCoreUEWrapper::Get().Wrap(*Node));
	}
}

void SCW_UEdGraph::GetNodesOfClass_UK2Node_Event(vector<ISCW_UK2Node_EventPtr>& OutNodes) const
{
	TArray<UK2Node_Event*> Nodes;
	EdGraph->GetNodesOfClassEx<UK2Node_Event>(Nodes);
	for (UK2Node_Event* Node : Nodes)
	{
		OutNodes.push_back(FSourcifyCoreUEWrapper::Get().Wrap(*Node));
	}
}

void SCW_UEdGraph::GetNodesOfClass_UK2Node_FunctionEntry(vector<ISCW_UK2Node_FunctionEntryPtr>& OutNodes) const
{
	TArray<UK2Node_FunctionEntry*> Nodes;
	EdGraph->GetNodesOfClassEx<UK2Node_FunctionEntry>(Nodes);
	for (UK2Node_FunctionEntry* Node : Nodes)
	{
		OutNodes.push_back(FSourcifyCoreUEWrapper::Get().Wrap(*Node));
	}
}
		
void SCW_UEdGraph::GetNodesOfClass_UK2Node_Variable(vector<ISCW_UK2Node_VariablePtr>& OutNodes) const
{
	TArray<UK2Node_Variable*> Nodes;
	EdGraph->GetNodesOfClassEx<UK2Node_Variable>(Nodes);
	for (UK2Node_Variable* Node : Nodes)
	{
		OutNodes.push_back(FSourcifyCoreUEWrapper::Get().Wrap(*Node));
	}
}

bool SCW_UEdGraph::ContainsNode(ISCW_UEdGraphNodeConstPtr Node) const
{
	return EdGraph->Nodes.Contains(dynamic_cast<const SCW_UEdGraphNode*>(Node.get())->ToUEdGraphNode());
}

void SCW_UEdGraph::InvalidateInterfaceGuid() const
{
	EdGraph->InterfaceGuid.Invalidate();
}

void SCW_UEdGraph::SetAllowDeletion(bool InAllowDeletion) const
{
	EdGraph->bAllowDeletion = InAllowDeletion;
}