/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

#include "ArFramePlayback.hpp"
#include "ArSessionPlayback.hpp"
#include "Base/BlockProfiler.hpp"

namespace OpenVulkano::AR::Playback
{
	ArFramePlayback::ArFramePlayback(const std::shared_ptr<ArSessionPlayback>& session, ArPlaybackReader& frameReader)
			: ArFrame(session, frameReader.GetNextFrameId())
	{
		//BlockProfiler profile("Read_AR_Frame");
		const auto data = frameReader.ReadMetadata();
		frameMetadata = ArFrameMetadata::FromXML(data.Data(), data.Size());
		if (session->GetCapabilities().IsDepthSupported())
		{
			auto depth = frameReader.ReadDepthImage();
			confImgData = std::move(depth.confidence.image);
			depthImgData = std::move(depth.depth.image);
			depthImage.format = session->GetSessionMetadata().depthFormat;
			depthImage.intrinsic = frameMetadata.intrinsic.GetForResolution({depth.depth.header.width, depth.depth.header.height});
			depthImage.depth.data = depthImgData.get();
			depthImage.depth.resolution = {depth.depth.header.width, depth.depth.header.height};
			depthImage.confidence.data = confImgData.get();
			depthImage.depth.resolution = {depth.confidence.header.width, depth.confidence.header.height};
		}
		if (session->IsLoadColorEnabled())
		{
			colorImgData = frameReader.ReadColorImage();
			colorImage.intrinsic = frameMetadata.intrinsic.GetForResolution({colorImgData.cols, colorImgData.rows});
			colorImage.format = ArImagePlanar::Format::RGB;
			colorImage.luminescenceOrColor = {colorImgData.data, {colorImgData.cols, colorImgData.rows}};
			colorImage.luminescenceOrColor.numChannels = colorImgData.channels;
		}
		SetSaved();
	}

	ArImagePlanar ArFramePlayback::GetCameraImage()
	{
		return colorImage;
	}

	ArDepthImage ArFramePlayback::GetDepthImage()
	{
		return depthImage;
	}

	Math::Matrix4f ArFramePlayback::GetCameraViewForCurrentDeviceOrientation()
	{
		return Math::Utils::inverse(GetCameraTransformation());
	}

	Math::Matrix4f ArFramePlayback::GetCameraProjection(Math::Vector2f viewportSize, float near, float far)
	{
		return GetFrameMetadata().projection; //TODO
	}
}
