#pragma once

#include "CoreMinimal.h"
#include "WingPropHandle.h"
#include "Engine/Blueprint.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphNode.h"
#include "EdGraph/EdGraphPin.h"

class WingGraphExport
{
public:
	WingGraphExport(UEdGraph* InGraph);
	WingGraphExport(UEdGraphNode* InNode);

	const FString GetOutput() { return Output.ToString(); }
	const FString GetDetails() { return Details.ToString(); }

private:
	////////////////////////////////////////////////////////
	//
	// General utilities for manipulating UEdGraph nodes.
	//
	////////////////////////////////////////////////////////

	// Get the pin that this pin is linked to.  If the
	// pin is linked to multiple pins, returns the first.
	// If the pin is linked to a knot node, follow the
	// chain of knot nodes and find the pin at the other
	// end of the chain.  Returns nullptr if this pin
	// is not linked to anything.
	//
	static UEdGraphPin* GetLinkedTo(UEdGraphPin *Pin);

	// Return true if the pin in question defaults
	// to self.
	//
	static bool IsDefaultToSelf(UEdGraphPin* Pin);

	// Get a subset of the pins in the node, filtered
	// by direction, category, or both.
	//
	static TArray<UEdGraphPin*> FilterPins(UEdGraphNode* Node,
		EEdGraphPinDirection Direction = EGPD_MAX, FName Category = FName());

	// Return true if the node has an exec pin that points
	// in the specified direction.
	//
	static bool HasExecPin(UEdGraphNode* Node, EEdGraphPinDirection Direction);

	// Find the first pin that points in the specified direction.
	//
	static UEdGraphPin* FindFirstPin(UEdGraphNode* Node, EEdGraphPinDirection Direction);

	////////////////////////////////////////////////////////
	//
	// Traverse and Emit the Nodes.
	//
	////////////////////////////////////////////////////////

	FString FormatPinSource(UEdGraphPin* Pin);
	void Traverse(UEdGraphNode* Node);
	void SortNodes();
	void EmitNode(UEdGraphNode* Node);
	void EmitNodeProperties(UEdGraphNode* Node, FStringBuilderBase& Out, bool bPrimary);
	void EmitLocalVariables();
	void EmitGraph();
	void EmitDetails();
	void EmitComments();

	////////////////////////////////////////////////////////
	//
	// Values recorded during traversal.
	//
	////////////////////////////////////////////////////////


	UEdGraph* Graph;
	WingPropHandle Props;

	// Data populated by passes.
	TArray<UEdGraphNode*> SortedNodes;
	TSet<UEdGraphNode*> Visited;

	// Output buffers.
	TStringBuilder<4096> Output;
	TStringBuilder<4096> Details;
};
