/*
 * Copyright 2019,2020 Sony Corporation
 */

// <-- Plugin Header -->
#include "Window/SRDisplaySceneViewport.h"
#include "Window/SRDisplayViewportClient.h"

// <-- Engine Header -->
#include <Slate/SceneViewport.h>
#include <Widgets/SViewport.h>

namespace sr_display
{
	void SSRDisplaySceneViewport::Construct(const FArguments& InArgs)
	{
		// Create Viewport Widget
		Viewport = SNew(SViewport)
			.IsEnabled(true)
			.EnableGammaCorrection(false)
			.ShowEffectWhenDisabled(false)
			.EnableBlending(true);
	}

	void SSRDisplaySceneViewport::Init(float SizeX, float SizeY)
	{
		// Create Viewport Client
		PlayViewportClient = MakeShareable(new FSRDisplayViewportClient(SizeX, SizeY));

		// Create Scene Viewport
		SceneViewport = MakeShareable(new FSceneViewport(PlayViewportClient.Get(), Viewport));

		// Assign SceneViewport to Viewport widget. It needed for rendering
		Viewport->SetViewportInterface(SceneViewport.ToSharedRef());
		PlayViewportClient->Viewport = SceneViewport.Get();

		// Assing Viewport widget for our custom PlayScene Viewport
		this->ChildSlot
		[
			Viewport.ToSharedRef()
		];
	}

	UTextureRenderTarget2D* SSRDisplaySceneViewport::GetRenderTarget()
	{
		return PlayViewportClient->GetRenderTarget();
	}

	void SSRDisplaySceneViewport::Shutdown()
	{
		if (SceneViewport.IsValid())
		{
			SceneViewport.Reset();
			SceneViewport = nullptr;
		}

		if (PlayViewportClient.IsValid())
		{
			PlayViewportClient->Shutdown();
			PlayViewportClient.Reset();
			PlayViewportClient = nullptr;
		}

		if (Viewport.IsValid())
		{
			Viewport.Reset();
			Viewport = nullptr;
		}
	}

	void SSRDisplaySceneViewport::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime)
	{
		SWidget::Tick(AllottedGeometry, InCurrentTime, InDeltaTime);

		PlayViewportClient->Tick();

		static bool bFirstTime = true;
		if (bFirstTime)
		{
			bFirstTime = false;
			FSlateApplication::Get().RegisterGameViewport(Viewport.ToSharedRef());
		}
	}

	void SSRDisplaySceneViewport::RenderTexture_RenderThread(FRHICommandListImmediate& RHICmdList)
	{
		PlayViewportClient->RenderTexture_RenderThread(RHICmdList);
	}

	bool SSRDisplaySceneViewport::GetMousePosition(FVector2D& MousePosition) const
	{
		return PlayViewportClient->GetMousePosition(MousePosition);
	}

	FViewport* SSRDisplaySceneViewport::GetViewport()
	{
		if (PlayViewportClient.IsValid())
		{
			return PlayViewportClient->Viewport;
		}
		return nullptr;
	}

} // namespace sr_display
