/*
 * Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
 */

#include <nostalgia/core/gfx.hpp>
#include <keel/media.hpp>

#include "typeconv.hpp"

namespace nostalgia::scene {

[[nodiscard]]
constexpr unsigned adjustLayerAttachment(unsigned layer, unsigned attachment) noexcept {
	if (attachment == 0) {
		return layer;
	} else {
		return attachment - 1;
	}
}

constexpr void setLayerAttachments(unsigned layer, TileDoc const&srcTile, SceneStatic::Tile &dstTile) noexcept {
	setTopEdge(
			dstTile.layerAttachments,
			adjustLayerAttachment(layer, srcTile.layerAttachments[0]));
	setBottomEdge(
			dstTile.layerAttachments,
			adjustLayerAttachment(layer, srcTile.layerAttachments[1]));
	setLeftEdge(
			dstTile.layerAttachments,
			adjustLayerAttachment(layer, srcTile.layerAttachments[2]));
	setRightEdge(
			dstTile.layerAttachments,
			adjustLayerAttachment(layer, srcTile.layerAttachments[3]));
}

ox::Error SceneDocToSceneStaticConverter::convert(
		keel::Context &ctx,
		SceneDoc &src,
		SceneStatic &dst) const noexcept {
	oxRequire(ts, keel::readObj<core::TileSheet>(ctx, src.tilesheet));
	const auto layerCnt = src.tiles.size();
	dst.setLayerCnt(layerCnt);
	dst.tilesheet = ox::FileAddress(src.tilesheet);
	dst.palettes.reserve(src.palettes.size());
	for (const auto &pal : src.palettes) {
		dst.palettes.emplace_back(pal);
	}
	for (auto layerIdx = 0u; const auto &layer : src.tiles) {
		const auto layerDim = src.size(layerIdx);
		auto dstLayer = dst.layer(layerIdx);
		dstLayer.setDimensions(layerDim);
		for (auto tileIdx = 0u; const auto &row : layer) {
			for (const auto &srcTile : row) {
				auto dstTile = dstLayer.tile(tileIdx);
				dstTile.tileType = srcTile.type;
				oxRequire(path, srcTile.getSubsheetPath(*ts));
				oxRequire(mapIdx, getTileOffset(*ts, path));
				dstTile.tileMapIdx = static_cast<uint16_t>(mapIdx);
				setLayerAttachments(layerIdx, srcTile, dstTile);
				++tileIdx;
			}
		}
		++layerIdx;
	}
	return {};
}

}
