/*
 * 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 <catch2/catch_test_macros.hpp>
#include <sstream>
#include <vector>

#include "Image/ImageLoaderPfm.hpp"
#include "Scene/DataFormat.hpp"

using namespace OpenVulkano;
using namespace OpenVulkano::Image;

TEST_CASE("ImageLoaderPfm loads PFM images", "[ImageLoaderPfm]")
{
	ImageLoaderPfm loader;

	SECTION("Grayscale Pf image")
	{
		std::ostringstream pfStream;
		pfStream << "Pf\n"
		         << "4 2\n"
		         << "-1.0\n";

		for (int i = 0; i < 8; ++i)
		{
			float pixelValue = 1.0f;
			pfStream.write(reinterpret_cast<const char*>(&pixelValue), sizeof(float));
		}

		std::string pfData = pfStream.str();
		std::vector<uint8_t> pfBuffer(pfData.begin(), pfData.end());

		auto image = loader.loadFromMemory(pfBuffer);

		REQUIRE(image != nullptr);
		REQUIRE(image->resolution.x == 4);
		REQUIRE(image->resolution.y == 2);
		REQUIRE(image->dataFormat == DataFormat::Format::R32_SFLOAT);

		const float expectedValue = 1.0f;
		for (size_t i = 0; i < image->data.Size(); i += sizeof(float))
		{
			float value;
			std::memcpy(&value, &image->data[i], sizeof(float));
			REQUIRE(value == expectedValue);
		}
	}

	SECTION("Color PF image")
	{
        std::ostringstream pfStream;
        pfStream << "PF\n"
                 << "3 2\n"
                 << "-1.0\n";

		for (int i = 0; i < 6 * 3; ++i)
		{
			float pixelValue = 1.0f;
			pfStream.write(reinterpret_cast<const char*>(&pixelValue), sizeof(float));
		}

		std::string pfData = pfStream.str();
		std::vector<uint8_t> pfBuffer(pfData.begin(), pfData.end());

		auto image = loader.loadFromMemory(pfBuffer);

		REQUIRE(image != nullptr);
		REQUIRE(image->resolution.x == 3);
		REQUIRE(image->resolution.y == 2);
		REQUIRE(image->dataFormat == DataFormat::Format::R32G32B32_SFLOAT);

		const float expectedValue = 1.0f;
		for (size_t i = 0; i < image->data.Size(); i += sizeof(float))
		{
			float value;
			std::memcpy(&value, &image->data[i], sizeof(float));
			REQUIRE(value == expectedValue);
		}
	}
}