
#include "PortaInterfaceEditor.h"
#include "ToolMenus.h"
#include "ContentBrowserMenuContexts.h"
#include "Factories/EnumFactory.h"
#include "AssetToolsModule.h"
#include "ContentBrowserModule.h"
#include "Engine/UserDefinedEnum.h"
#include "IContentBrowserSingleton.h"
#include "Kismet2/EnumEditorUtils.h"

#define LOCTEXT_NAMESPACE "FPortaInterfaceEditorModule"

void FPortaInterfaceEditorModule::StartupModule()
{
	// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
	ExtendDataTableMenu();
}

void FPortaInterfaceEditorModule::ShutdownModule()
{
	// This function may be called during shutdown to clean up your module.  For modules that support dynamic reloading,
	// we call this function before unloading the module.
}

void FPortaInterfaceEditorModule::ExtendDataTableMenu()
{
	auto Menu = UToolMenus::Get()->ExtendMenu("ContentBrowser.AssetContextMenu.DataTable");
	FToolMenuSection& Section = Menu->FindOrAddSection("GetAssetActions");
	Section.AddDynamicEntry("ColToEnum", FNewToolMenuSectionDelegate::CreateLambda([](FToolMenuSection& InSection)
	{
			UContentBrowserAssetContextMenuContext* Context = InSection.FindContext<UContentBrowserAssetContextMenuContext>();
			if (Context)
			{

				TArray<UObject*> SelectedObjects = Context->GetSelectedObjects();
				if (SelectedObjects.Num() > 0)
				{
					InSection.AddMenuEntry(
						"ColToEnum",
						LOCTEXT("ColToEnum", "Create Enum from Row Names"),
						LOCTEXT("ColToEnum_ToolTip", "Create Enum from Row Names."),
						FSlateIcon(),
						FUIAction(
							FExecuteAction::CreateLambda([SelectedObjects]()
								{
									FAssetToolsModule& AssetToolsModule = FModuleManager::Get().LoadModuleChecked<FAssetToolsModule>("AssetTools");
									FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked<FContentBrowserModule>("ContentBrowser");

									for (UObject* SelectedObject : SelectedObjects)
									{
										auto DataTable = Cast<UDataTable>(SelectedObject);
										if (DataTable)
										{
											TArray<UObject*> ObjectsToSync;
											auto Factory = NewObject<UEnumFactory>();
											auto PackageName = DataTable->GetPathName();
											auto PackagePath = FPackageName::GetLongPackagePath(PackageName);
											FString Name = DataTable->GetName() + TEXT("_RowEnum");

											FSoftObjectPath Path(PackagePath + "/" + Name);
											UUserDefinedEnum* UserEnum = nullptr;
											auto Existing = Path.TryLoad();
											if (Existing)
											{
												UserEnum = Cast<UUserDefinedEnum>(Existing);
												if (UserEnum)
												{
													//the last entry is the MAX, which we can't remove, so go back before it
													for (int i = UserEnum->NumEnums() - 2; i >= 0; --i)
													{
														FEnumEditorUtils::RemoveEnumeratorFromUserDefinedEnum(UserEnum, i);
													}
												}
											}
											else
											{
												if (UObject* NewAsset = AssetToolsModule.Get().CreateAsset(Name, PackagePath, UUserDefinedEnum::StaticClass(), Factory))
												{
													ObjectsToSync.Add(NewAsset);
													UserEnum = Cast<UUserDefinedEnum>(NewAsset);
												}
											}

											if (UserEnum)
											{
												auto RowNames = DataTable->GetRowNames();
												for (int i = 0; i < RowNames.Num(); ++i)
												{
													FEnumEditorUtils::AddNewEnumeratorForUserDefinedEnum(UserEnum);
													FEnumEditorUtils::SetEnumeratorDisplayName(UserEnum, i, FText::FromName(RowNames[i]));
												}
											}

											if (ObjectsToSync.Num() > 0)
											{
												ContentBrowserModule.Get().SyncBrowserToAssets(ObjectsToSync);
											}

											return;
										}
									}
								}),
							FCanExecuteAction::CreateLambda([SelectedObjects]()
								{
									return SelectedObjects.Num() == 1;
								})

						)
					);

				}
			}

	}));
}

#undef LOCTEXT_NAMESPACE
	
IMPLEMENT_MODULE(FPortaInterfaceEditorModule, PortaInterfaceEditor)
