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

#include "StaticMeshActorItem.h"
#include "StandInsOutliner.h"
#include "LevelEditor.h"
#include "TreeItemID.h"
#include "GameFramework/Actor.h"
#include "Framework/MultiBox/MultiBoxBuilder.h"
#include "SimplygonAssetUserData.h"

#define LOCTEXT_NAMESPACE "StaticMeshActorItem"

StandInsOutliner::FStaticMeshActorItem::FStaticMeshActorItem(AActor* InStaticMeshActor, FTreeItemPtr InParentItem)
	: StaticMeshActor(InStaticMeshActor), ID(InStaticMeshActor), ParentItem(InParentItem)
{
	Type = ITreeItem::StaticMeshActor;
}

bool StandInsOutliner::FStaticMeshActorItem::CanInteract() const
{
	return true;
}

void StandInsOutliner::FStaticMeshActorItem::GenerateContextMenu(FMenuBuilder& MenuBuilder, SStandInsOutliner& Outliner)
{
	auto SharedOutliner = StaticCastSharedRef<SStandInsOutliner>(Outliner.AsShared());
	MenuBuilder.AddMenuEntry(LOCTEXT("RemoveSMActorFromStandinActor", "Remove From Standin"), FText(), FSlateIcon(), FUIAction(FExecuteAction::CreateRaw(&Outliner, &SStandInsOutliner::RemoveFromStandinActor)));
	MenuBuilder.AddMenuEntry(LOCTEXT("SimplygonUserDataTagClippingGeometry", "Tag as ClippingGeometry"), FText(), FSlateIcon(), FUIAction(FExecuteAction::CreateRaw(&Outliner, &SStandInsOutliner::AddSimplygonUseAssetData, ESimplygonMetaTagType::ClippingGeometry)));
	MenuBuilder.AddMenuEntry(LOCTEXT("SimplygonUserDataTagOccluderGeometry", "Tag as Occluder"), FText(), FSlateIcon(), FUIAction(FExecuteAction::CreateRaw(&Outliner, &SStandInsOutliner::AddSimplygonUseAssetData, ESimplygonMetaTagType::Occluder)));
	MenuBuilder.AddMenuEntry(LOCTEXT("SimplygonUserDataTagGeometryCameraPath", "Tag as GeometryCameraPath"), FText(), FSlateIcon(), FUIAction(FExecuteAction::CreateRaw(&Outliner, &SStandInsOutliner::AddSimplygonUseAssetData, ESimplygonMetaTagType::GeometryCameraPath)));
	MenuBuilder.AddMenuEntry(LOCTEXT("SimplygonUserDataTagRemove", "Remove Tag"), FText(), FSlateIcon(), FUIAction(FExecuteAction::CreateRaw(&Outliner, &SStandInsOutliner::RemoveSimplygonUserAssetData)));
}

FString StandInsOutliner::FStaticMeshActorItem::GetDisplayString() const
{
	if (StaticMeshActor.IsValid())
	{
		return StaticMeshActor->GetFName().GetPlainNameString();
	}
	else
	{
		return FString("");
	}
}

FString StandInsOutliner::FStaticMeshActorItem::GetName() const
{
	if (StaticMeshActor.IsValid())
	{
		return StaticMeshActor->GetName();
	}
	else
	{
		return FString("");
	}
}

FText StandInsOutliner::FStaticMeshActorItem::GetSimplygonUserDataTagsAsText() const
{
	if (StaticMeshActor.IsValid())
	{
		
		AActor* Actor = StaticMeshActor.Get();
		if (Actor)
		{
			TInlineComponentArray<UStaticMeshComponent*> Components;
			Actor->GetComponents(Components);
			for (auto& Component : Components)
			{
				USimplygonAssetUserData* SimplygonUserData = Component->GetAssetUserData<USimplygonAssetUserData>();
				if (SimplygonUserData)
				{
					switch (SimplygonUserData->MetaTag)
					{
					case ESimplygonMetaTagType::Occluder:
						return FText::FromString("Occluder");
						break;
					case ESimplygonMetaTagType::ClippingGeometry:
						return FText::FromString("Clipping Geometry");
						break;
					default:
						return FText::FromString("No UserData");
					}
				}
				
			}
		}
		
		
		
	}
	return FText::FromString("");
}

bool StandInsOutliner::FStaticMeshActorItem::HasSimplygonUserData() const
{ 
	if (StaticMeshActor.IsValid())
	{

		AActor* Actor = StaticMeshActor.Get();
		if (Actor)
		{
			TInlineComponentArray<UStaticMeshComponent*> Components;
			Actor->GetComponents(Components);
			for (auto& Component : Components)
			{
				USimplygonAssetUserData* SimplygonUserData = Component->GetAssetUserData<USimplygonAssetUserData>();
				if (SimplygonUserData)
				{
					return true;
				}

			}
		}

	}
	return false;
}

FSlateColor StandInsOutliner::FStaticMeshActorItem::GetTint() const
{
	bool HasSimplygonUserAssetData = false;
	if (StaticMeshActor.IsValid())
	{

		AActor* Actor = StaticMeshActor.Get();
		if (Actor)
		{
			TInlineComponentArray<UStaticMeshComponent*> Components;
			Actor->GetComponents(Components);
			for (auto& Component : Components)
			{
				USimplygonAssetUserData* SimplygonUserData = Component->GetAssetUserData<USimplygonAssetUserData>();
				if (SimplygonUserData)
				{
					HasSimplygonUserAssetData = true;
					break;
				}

			}
		}

	}

	return HasSimplygonUserAssetData ? FLinearColor(0.95f, 0.85f, 0.0f) : FLinearColor(1.0f, 1.0f, 1.0f);
}

StandInsOutliner::FTreeItemID StandInsOutliner::FStaticMeshActorItem::GetID()
{
	return ID;
}

void StandInsOutliner::FStaticMeshActorItem::PopulateDragDropPayload(FDragDropPayload& Payload) const
{
	AActor* ActorPtr = StaticMeshActor.Get();
	if (ActorPtr)
	{
		if (!Payload.StaticMeshActors)
		{
			Payload.StaticMeshActors = TArray<TWeakObjectPtr<AActor>>();
		}
		Payload.StaticMeshActors->AddUnique(StaticMeshActor);
	}
}

StandInsOutliner::FDragValidationInfo StandInsOutliner::FStaticMeshActorItem::ValidateDrop(FDragDropPayload& DraggedObjects) const
{
	FStaticMeshActorDropTarget Target(StaticMeshActor.Get());
	return Target.ValidateDrop(DraggedObjects);
}

void StandInsOutliner::FStaticMeshActorItem::OnDrop(FDragDropPayload& DraggedObjects, const FDragValidationInfo& ValidationInfo, TSharedRef<SWidget> DroppedOnWidget)
{
	FStaticMeshActorDropTarget Target(StaticMeshActor.Get());
	Target.OnDrop(DraggedObjects, ValidationInfo, DroppedOnWidget);
}


StandInsOutliner::FDragValidationInfo StandInsOutliner::FStaticMeshActorDropTarget::ValidateDrop(FDragDropPayload& DraggedObjects) const
{
	return FDragValidationInfo(EStandInsOutlinerActionType::InvalidAction, FStandInsOutlinerDragDropOp::ToolTip_Incompatible, LOCTEXT("NotImplemented", "Not implemented"));
}

void StandInsOutliner::FStaticMeshActorDropTarget::OnDrop(FDragDropPayload& DraggedObjects, const FDragValidationInfo& ValidationInfo, TSharedRef<SWidget> DroppedOnWidget)
{

}

bool StandInsOutliner::FStaticMeshActorItem::IsHiddenInEditor() const
{
	if (StaticMeshActor.IsValid())
	{
		return StaticMeshActor->IsTemporarilyHiddenInEditor();
	}

	return false;
}

void StandInsOutliner::FStaticMeshActorItem::SetHiddenInEditor(bool bHidden)
{
	if (StaticMeshActor.IsValid())
	{
		StaticMeshActor->SetIsTemporarilyHiddenInEditor(bHidden);
		StaticMeshActor->bHiddenEd;
	}
}

#undef LOCTEXT_NAMESPACE
