/** Handler for when Reimport is selected */
void FAssetTypeActions_FaceFXBase::ExecuteReimport(TArray<TWeakObjectPtr<UObject>> Objects)
{
	TArray<UFaceFXAsset*> SucceedAssets;

	GWarn->BeginSlowTask(LOCTEXT("ReimportProgress", "Reimporting FaceFX Assets..."), true);
	int32 progress = 0;

	//The whole result set
	FFaceFXImportResultSet ResultSet;

	for (const TWeakObjectPtr<UObject>& Object : Objects)
	{
		if(UFaceFXAsset* FaceFXAsset = Cast<UFaceFXAsset>(Object.Get()))
		{
			FFaceFXImportResult& Result = ResultSet.GetOrAdd(FaceFXAsset);

			FCompilationBeforeDeletionDelegate DeletionDelegate;
			if(FaceFXAsset->IsA(UFaceFXActor::StaticClass()) && UFaceFXEditorConfig::Get().IsImportAnimationOnActorImport())
			{
				//actor assets may lead to changed animation sets
				DeletionDelegate = FCompilationBeforeDeletionDelegate::CreateRaw(this, &FAssetTypeActions_FaceFXBase::OnReimportBeforeDelete);
			}

			FFaceFXEditorTools::ReImportFaceFXAsset(FaceFXAsset, Result, DeletionDelegate);
		}

		GWarn->UpdateProgress(++progress, Objects.Num());
	}

	GWarn->EndSlowTask();

	FFaceFXResultWidget::Create(LOCTEXT("ShowReimportResultTitle", "Reimport Result"), ResultSet);
}
UObject* UFaceFXActorFactory::CreateNew(UClass* Class, UObject* InParent, const FName& Name, EObjectFlags Flags, const FCompilationBeforeDeletionDelegate& BeforeDeletionCallback, FString FaceFXAsset)
{
	if(FaceFXAsset.IsEmpty())
	{
		//fetch source file
		if(IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get())
		{
			//get parent window
			void* ParentWindowWindowHandle = nullptr;
			IMainFrameModule& MainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>(TEXT("MainFrame"));
			const TSharedPtr<SWindow>& MainFrameParentWindow = MainFrameModule.GetParentWindow();
			if ( MainFrameParentWindow.IsValid() && MainFrameParentWindow->GetNativeWindow().IsValid() )
			{
				ParentWindowWindowHandle = MainFrameParentWindow->GetNativeWindow()->GetOSWindowHandle();
			}

			static FString LastCreatePath;

			//query for files
			TArray<FString> Files;
			DesktopPlatform->OpenFileDialog(ParentWindowWindowHandle, LOCTEXT("OpenAssetTitle", "Select FaceFX Asset").ToString(), TEXT(""), LastCreatePath, FACEFX_FILEFILTER_ASSET_ACTOR, EFileDialogFlags::None, Files);

			if(Files.Num() <= 0)
			{
				//no file selected
				ShowError(LOCTEXT("CreateFail", "Import of FaceFX asset cancelled."));
				return nullptr;
			}
			FaceFXAsset = Files[0];
			LastCreatePath = FaceFXAsset;
		}
		else
		{
			ShowError(LOCTEXT("CreateFail", "Internal Error: Retrieving platform module failed."));
			return nullptr;
		}
	}

	if(!FaceFXAsset.IsEmpty())
	{
		GWarn->BeginSlowTask(LOCTEXT("ImportProgress", "Importing FaceFX Assets..."), true);

		//create asset
		UFaceFXAsset* NewAsset = NewObject<UFaceFXAsset>(InParent, Class, Name, Flags);

		//initialize asset
		FFaceFXImportResultSet ResultSet;

		if(OnPreInitialization(NewAsset, FaceFXAsset, ResultSet) && FFaceFXEditorTools::InitializeFromFile(NewAsset, FaceFXAsset, ResultSet.GetOrAdd(NewAsset), BeforeDeletionCallback, true))
		{
			//success
			FFaceFXEditorTools::SavePackage(NewAsset->GetOutermost());
		}
						
		GWarn->EndSlowTask();

		FFaceFXResultWidget::Create(LOCTEXT("ShowCreateFxActorResultTitle", "Create FaceFX Asset Result"), ResultSet);

		return NewAsset;
	}
	else
	{
		ShowError(LOCTEXT("CreateFail", "Import failed. FaceFX asset missing."));
	}

	return nullptr;
}
/** Handler for when SetSource is selected */
void FAssetTypeActions_FaceFXBase::ExecuteSetSource(TArray<TWeakObjectPtr<UObject>> Objects)
{
	if(Objects.Num() == 0)
	{
		//failure
		FFaceFXEditorTools::ShowError(LOCTEXT("SetSourceFailedMissing","Missing asset."));
		return;
	}

	UFaceFXAsset* FaceFXAsset = Cast<UFaceFXAsset>(Objects[0].Get());
	if(!FaceFXAsset)
	{
		//failure
		FFaceFXEditorTools::ShowError(LOCTEXT("SetSourceFailedInvalid","Invalid asset type."));
		return;
	}

	if(IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get())
	{
		//get parent window
		void* ParentWindowWindowHandle = nullptr;
		IMainFrameModule& MainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>(TEXT("MainFrame"));
		const TSharedPtr<SWindow>& MainFrameParentWindow = MainFrameModule.GetParentWindow();
		if ( MainFrameParentWindow.IsValid() && MainFrameParentWindow->GetNativeWindow().IsValid() )
		{
			ParentWindowWindowHandle = MainFrameParentWindow->GetNativeWindow()->GetOSWindowHandle();
		}

		//query for files
		TArray<FString> Files;
		DesktopPlatform->OpenFileDialog(ParentWindowWindowHandle, LOCTEXT("OpenAssetTitle", "Select FaceFX Asset").ToString(), TEXT(""), FaceFXAsset->GetAssetPathAbsolute(), FACEFX_FILEFILTER_ASSET_ACTOR, EFileDialogFlags::None, Files);

		if(Files.Num() <= 0)
		{
			//no file selected
			FFaceFXEditorTools::ShowError(LOCTEXT("SetSourceFailedCancelled", "FaceFX asset selection cancelled."));
			return;
		}

		if(UFaceFXAnim* FaceFXAnim = Cast<UFaceFXAnim>(FaceFXAsset))
		{
			//remove previous animation id in case of an UFaceFXAnim so the init phase will ask the user for an animation of the new source
			FaceFXAnim->GetId().Reset();
		}

		//assign new file and reimport
		FFaceFXImportResultSet ResultSet;

        FCompilationBeforeDeletionDelegate DeletionDelegate;
        if(FaceFXAsset->IsA(UFaceFXActor::StaticClass()) && UFaceFXEditorConfig::Get().IsImportAnimationOnActorImport())
        {
            //actor assets may lead to changed animation sets
            DeletionDelegate = FCompilationBeforeDeletionDelegate::CreateStatic(&UFaceFXActorFactory::OnFxActorCompilationBeforeDelete);
        }

		FFaceFXEditorTools::InitializeFromFile(FaceFXAsset, Files[0], ResultSet.GetOrAdd(FaceFXAsset), DeletionDelegate);

		FFaceFXResultWidget::Create(LOCTEXT("ShowSetSourceResultTitle", "Set Source Result"), ResultSet);
	}
	else
	{
		//failure
		FFaceFXEditorTools::ShowError(LOCTEXT("SetSourceFailedPlatform","Unable to fetch desktop platform module."));
	}
}