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

#pragma once

#include <functional>
#include <map>
#include "ISCW_UnrealEngine.h"
#include "SCW_Base.h"

using std::function;
using std::map;
using std::vector;
using std::wstring;

namespace Sourcify
{
	class SCW_UnrealEngine : public SCW_Base, public ISCW_UnrealEngine
	{
	public:
		SCW_UnrealEngine();

		int32_t Algo_LevenshteinDistance(const wstring& StrA, const wstring& StrB) const override;

		void EditorUtilities_CopySingleProperty(ISCW_UObjectConstPtr InSourceObject, ISCW_UObjectPtr InTargetObject, ISCW_FPropertyConstPtr InProperty) const override;

		ISCW_UActorComponentPtr EditorUtilities_FindMatchingComponentInstance(ISCW_UActorComponentPtr SourceComponent, ISCW_AActorPtr TargetActor) const override;

		void FBlueprintNamespaceUtilities_GetDefaultImportsForObject(ISCW_UObjectConstPtr InObject, set<wstring>& OutNamespaces) const override;

		void FBlueprintEditorUtils_PurgeNullGraphs(ISCW_UBlueprintPtr Blueprint) const override;

		bool FBlueprintEditorUtils_SupportsConstructionScript(ISCW_UBlueprintPtr Blueprint) const override;

		ISCW_FComponentKeyPtr FComponentKey(ISCW_UBlueprintPtr Blueprint, ISCW_UK2Node_AddComponentPtr UCSNode) const override;

		ISCW_FComponentKeyPtr FComponentKey(ISCW_USCS_NodePtr SCSNode) const override;

		wstring FGuid_NewGuid()	const override;

		ISCW_UObjectPtr FindObjectWithOuter(ISCW_UObjectConstPtr Outer, SCW_ClassToLookFor ClassToLookFor = SCW_ClassToLookFor::None, wstring NameToLookFor = L"None"/*NAME_None*/) const override;

		void FStructureEditorUtils_CompileStructure(ISCW_UUserDefinedStructPtr Struct) const override;

		void GEngine_Exec(const wchar_t* Command) const override;
			
		ISCW_UGeneralProjectSettingsConstPtr GetDefault_UGeneralProjectSettings() const override;
		
		void GetDerivedClasses(ISCW_UClassConstPtr ClassToLookFor, vector<ISCW_UClassPtr>& Results, bool bRecursive = true) const override;

		bool IsChildOf_UActorComponent(ISCW_UClassConstPtr InClassPtr) const override;

		bool IsChildOf_UWidget(ISCW_UClassConstPtr InClassPtr) const override;
		
		vector<ISCW_FPropertyPtr> TFieldIterator_GetFProperties(const ISCW_UStructConstPtr Struct, ISCW_EFieldIterationFlags InIterationFlags = ISCW_EFieldIterationFlags::Default) const override;

		vector<ISCW_FObjectPropertyPtr> TFieldRange_FObjectProperties(ISCW_UStructConstPtr InStructPtr, ISCW_EFieldIterationFlags InIterationFlags = ISCW_EFieldIterationFlags::Default) const override;

		vector<ISCW_UFunctionPtr> TFieldRange_UFunctions(ISCW_UStructConstPtr InStructPtr, ISCW_EFieldIterationFlags InIterationFlags = ISCW_EFieldIterationFlags::Default) const override;
		
		bool FDesktopPlatformModule_GenerateProjectFiles(const wstring& RootDir, const wstring& ProjectFileName) const override;

		bool FAssetRegistryModule_GetRegistry_GetReferencers(const wstring& PackageName, vector<ISCW_UObjectPtr>& OutReferencers) const override;

		void FAssetRegistryModule_SearchAllAssets(bool bSynchronousSearch) const override;

		ISCW_UEdGraphPtr FBlueprintEditorUtils_FindUserConstructionScript(ISCW_UBlueprintPtr Blueprint) const override;

		int32_t FBlueprintEditorUtils_GetChildrenOfBlueprint(ISCW_UBlueprintConstPtr Blueprint, vector<ISCW_UBlueprintPtr>& OutChildren) const override;

		bool FBlueprintEditorUtils_IsDataOnlyBlueprint(ISCW_UBlueprintConstPtr Blueprint) const override;

		void FBlueprintEditorUtils_ConformCallsToParentFunctions(ISCW_UBlueprintPtr Blueprint) const override;

		void FBlueprintEditorUtils_ConformImplementedEvents(ISCW_UBlueprintPtr Blueprint) const override;

		void FBlueprintEditorUtils_ConformImplementedInterfaces(ISCW_UBlueprintPtr Blueprint) const override;
	
		void FBlueprintEditorUtils_MarkBlueprintAsModified(ISCW_UBlueprintPtr Blueprint) const override;

		void FBlueprintEditorUtils_MarkBlueprintAsStructurallyModified(ISCW_UBlueprintPtr Blueprint) const override;

		void FBlueprintEditorUtils_PostEditChangeBlueprintActors(ISCW_UBlueprintPtr Blueprint) const override;

		bool FBlueprintEditorUtils_PropertyValueToString_UObject(ISCW_FPropertyConstPtr Property, ISCW_UObjectPtr Object, wstring& OutString) const override;

		void FBlueprintEditorUtils_RefreshAllNodes(ISCW_UBlueprintPtr Blueprint) const override;

		void FBlueprintEditorUtils_RemoveInterface(ISCW_UBlueprintPtr Blueprint, const wstring& InterfaceClassPathName, bool bPreserveFunctions /* = false */) const override;

		void FBlueprintEditorUtils_RemoveVariableNodes(ISCW_UBlueprintPtr Blueprint, const wstring& Name) const override;

		void FBlueprintEditorUtils_RenameFunctionReferences(ISCW_UBlueprintPtr Blueprint, ISCW_UClassPtr FunctionClass, const wstring& OldFuncName, const wstring& NewFuncName) const override;

		void FBlueprintEditorUtils_RenameGraph(ISCW_UEdGraphPtr Graph, const wstring& NewName) const override;

		void FBlueprintEditorUtils_UpdateOutOfDateCompositeNodes(ISCW_UBlueprintPtr Blueprint) const override;

		void FBlueprintEditorUtils_UpdateTransactionalFlags(ISCW_UBlueprintPtr Blueprint) const override;

		wstring FCommandLine_Get() const override;

		vector<vector<wstring>> FCsvParser_GetRows(const wstring& CsvContent) const override;

		bool FFileHelper_SaveStringToFile(wstring String, const wchar_t* Filename) const override;

		bool FFileHelper_LoadFileToString(wstring& Result, const wchar_t* Filename) const override;

		ISCW_FGraphNodeCreator_UK2Node_EventPtr FGraphNodeCreator_UK2Node_Event(ISCW_UEdGraphPtr Graph) const override;

		ISCW_FGraphNodeCreator_UK2Node_CreateDelegatePtr FGraphNodeCreator_UK2Node_CreateDelegate(ISCW_UEdGraphPtr Graph) const override;

		ISCW_FObjectPropertyConstPtr FindFProperty(ISCW_UBlueprintGeneratedClassPtr Owner, const wstring& FieldName) const override;

		ISCW_FObjectPropertyConstPtr FindFProperty(ISCW_UClassPtr Owner, const wstring& FieldName) const override;

#if ISCW_UE_VERSION_NEWER_THAN_OR_EQUAL(5, 7, 0)
		ISCW_UObjectPtr FindObject(ISCW_UObjectPtr Outer, const wstring& Name, SCW_EFindObjectFlags Flags /* = SCW_EFindObjectFlags::None */) const override;
#else
		ISCW_UObjectPtr FindObject(ISCW_UObjectPtr Outer, const wstring& Name, bool ExactClass = false) const override;
#endif

#if ISCW_UE_VERSION_NEWER_THAN_OR_EQUAL(5, 7, 0)
		ISCW_UEnumPtr FindObject_UEnum(ISCW_UObjectPtr Outer, const wstring& Name, SCW_EFindObjectFlags Flags /* = SCW_EFindObjectFlags::None */) const override;
#else
		ISCW_UEnumPtr FindObject_UEnum(ISCW_UObjectPtr Outer, const wstring& Name, bool bExactClass /* = false */) const override;
#endif

		bool FKismetEditorUtilities_CompileBlueprint(ISCW_UBlueprintPtr Blueprint, SCW_EBlueprintCompileOptions Options) const override;

		void FKismetEditorUtilities_UpgradeCosmeticallyStaleBlueprint(ISCW_UBlueprintPtr Blueprint) const override;

		wstring FName_NameToDisplayString(const wstring& Name, bool bIsBool) const override;

		void FPlatformMisc_RequestExit(bool Force) const override;

		bool GConfig_IsKnownConfigName(const wstring& ConfigName) const override;

		bool ILiveCoding_IsEnabledForSession() const override;

		bool ILiveCoding_Compile() const override;

		ISCW_FSlowTaskPtr FSlowTask_New(int32_t InAmountOfWork, const wstring& InDefaultMessage /* = L"" */, bool bInEnabled /* = true */) const override;

		bool FSourceCodeNavigation_FindModulePath(const wstring& ModuleName, wstring& OutPath) override;

		wstring FTopLevelAssetPath_ToString(ISCW_UFieldConstPtr Field) override;

		void ISourceControlProvider_NotifySourceControl(const vector<wstring>& Files) const override;

		void* FMemory_Malloc(size_t Size, size_t Alignment = 0) const override;

		void FMemory_Free(void* Original) const override;

		void* FMemory_Realloc(void* Original, size_t Size, size_t Alignment = 0) const override;

		wstring FModuleManager_GetModuleFilename(const wstring& ModuleName) const override;

		vector<ISCW_UClassPtr> TObjectIterator_GetClasses(SCW_EObjectFlags AdditionalExclusionFlags/* = SCW_EObjectFlags::RF_ClassDefaultObject*/, bool bIncludeDerivedClasses/* = true*/) const override;

		vector<ISCW_UEnumPtr> TObjectIterator_GetEnums(SCW_EObjectFlags AdditionalExclusionFlags/* = SCW_EObjectFlags::RF_ClassDefaultObject*/, bool bIncludeDerivedClasses/* = true*/) const override;

		vector<ISCW_UObjectPtr> TObjectIterator_GetObjects(SCW_EObjectFlags AdditionalExclusionFlags /* = SCW_EObjectFlags::RF_ClassDefaultObject */, bool bIncludeDerivedClasses /* = true */) const override;

		vector<ISCW_UStructPtr> TObjectIterator_GetStructs(SCW_EObjectFlags AdditionalExclusionFlags/* = SCW_EObjectFlags::RF_ClassDefaultObject*/, bool bIncludeDerivedClasses/* = true*/) const override;

		bool FPaths_FileExists(const wstring& InPath) override;

		wstring FPaths_ConvertRelativePathToFull(const wstring& InPath) const override;

		wstring FPaths_GameSourceDir() const override;

		wstring FPaths_GetBaseFilename(const wstring& InPath, bool bRemovePath/* = true*/) const override;

		wstring FPaths_GetExtension(const wstring& InPath) const override;

		wstring FPaths_GetPath(const wstring& InPath) const override;

		wstring FPaths_GetProjectFilePath() const override;

		wstring FPaths_ProjectSavedDir() const override;

		bool FPaths_MakePathRelativeTo(wstring& InOutPath, const wstring& InRelativeTo) const override;

		void FPaths_NormalizeDirectoryName(wstring& InOutPath) const override;

		void FPaths_NormalizeFilename(wstring& InOutPath) const override;

		wstring FPaths_RootDir() const override;

		bool FPlatformFileManager_GetPlatformFile_DirectoryExists(const wstring& InPath) const override;

		bool FPlatformFileManager_GetPlatformFile_FileExists(const wstring& InFile) const override;

		bool FPlatformFileManager_GetPlatformFile_IterateDirectory(const wstring& InPath, function<bool(const wchar_t*, bool)> Visitor) const override;

		bool FPlatformFileManager_GetPlatformFile_IterateDirectoryRecursively(const wstring& InPath, std::function<bool(const wchar_t*, bool)> Visitor) const override;

		bool FPlatformFileManager_GetPlatformFile_SetReadOnly(const wstring& InFile, bool bNewReadOnlyValue) const override;
		
		ISCW_UPackagePtr GetTransientPackage() const override;

		bool IsValid(ISCW_UObjectConstPtr Test) const override;

		void LogMacros_UE_LOG(SCW_UE_LOG_Category Category, SCW_ELogVerbosity Verbosity, const wstring& Message, const wstring Filename = L"", const int32_t LineNumber=-1) const override;
		
		ISCW_UBlueprintPtr LoadObject_UBlueprint(ISCW_UObjectPtr Outer, const wstring& Path) const override;

		ISCW_UObjectPtr LoadObject_UObject(ISCW_UObjectPtr Outer, const wstring& Path) const override;

		wstring MakeUniqueObjectName(ISCW_UObjectPtr Outer, ISCW_UClassPtr Class, const wstring& BaseName) const override;

		ISCW_UObjectPtr NewObject_UObject(ISCW_UObjectPtr Outer, ISCW_UClassPtr Class, const wstring& Name, SCW_EObjectFlags Flags/* = SCW_EObjectFlags::RF_NoFlags*/) const override;

		ISCW_USimpleConstructionScriptPtr NewObject_USimpleConstructionScript(ISCW_UBlueprintGeneratedClassPtr Class, const wstring& Name = L"") const override;

		void ObjectTools_ConsolidateObjects(ISCW_UObjectPtr ObjectToConsolidateTo, const vector<ISCW_UObjectPtr>& ObjectsToConsolidate, bool bShowDeleteConfirmation /* = true */) const override;

		bool GameProjectUtils_IsValidClassNameForCreation(const wstring& ClassName, const wstring& OutputDirectory, wstring& OutReason) const override;

		bool UEditorPerProjectUserSettings_GetAutomaticallyHotReloadNewClasses() const override;

		void UEngine_CopyPropertiesForUnrelatedObjects(ISCW_UObjectPtr SourceObject, ISCW_UObjectPtr DestinationObject) const override;

		wstring UGeneralProjectSettings_GetProjectName() const override;

		// UMetaData is deprecated as of 5.6, use FMetaData instead.
#if ISCW_UE_VERSION_OLDER_THAN(5, 6, 0)
		map<wstring, wstring> UMetaData_GetMapForObject(ISCW_UObjectConstPtr Object) const override;
		wstring UMetaData_GetRemappedKeyName(const wstring& Key) const override;
#else
		map<wstring, wstring> FMetaData_GetMapForObject(ISCW_UObjectConstPtr Object) const override;
		wstring FMetaData_GetRemappedKeyName(const wstring& Key) const override;
#endif // #if ISCW_UE_VERSION_OLDER_THAN(5, 6, 0)

		bool UPackageTools_ReloadPackages(vector<ISCW_UPackagePtr> Packages, wstring& ErrorMessage, SCW_EReloadPackagesInteractionMode Mode) const override;

		void USubobjectDataSubsystem_ChangeSubobjectClass(ISCW_FSubobjectDataHandlePtr SubobjectDataHandle, ISCW_UClassPtr NewClass) const override;

		void USubobjectDataSubsystem_GatherSubobjectData(ISCW_UObjectPtr Context, vector<ISCW_FSubobjectDataHandlePtr>& OutArray) const override;

		ISCW_UWorldPtr UWorld_CreateWorld(const SCW_EWorldType InWorldType, bool bInformEngineOfWorld, wstring WorldName = L"none", ISCW_UPackagePtr InWorldPackage = nullptr, bool bAddToRoot = true, SCW_ERHIFeatureLevel InFeatureLevel = SCW_ERHIFeatureLevel::Num/*, const InitializationValues* InIVS = nullptr, bool bInSkipInitWorld = false*/) const override;

		ISCW_UClassPtr UWorld_StaticClass() const override;

		bool GLOBAL_GetGFlushRenderingCommandsOnPreEditChange() const override;

		void GLOBAL_SetGFlushRenderingCommandsOnPreEditChange(bool bInFlushRenderingCommandsOnPreEditChange) const override;

		SCW_EAppReturnType FMessageDialog_Open(SCW_EAppMsgType MessageType, const wstring& Message) override;
		SCW_EAppReturnType FMessageDialog_Open(SCW_EAppMsgType MessageType, const wstring& Message, const wstring& Title) override;
		SCW_EAppReturnType FMessageDialog_Open(SCW_EAppMsgCategory MessageCategory, SCW_EAppMsgType MessageType, const wstring& Message) override;
		SCW_EAppReturnType FMessageDialog_Open(SCW_EAppMsgCategory MessageCategory, SCW_EAppMsgType MessageType, const wstring& Message, const wstring& Title) override;

		void GEditor_CloseAndReopenAssetEditor(ISCW_UObjectPtr Asset) override;

		shared_ptr<ISCW_UnrealEngine> ToUnrealEnginePtr() override;
		shared_ptr<const ISCW_UnrealEngine> ToUnrealEnginePtr() const override;
	};
} // namespace Sourcify