static TSharedRef<IToolTip> OnGenerateDocTooltip(const FSlateHyperlinkRun::FMetadata& Metadata)
{
	FText DisplayText;
	const FString* Url = Metadata.Find(TEXT("href"));
	if(Url != nullptr)
	{
		DisplayText = FText::Format(LOCTEXT("DocLinkPattern", "View Documentation: {0}"), FText::FromString(*Url));
	}
	else
	{
		DisplayText = LOCTEXT("UnknownLink", "Empty Hyperlink");
	}

	FString UrlString;
	if(Url != nullptr)
	{
		UrlString = *Url;
	}

	// urls for rich tooltips must start with Shared/
	if(UrlString.Len() > 0 && !UrlString.StartsWith(TEXT("Shared")))
	{
		UrlString = FString(TEXT("Shared")) / UrlString;
	}

	FString ExcerptString;
	const FString* Excerpt = Metadata.Find(TEXT("excerpt"));
	if(Excerpt != nullptr)
	{
		ExcerptString = *Excerpt;
	}

	return IDocumentation::Get()->CreateToolTip(DisplayText, nullptr, UrlString, ExcerptString);
}
static void OnAssetLinkClicked(const FSlateHyperlinkRun::FMetadata& Metadata)
{
	const FString* Url = Metadata.Find(TEXT("href"));
	const FString* Action = Metadata.Find(TEXT("action"));
	if(Url)
	{
		ParseAssetLink(*Url, Action);
	}
}
static FText OnGetAssetTooltipText(const FSlateHyperlinkRun::FMetadata& Metadata)
{
	const FString* Url = Metadata.Find(TEXT("href"));
	if(Url != nullptr)
	{
		const FString* Action = Metadata.Find(TEXT("action"));
		return FText::Format(LOCTEXT("AssetLinkPattern", "{0} asset: {1}"), (Action == nullptr || *Action == TEXT("select")) ? LOCTEXT("AssetOpenDesc", "Open") : LOCTEXT("AssetFindDesc", "Find"), FText::FromString(*Url));
	}

	return LOCTEXT("InvalidAssetLink", "Invalid Asset Link");
}
static void OnCodeLinkClicked(const FSlateHyperlinkRun::FMetadata& Metadata)
{
	const FString* Url = Metadata.Find(TEXT("href"));
	if(Url)
	{	
		ParseCodeLink(*Url);
	}
}
void SCreditsScreen::OnBrowserLinkClicked(const FSlateHyperlinkRun::FMetadata& Metadata)
{
	const FString* url = Metadata.Find(TEXT("href"));

	if ( url != NULL )
	{
		FPlatformProcess::LaunchURL(**url, NULL, NULL);
	}
}
static void OnBrowserLinkClicked(const FSlateHyperlinkRun::FMetadata& Metadata)
{
	const FString* URL = Metadata.Find(TEXT("href"));
	
	if(URL)
	{
		FPlatformProcess::LaunchURL(**URL, nullptr, nullptr);
	}
}
static FText OnGetTutorialTooltipText(const FSlateHyperlinkRun::FMetadata& Metadata)
{
	const FString* Url = Metadata.Find(TEXT("href"));
	if(Url != nullptr)
	{
		return FText::Format(LOCTEXT("TutorialLinkPattern", "Open tutorial: {0}"), FText::FromString(*Url));
	}

	return LOCTEXT("InvalidTutorialLink", "Invalid Tutorial Link");
}
static FText OnGetCodeTooltipText(const FSlateHyperlinkRun::FMetadata& Metadata)
{
	const FString* Url = Metadata.Find(TEXT("href"));
	if(Url != nullptr)
	{
		const bool bUseShortIDEName = true;
		return FText::Format(LOCTEXT("CodeLinkPattern", "Open code in {0}: {1}"), FSourceCodeNavigation::GetSuggestedSourceCodeIDE(), FText::FromString(*Url));
	}

	return LOCTEXT("InvalidCodeLink", "Invalid Code Link");
}
static void OnDocLinkClicked(const FSlateHyperlinkRun::FMetadata& Metadata)
{
	const FString* Url = Metadata.Find(TEXT("href"));
	if(Url)
	{
		if( FEngineAnalytics::IsAvailable() )
		{
			TArray<FAnalyticsEventAttribute> EventAttributes;
			EventAttributes.Add(FAnalyticsEventAttribute(TEXT("DocLink"), *Url));

			FEngineAnalytics::GetProvider().RecordEvent( TEXT("Rocket.Tutorials.DocLinkClicked"), EventAttributes );
		}

		IDocumentation::Get()->Open(*Url, FDocumentationSourceInfo(TEXT("tutorials")));
	}
}
static void OnBrowserLinkClicked(const FSlateHyperlinkRun::FMetadata& Metadata)
{
	const FString* Url = Metadata.Find(TEXT("href"));
	if(Url)
	{
		if( FEngineAnalytics::IsAvailable() )
		{
			TArray<FAnalyticsEventAttribute> EventAttributes;
			EventAttributes.Add(FAnalyticsEventAttribute(TEXT("BrowserLink"), *Url));

			FEngineAnalytics::GetProvider().RecordEvent( TEXT("Rocket.Tutorials.BrowserLinkClicked"), EventAttributes );
		}

		FPlatformProcess::LaunchURL(**Url, nullptr, nullptr);
	}
}