// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.

#include "ComboActionGraph.h"

#include "Nodes/ComboActionGraphEdge.h"
#include "Nodes/ComboActionGraphNode.h"
#include "Nodes/ComboActionGraphNode_StartNode.h"

#define LOCTEXT_NAMESPACE "ComboActionGraph"

DEFINE_LOG_CATEGORY(LogComboActionGraph);


UComboActionGraph::UComboActionGraph()
{
	this->NodeType = UComboActionGraphNode::StaticClass();
	this->EdgeType = UComboActionGraphEdge::StaticClass();

	this->bEdgeEnabled = false;
	this->GraphGUID = FGuid::NewGuid();

#if WITH_EDITORONLY_DATA
	this->EdGraph = nullptr;

	this->bCanRenameNode = true;
#endif
}

bool UComboActionGraph::CanStartDialogueGraph() const
{
	if (this->AllNodes.Num() == 0)
	{
		return false;
	}
	
	for (const UComboActionGraphNode *Itr : this->AllNodes)
	{
		if (!Itr || !Itr->ValidateNodeRuntime())
		{
			return false;
		}
	}
	
	return true;
}

void UComboActionGraph::CreateGraph()
{
#if WITH_EDITOR
	// We already have an existing graph or start node
	if (this->EdGraph != nullptr || this->StartNode != nullptr)
	{
		return;
	}

	this->StartNode = this->ConstructActionNode<UComboActionGraphNode_StartNode>();
	if (this->StartNode != nullptr )
	{
		this->StartNode->Graph = this;

		this->RootNodes.Add(this->StartNode);
		this->AllNodes.Add(this->StartNode);
	}
#endif
}

void UComboActionGraph::ClearGraph()
{
	for (UComboActionGraphNode *Node : this->AllNodes)
	{
		Node->ParentNodes.Empty();
		Node->ChildrenNodes.Empty();
		Node->Edges.Empty();
	}

	this->AllNodes.Empty();
	this->RootNodes.Empty();
}

void UComboActionGraph::PostInitProperties()
{
	UObject::PostInitProperties();

	// Ignore these cases
	if (this->HasAnyFlags(EObjectFlags::RF_ClassDefaultObject | EObjectFlags::RF_NeedLoad))
	{
		return;
	}

#if WITH_EDITOR
	this->CreateGraph();
#endif
}

#if WITH_EDITOR
bool UComboActionGraph::ValidateGraph(TArray<FText> &ValidationErrors, bool RichTextFormat)
{
	bool bReturnValue = true;

	if (this->StartNode == nullptr)
	{
		const FString RichTextReturn =
			FString("* ")
			.Append(TEXT("<RichTextBlock.Bold>Dialogue Graph</>"))
			.Append(": Has no Start Node!");

		const FString TextReturn =
			this->GetName()
			.Append(": Has no Start Node!");
		
		ValidationErrors.Add(FText::FromString(RichTextFormat ? RichTextReturn : TextReturn));

		bReturnValue = false;
	}

	for (UComboActionGraphNode *Itr : this->AllNodes)
	{
		if (Itr != nullptr && !Itr->ValidateNode(ValidationErrors, RichTextFormat))
		{
			bReturnValue = false;
		}
	}
	
	return bReturnValue;
}

EDataValidationResult UComboActionGraph::IsDataValid(TArray<FText>& ValidationErrors)
{
	return this->ValidateGraph(ValidationErrors, false)
		? EDataValidationResult::Valid
		: EDataValidationResult::Invalid; 
}
#endif

#undef LOCTEXT_NAMESPACE
