// Copyright (c) Microsoft Corporation. 
// Licensed under the MIT license.

#include "LODRecipeExtensions.h"
#include "LODRecipeToolbarExtenders.h"
#include "LODRecipeContentBrowserExtenders.h"

#include "StaticMeshEditorModule.h"
#include "IStaticMeshEditor.h"
#include "ISkeletalMeshEditorModule.h"
#include "IPersonaToolkit.h"
#include "Engine/SkeletalMesh.h"
#include "ContentBrowserModule.h"
#include "ContentBrowserDelegates.h"

FDelegateHandle FLODRecipeExtensions::SkeletalMeshExtensionHandle;
FDelegateHandle FLODRecipeExtensions::ContentBrowserContextMenuExtensionHandle;

void FLODRecipeExtensions::OnModulesChanged(FName InModuleName, EModuleChangeReason InChangeReason)
{
	if (InChangeReason == EModuleChangeReason::ModuleLoaded)
	{
		if (InModuleName == "SkeletalMeshEditor")
		{
			AddSkeletalMeshEditorToolbarExtensions();
		}
		else if (InModuleName == "StaticMeshEditor")
		{
			AddStaticMeshEditorToolbarExtensions();
		}
		else if (InModuleName == "ContentBrowser")
		{
			AddContentBrowserExtensions();
		}
	}
}

void FLODRecipeExtensions::RemoveExtensions()
{
	RemoveSkeletalMeshEditorToolbarExtensions();
	RemoveContentBrowserExtensions();
}

void FLODRecipeExtensions::AddStaticMeshEditorToolbarExtensions()
{
	IStaticMeshEditorModule* StaticMeshEditorModule = &FModuleManager::LoadModuleChecked<IStaticMeshEditorModule>("StaticMeshEditor");
	StaticMeshEditorModule->OnStaticMeshEditorOpened().AddStatic(&FLODRecipeExtensions::OnStaticMeshEditorOpened);
}

void FLODRecipeExtensions::OnStaticMeshEditorOpened(TWeakPtr<IStaticMeshEditor> StaticMeshEditor)
{
	StaticMeshEditor.Pin()->AddToolbarExtender(MakeShareable(new FStaticMeshEditorExtender(StaticMeshEditor)));
}

void FLODRecipeExtensions::AddSkeletalMeshEditorToolbarExtensions()
{
	ISkeletalMeshEditorModule& SkeletalMeshEditorModule = FModuleManager::LoadModuleChecked<ISkeletalMeshEditorModule>("SkeletalMeshEditor");
	auto& SkeletalMeshToolbarExtenders = SkeletalMeshEditorModule.GetAllSkeletalMeshEditorToolbarExtenders();
	SkeletalMeshToolbarExtenders.Add(ISkeletalMeshEditorModule::FSkeletalMeshEditorToolbarExtender::CreateStatic(&FLODRecipeExtensions::AddSkeletalMeshEditorToolbarExtender));
	SkeletalMeshExtensionHandle = SkeletalMeshToolbarExtenders.Last().GetHandle();
}

void FLODRecipeExtensions::RemoveSkeletalMeshEditorToolbarExtensions()
{
	ISkeletalMeshEditorModule* SkeletalMeshEditorModule = FModuleManager::Get().GetModulePtr<ISkeletalMeshEditorModule>("SkeletalMeshEditor");
	if (SkeletalMeshEditorModule)
	{
		typedef ISkeletalMeshEditorModule::FSkeletalMeshEditorToolbarExtender DelegateType;
		SkeletalMeshEditorModule->GetAllSkeletalMeshEditorToolbarExtenders().RemoveAll([=](const DelegateType& In) { return In.GetHandle() == SkeletalMeshExtensionHandle; });
	}
}

TSharedRef<FExtender> FLODRecipeExtensions::AddSkeletalMeshEditorToolbarExtender(const TSharedRef<FUICommandList> CommandList, TSharedRef<ISkeletalMeshEditor> InSkeletalMeshEditor)
{
	USkeletalMesh* SkeletalMesh = InSkeletalMeshEditor->GetPersonaToolkit()->GetMesh();
	return MakeShareable(new FSkeletaMeshEditorExtender(CommandList, InSkeletalMeshEditor));
}

//////////////////////////////////////////////////////////////////////////
// Content browser

void FLODRecipeExtensions::AddContentBrowserExtensions()
{
	FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked<FContentBrowserModule>(TEXT("ContentBrowser"));
	FContentBrowserMenuExtender_SelectedAssets ContentBrowserAssetSelectedExtensionHandle = FContentBrowserMenuExtender_SelectedAssets::CreateStatic(&FLODRecipeExtensions::AddContentBrowserContextMenuExtender);
	TArray<FContentBrowserMenuExtender_SelectedAssets>& CBMenuExtenderDelegates = ContentBrowserModule.GetAllAssetViewContextMenuExtenders();

	CBMenuExtenderDelegates.Add(ContentBrowserAssetSelectedExtensionHandle);
	ContentBrowserContextMenuExtensionHandle = CBMenuExtenderDelegates.Last().GetHandle();
}

void FLODRecipeExtensions::RemoveContentBrowserExtensions()
{
	FModuleStatus OutModuleStatus;
	const FName InModuleName = FName(TEXT("ContentBrowser"));
	if (FModuleManager::Get().QueryModule(InModuleName, OutModuleStatus) && OutModuleStatus.bIsLoaded)
	{
		FContentBrowserModule& ContentBrowserModule = FModuleManager::GetModuleChecked<FContentBrowserModule>(InModuleName);
		TArray<FContentBrowserMenuExtender_SelectedAssets>& CBMenuExtenderDelegates = ContentBrowserModule.GetAllAssetViewContextMenuExtenders();
		if (CBMenuExtenderDelegates.Num() > 0)
		{
			CBMenuExtenderDelegates.RemoveAll([](const FContentBrowserMenuExtender_SelectedAssets& Delegate) { return Delegate.GetHandle() == ContentBrowserContextMenuExtensionHandle; });
		}
	}
}

TSharedRef<FExtender> FLODRecipeExtensions::AddContentBrowserContextMenuExtender(const TArray<FAssetData>& SelectedAssets)
{
	return MakeShareable(new FLODRecipeContentBrowserContextMenu(SelectedAssets));
}
