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

#pragma once
#include "ISCW_UEdGraphSchema.h"

#include <memory>
#include <string>

using std::wstring;

namespace Sourcify
{	
	struct ISCW_FBlueprintMetadata
	{
	public:
		// Struct/Enum/Class:
		// If true, this class, struct, or enum is a valid type for use as a variable in a blueprint
		static constexpr const wchar_t* MD_AllowableBlueprintVariableType = L"BlueprintType";

		// If true, this class, struct, or enum is not valid for use as a variable in a blueprint
		static constexpr const wchar_t* MD_NotAllowableBlueprintVariableType = L"NotBlueprintType";

		// Class:
		// [ClassMetadata] If present, the component class can be spawned by a blueprint
		static constexpr const wchar_t* MD_BlueprintSpawnableComponent = L"BlueprintSpawnableComponent";

		/** If true, the class will be usable as a base for blueprints */
		static constexpr const wchar_t* MD_IsBlueprintBase = L"IsBlueprintBase";

		/** A listing of classes that this class is accessible from (and only those classes, if present).  Note that this determines the GRAPH CONTEXTS in which the node cannot be placed (e.g. right click menu, palette), and does NOT control menus when dragging off of a context pin (i.e. contextual drag) */
		static constexpr const wchar_t* MD_RestrictedToClasses = L"RestrictedToClasses";

		/// [ClassMetadata] Used for Actor and Component classes. If the native class cannot tick, Blueprint generated classes based this Actor or Component can have bCanEverTick flag overridden even if bCanBlueprintsTickByDefault is false.
		static constexpr const wchar_t* MD_ChildCanTick = L"ChildCanTick";

		/// [ClassMetadata] Used for Actor and Component classes. If the native class cannot tick, Blueprint generated classes based this Actor or Component can never tick even if bCanBlueprintsTickByDefault is true.
		static constexpr const wchar_t* MD_ChildCannotTick = L"ChildCannotTick";

		/// [ClassMetadata] Used to make the first subclass of a class ignore all inherited showCategories and hideCategories commands
		static constexpr const wchar_t* MD_IgnoreCategoryKeywordsInSubclasses = L"IgnoreCategoryKeywordsInSubclasses";

		/** Specifies which struct implements the custom thunk functions for this class */
		static constexpr const wchar_t* MD_CustomThunkTemplates = L"CustomThunkTemplates";

		//    function metadata
		/** Specifies a UFUNCTION as Kismet protected, which can only be called from itself */
		static constexpr const wchar_t* MD_Protected = L"BlueprintProtected";

		/** Marks a UFUNCTION as latent execution */
		static constexpr const wchar_t* MD_Latent = L"Latent";

		/** Indicates that the UFUNCTION implements its own thunk function */
		static constexpr const wchar_t* MD_CustomThunk = L"CustomThunk";

		/** Marks a UFUNCTION as accepting variadic arguments */
		static constexpr const wchar_t* MD_Variadic = L"Variadic";

		/** Marks a UFUNCTION as unsafe for use in the UCS, which prevents it from being called from the UCS.  Useful for things that spawn actors, etc that should never happen in the UCS */
		static constexpr const wchar_t* MD_UnsafeForConstructionScripts = L"UnsafeDuringActorConstruction";

		// The category that a function appears under in the palette
		static constexpr const wchar_t* MD_FunctionCategory = L"Category";

		// [FunctionMetadata] Indicates that the function is deprecated
		static constexpr const wchar_t* MD_DeprecatedFunction = L"DeprecatedFunction";

		// [FunctionMetadata] Indicates that the property is deprecated
		static constexpr const wchar_t* MD_DeprecatedProperty = L"DeprecatedProperty";

		// [FunctionMetadata] Supplies the custom message to use for deprecation
		static constexpr const wchar_t* MD_DeprecationMessage = L"DeprecationMessage";

		// [FunctionMetadata] Indicates that the function should be drawn as a compact node with the specified body title
		static constexpr const wchar_t* MD_CompactNodeTitle = L"CompactNodeTitle";

		// [FunctionMetadata] Indicates that the function should be drawn with this title over the function name
		static constexpr const wchar_t* MD_DisplayName = L"DisplayName";

		// [FunctionMetadata] Indicates the display name of the return value pin
		static constexpr const wchar_t* MD_ReturnDisplayName = L"ReturnDisplayName";

		// [FunctionMetadata] Indicates that a particular function parameter is for internal use only, which means it will be both hidden and not connectible.
		static constexpr const wchar_t* MD_InternalUseParam = L"InternalUseParam";

		// [FunctionMetadata] Indicates that the function should appear as blueprint function even if it doesn't return a value.
		static constexpr const wchar_t* MD_ForceAsFunction = L"ForceAsFunction";

		// [FunctionMetadata] Indicates that the function should be ignored when considered for blueprint type promotion
		static constexpr const wchar_t* MD_IgnoreTypePromotion = L"IgnoreTypePromotion";

		//    property metadata

		/** UPROPERTY will be exposed on "Spawn Blueprint" nodes as an input  */
		static constexpr const wchar_t* MD_ExposeOnSpawn = L"ExposeOnSpawn";

		/** UPROPERTY uses the specified function as a getter rather than reading from the property directly */
		static constexpr const wchar_t* MD_PropertyGetFunction = L"BlueprintGetter";

		/** UPROPERTY uses the specified function as a setter rather than writing to the property directly */
		static constexpr const wchar_t* MD_PropertySetFunction = L"BlueprintSetter";

		/** UPROPERTY cannot be modified by other blueprints */
		static constexpr const wchar_t* MD_Private = L"BlueprintPrivate";

		/** If true, the self pin should not be shown or connectable regardless of purity, const, etc. similar to InternalUseParam */
		static constexpr const wchar_t* MD_HideSelfPin = L"HideSelfPin";

		/** If true, the specified UObject parameter will default to "self" if nothing is connected */
		static constexpr const wchar_t* MD_DefaultToSelf = L"DefaultToSelf";

		/** The specified parameter should be used as the context object when retrieving a UWorld pointer (implies hidden and default-to-self) */
		static constexpr const wchar_t* MD_WorldContext = L"WorldContext";

		/** For functions that have the MD_WorldContext metadata but are safe to be called from contexts that do not have the ability to provide the world context (either through GetWorld() or ShowWorldContextPin class metadata */
		static constexpr const wchar_t* MD_CallableWithoutWorldContext = L"CallableWithoutWorldContext";

		/** For functions that should be compiled in development mode only */
		static constexpr const wchar_t* MD_DevelopmentOnly = L"DevelopmentOnly";

		/** If true, an unconnected pin will generate a UPROPERTY under the hood to connect as the input, which will be set to the literal value for the pin.  Only valid for reference parameters. */
		static constexpr const wchar_t* MD_AutoCreateRefTerm = L"AutoCreateRefTerm";

		/** The specified parameter should hide the asset picker on the pin, even if it is a valid UObject Asset. */
		static constexpr const wchar_t* MD_HideAssetPicker = L"HideAssetPicker";

		/** If true, the hidden world context pin will be visible when the function is placed in a child blueprint of the class. */
		static constexpr const wchar_t* MD_ShowWorldContextPin = L"ShowWorldContextPin";

		/** Comma delimited list of pins that should be hidden on this function. */
		static constexpr const wchar_t* MD_HidePin = L"HidePin";

		static constexpr const wchar_t* MD_BlueprintInternalUseOnly = L"BlueprintInternalUseOnly";
		static constexpr const wchar_t* MD_BlueprintInternalUseOnlyHierarchical = L"BlueprintInternalUseOnlyHierarchical";
		static constexpr const wchar_t* MD_NeedsLatentFixup = L"NeedsLatentFixup";

		static constexpr const wchar_t* MD_LatentInfo = L"LatentInfo";
		static constexpr const wchar_t* MD_LatentCallbackTarget = L"LatentCallbackTarget";

		/** If true, properties defined in the C++ private scope will be accessible to blueprints */
		static constexpr const wchar_t* MD_AllowPrivateAccess = L"AllowPrivateAccess";

		/** Categories of functions to expose on this property */
		static constexpr const wchar_t* MD_ExposeFunctionCategories = L"ExposeFunctionCategories";

		// [InterfaceMetadata]
		static constexpr const wchar_t* MD_CannotImplementInterfaceInBlueprint = L"CannotImplementInterfaceInBlueprint";
		static constexpr const wchar_t* MD_ProhibitedInterfaces = L"ProhibitedInterfaces";

		/** Keywords used when searching for functions */
		static constexpr const wchar_t* MD_FunctionKeywords = L"Keywords";

		/** Indicates that during compile we want to create multiple exec pins from an enum param */
		static constexpr const wchar_t* MD_ExpandEnumAsExecs = L"ExpandEnumAsExecs";

		/** Synonym for MD_ExpandEnumAsExecs */
		static constexpr const wchar_t* MD_ExpandBoolAsExecs = L"ExpandBoolAsExecs";

		static constexpr const wchar_t* MD_CommutativeAssociativeBinaryOperator = L"CommutativeAssociativeBinaryOperator";

		/** Metadata string that indicates to use the MaterialParameterCollectionFunction node. */
		static constexpr const wchar_t* MD_MaterialParameterCollectionFunction = L"MaterialParameterCollectionFunction";

		/** Metadata string that sets the tooltip */
		static constexpr const wchar_t* MD_Tooltip = L"Tooltip";

		/** Metadata string that indicates the specified event can be triggered in editor */
		static constexpr const wchar_t* MD_CallInEditor = L"CallInEditor";

		/** Metadata to identify an DataTable Pin. Depending on which DataTable is selected, we display different RowName options */
		static constexpr const wchar_t* MD_DataTablePin = L"DataTablePin";

		/** Metadata that flags make/break functions for specific struct types. */
		static constexpr const wchar_t* MD_NativeMakeFunction = L"HasNativeMake";
		static constexpr const wchar_t* MD_NativeBreakFunction = L"HasNativeBreak";
		static constexpr const wchar_t* MD_NativeDisableSplitPin = L"DisableSplitPin";

		/** Metadata that flags function params that govern what type of object the function returns */
		static constexpr const wchar_t* MD_DynamicOutputType = L"DeterminesOutputType";
		/** Metadata that flags the function output param that will be controlled by the "MD_DynamicOutputType" pin */
		static constexpr const wchar_t* MD_DynamicOutputParam = L"DynamicOutputParam";

		static constexpr const wchar_t* MD_CustomStructureParam = L"CustomStructureParam";

		static constexpr const wchar_t* MD_ArrayParam = L"ArrayParm";
		static constexpr const wchar_t* MD_ArrayDependentParam = L"ArrayTypeDependentParams";

		/** Metadata that flags TSet parameters that will have their type determined at blueprint compile time */
		static constexpr const wchar_t* MD_SetParam = L"SetParam";

		/** Metadata that flags TMap function parameters that will have their type determined at blueprint compile time */
		static constexpr const wchar_t* MD_MapParam = L"MapParam";
		static constexpr const wchar_t* MD_MapKeyParam = L"MapKeyParam";
		static constexpr const wchar_t* MD_MapValueParam = L"MapValueParam";

		/** Metadata that identifies an integral property as a bitmask. */
		static constexpr const wchar_t* MD_Bitmask = L"Bitmask";
		/** Metadata that associates a bitmask property with a bitflag enum. */
		static constexpr const wchar_t* MD_BitmaskEnum = L"BitmaskEnum";
		/** Metadata that identifies an enum as a set of explicitly-named bitflags. */
		static constexpr const wchar_t* MD_Bitflags = L"Bitflags";
		/** Metadata that signals to the editor that enum values correspond to mask values instead of bitshift (index) values. */
		static constexpr const wchar_t* MD_UseEnumValuesAsMaskValuesInEditor = L"UseEnumValuesAsMaskValuesInEditor";

		/** Stub function used internally by animation blueprints */
		static constexpr const wchar_t* MD_AnimBlueprintFunction = L"AnimBlueprintFunction";

		/** Metadata that should be used with UPARAM to specify whether a TSubclassOf argument should use the DisplayName of classes */
		static constexpr const wchar_t* MD_ShowDisplayNames = L"ShowDisplayNames";

		/** Metadata that should be used with UPARAM to specify whether a TSubclassOf argument allows abstract classes */
		static constexpr const wchar_t* MD_AllowAbstractClasses = L"AllowAbstract";
		/** Metadata that should be used with UPARAM to specify which classes are allowed in selection */
		static constexpr const wchar_t* MD_AllowedClasses = L"AllowedClasses";

		/** Metadata that should be used with UPARAM to specify a function name that generates a list of available values */
		static constexpr const wchar_t* MD_GetOptions = L"GetOptions";

		/** Namespace into which a type can be optionally defined = L"wasd"; if empty or not set, the type will belong to the global namespace (default). */
		static constexpr const wchar_t* MD_Namespace = L"Namespace";

		/** Function or class marked as thread-safe. Opts class/function compilation into thread-safety checks. */
		static constexpr const wchar_t* MD_ThreadSafe = L"BlueprintThreadSafe";

		/** Function marked as explicitly not thread-safe. Opts function out of class-level thread-safety checks. */
		static constexpr const wchar_t* MD_NotThreadSafe = L"NotBlueprintThreadSafe";

		/** Metadata to add the property or function to the FieldNotification system. */
		static constexpr const wchar_t* MD_FieldNotify = L"FieldNotify";

	private:
		// This class should never be instantiated
		ISCW_FBlueprintMetadata() {}
	};

	class ISCW_UEdGraphSchema_K2 : public virtual ISCW_UEdGraphSchema
	{
	public:
		static constexpr const wchar_t* PC_Exec = L"exec";
		static constexpr const wchar_t* PC_Boolean = L"bool";
		static constexpr const wchar_t* PC_Byte = L"byte";
		static constexpr const wchar_t* PC_Class = L"class";
		static constexpr const wchar_t* PC_Int = L"int";
		static constexpr const wchar_t* PC_Int64 = L"int64";
		static constexpr const wchar_t* PC_Float = L"float";
		static constexpr const wchar_t* PC_Double = L"double";
		static constexpr const wchar_t* PC_Real = L"real";
		static constexpr const wchar_t* PC_Name = L"name";
		static constexpr const wchar_t* PC_Delegate = L"delegate";
		static constexpr const wchar_t* PC_MCDelegate = L"mcdelegate";
		static constexpr const wchar_t* PC_Object = L"object";
		static constexpr const wchar_t* PC_Interface = L"interface";
		static constexpr const wchar_t* PC_String = L"string";
		static constexpr const wchar_t* PC_Text = L"text";
		static constexpr const wchar_t* PC_Struct = L"struct";
		static constexpr const wchar_t* PC_Wildcard = L"wildcard";
		static constexpr const wchar_t* PC_FieldPath = L"fieldpath";
		static constexpr const wchar_t* PC_Enum = L"enum";
		static constexpr const wchar_t* PC_SoftObject = L"softobject";
		static constexpr const wchar_t* PC_SoftClass = L"softclass";
		static constexpr const wchar_t* PSC_Self = L"self";
		static constexpr const wchar_t* PSC_Index = L"index";
		static constexpr const wchar_t* PSC_Bitmask = L"bitmask";
		static constexpr const wchar_t* PN_Execute = L"execute";
		static constexpr const wchar_t* PN_Then = L"then";
		static constexpr const wchar_t* PN_Completed = L"Completed";
		static constexpr const wchar_t* PN_DelegateEntry = L"delegate";
		static constexpr const wchar_t* PN_EntryPoint = L"EntryPoint";
		static constexpr const wchar_t* PN_Self = L"self";
		static constexpr const wchar_t* PN_Else = L"else";
		static constexpr const wchar_t* PN_Loop = L"loop";
		static constexpr const wchar_t* PN_After = L"after";
		static constexpr const wchar_t* PN_ReturnValue = L"ReturnValue";
		static constexpr const wchar_t* PN_ObjectToCast = L"Object";
		static constexpr const wchar_t* PN_Condition = L"Condition";
		static constexpr const wchar_t* PN_Start = L"Start";
		static constexpr const wchar_t* PN_Stop = L"Stop";
		static constexpr const wchar_t* PN_Index = L"Index";
		static constexpr const wchar_t* PN_Item = L"Item";
		static constexpr const wchar_t* PN_CastSucceeded = L"then";
		static constexpr const wchar_t* PN_CastFailed = L"CastFailed";
		static constexpr const wchar_t* PN_CastedValuePrefix = L"As";

		static constexpr const wchar_t* FN_UserConstructionScript = L"UserConstructionScript";
		static constexpr const wchar_t* FN_ExecuteUbergraphBase = L"ExecuteUbergraph";
		static constexpr const wchar_t* GN_EventGraph = L"EventGraph";
		static constexpr const wchar_t* GN_AnimGraph = L"AnimGraph";

	public:
		virtual ~ISCW_UEdGraphSchema_K2() = default;
		
		virtual std::shared_ptr<ISCW_UEdGraphSchema_K2> ToUEdGraphSchema_K2Ptr() = 0;
		virtual std::shared_ptr<const ISCW_UEdGraphSchema_K2> ToUEdGraphSchema_K2Ptr() const = 0;
	};

	using ISCW_UEdGraphSchema_K2ConstPtr = std::shared_ptr<const ISCW_UEdGraphSchema_K2>;
	using ISCW_UEdGraphSchema_K2Ptr = std::shared_ptr<ISCW_UEdGraphSchema_K2>;
} // namespace Sourcify