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

#pragma once

#include "CoreMinimal.h"
#include "EdGraph/EdGraphNode.h"
#include "EdGraph_Sourcify.h"
#include "Textures/SlateIcon.h"
#include "UObject/ObjectMacros.h"
#include "EdGraphNode_Sourcify.generated.h"

class UEdGraphPin;
class SSourcifyNode;

UCLASS()
class UEdGraphNode_Sourcify : public UEdGraphNode
{
	GENERATED_BODY()

public:
	UEdGraphNode_Sourcify();

	/** Returns first asset identifier */
	FAssetIdentifier GetIdentifier() const;
	
	/** Returns all identifiers on this node including virtual things */
	void GetAllIdentifiers(TArray<FAssetIdentifier>& OutIdentifiers) const;

	/** Returns only the packages in this node, skips searchable names */
	void GetAllPackageNames(TArray<FName>& OutPackageNames) const;

	/** Returns our owning graph */
	UEdGraph_Sourcify* GetSourcifyGraph() const;

	// UEdGraphNode implementation
	virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
	FLinearColor GetNodeTitleColor() const override;
	virtual FText GetTooltipText() const override;
	virtual void AllocateDefaultPins() override;
	virtual UObject* GetJumpTargetForDoubleClick() const override;
	virtual FSlateIcon GetIconAndTint(FLinearColor& OutColor) const override;
	virtual bool ShowPaletteIconOnNode() const override { return true; }
	// End UEdGraphNode implementation

	void SetAllowThumbnail(bool bInAllow) { bAllowThumbnail = bInAllow; }
	bool AllowsThumbnail() const;
	bool UsesThumbnail() const;
	bool IsPackage() const;
	bool IsCollapsed() const;
	bool IsADuplicate() const { return bIsADuplicate; }

	// Nodes that are filtered out still may still show because they
	// are between nodes that pass the filter and the root.  This "filtered"
	// bool allows us to render these in-between nodes differently
	void SetIsFiltered(bool bInFiltered);
	bool GetIsFiltered() const;

	bool IsOverflow() const { return bIsOverflow; }

	FAssetData GetAssetData() const;

	UEdGraphPin* GetDependencyPin();
	UEdGraphPin* GetReferencerPin();

	const Sourcify::DependencyNode::ReferenceInfo& GetInfo() const;
	
	Sourcify::NodeErrorStatus ValidateConversionSettings() const;
	void UnRegisterDelegates();

	SSourcifyNode* SourcifyWidgetNode;

private:
	void CacheAssetData(const FAssetData& AssetData);
	void SetupReferenceNode(const Sourcify::DependencyNode::ReferenceInfo& InInfo, const FIntPoint& NodeLoc, const TArray<FAssetIdentifier>& NewIdentifiers, const FAssetData& InAssetData, bool bInAllowThumbnail, bool bInIsADuplicate);
	void SetReferenceNodeCollapsed(const FIntPoint& NodeLoc, int32 InNumReferencesExceedingMax, const TArray<FAssetIdentifier>& Identifiers);
	void AddReferencer(class UEdGraphNode_Sourcify* ReferencerNode);
	void OnNodeTypeChanged(Sourcify::DependencyNode* InDependencyNodePtr);

private:
	Sourcify::DependencyNode::ReferenceInfo Info;
	TArray<FAssetIdentifier> Identifiers;
	FText NodeTitle;

	bool bAllowThumbnail;
	bool bUsesThumbnail;
	bool bIsPackage;
	bool bIsPrimaryAsset;
	bool bIsCollapsed;
	bool bIsADuplicate;
	bool bIsFiltered;
	bool bIsOverflow;

	FAssetData CachedAssetData;
	FLinearColor AssetTypeColor;
	FSlateIcon AssetBrush;

	UEdGraphPin* DependencyPin;
	UEdGraphPin* ReferencerPin;

	friend UEdGraph_Sourcify;
};


