#pragma once

#include "CoreMinimal.h"
#include "EdGraph/EdGraphPin.h"

class UEdGraph;
class UEdGraphNode;
struct FWingProperty;

class WingGraphExport
{
public:
	WingGraphExport(UEdGraph* InGraph, bool Locals, bool Details);
	WingGraphExport(UEdGraphNode* InNode, bool Locals, bool Details);

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

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

	enum PinKind
	{
		PK_EXEC,
		PK_VALUE,
		PK_BOTH
	};

	// Return true if this pin is connected.
	//
	static bool IsLinked(UEdGraphPin *Pin);

	// Get the pin that this pin is linked to.
	//
	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, Kind, or both.
	//
	static TArray<UEdGraphPin*> GetPins(
		UEdGraphNode* Node, EEdGraphPinDirection Direction, PinKind Kind);
	
	// Return true if the node has an exec pin that points
	// in the specified direction.
	//
	static bool HasExecPin(UEdGraphNode* Node, EEdGraphPinDirection Direction);

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

	void EmitLinks(UEdGraphPin* Pin);
	void EmitInputPinValue(UEdGraphPin* Pin);
	void Traverse(UEdGraphNode* Node);
	void SortNodes();
	void EmitNode(UEdGraphNode* Node);
	void EmitLocalVariables();
	void EmitGraph();
	void EmitComments();
	void EmitDetailsSuggestion();
	void GetProperties(UEdGraphNode *Node,
		TArray<FWingProperty> &Primary, TArray<FWingProperty> &Secondary);

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

	UEdGraph* Graph = nullptr;
	bool ShowLocals = false;
	bool ShowDetails = false;
	bool SuppressedDetails = false;

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

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