#pragma once

#include "CoreMinimal.h"
#include "UObject/StrongObjectPtr.h"

class UBlueprint;
class USCS_Node;
class UActorComponent;
class USimpleConstructionScript;
class UClass;
class UWingComponentRef;
class WingOut;


struct UWingComponent
{
public:
	static UActorComponent* GetImmutableTemplate(const UWingComponentRef *Ref);
	static UActorComponent* GetMutableTemplate(const UWingComponentRef *Ref);

	static bool ReparentComponent(UWingComponentRef *Ref, UWingComponentRef *Parent, WingOut Errors);
	static bool DeleteComponent(UWingComponentRef *Ref, WingOut Errors);
	static bool AddComponent(UBlueprint *BP, UClass *Class,
		UWingComponentRef *Parent, FName Name, WingOut Errors);

	static TArray<TStrongObjectPtr<UWingComponentRef>> GetAll(UBlueprint* BP);
	static void PrintAll(UBlueprint* BP, WingOut Out);

	static bool CheckValidComponentClass(UClass *Class, WingOut Errors);
private:
	struct FoundComponent
	{
		FName Name;
		USCS_Node *SCS;
		UActorComponent *Native;
	};

	static UActorComponent *FindComponentInCDO(UClass *Class, FName Name);
	static USCS_Node* FindSCSNodeByName(UBlueprint *BP, FName VariableName);
	static FoundComponent FindComponent(UBlueprint *BP, FName Name);
	static bool CheckValidParent(FoundComponent FC, WingOut Errors);
	static bool CheckExists(FoundComponent FC, WingOut Errors);
	static bool CheckNoSuchComponent(FoundComponent FC, WingOut Errors);
	static bool CheckNotNative(FoundComponent FC, const TCHAR *Action, WingOut Errors);
	static bool CheckOwnedByBlueprint(FoundComponent FC, UBlueprint *BP, WingOut Errors);
	static void AddChildNode(UBlueprint *BP, USCS_Node *Node, FoundComponent Parent);
	static TMap<FName, FName> CalculateParentNames(USimpleConstructionScript *Script);
	static void PrintComponentInfo(const FString& TypeName, const FString& VarName,
		const FString& ParentName, bool Inherited, WingOut Out);
};
