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

#include <ox/model/model.hpp>

#include <keel/module.hpp>

#include <nostalgia/gfx/palette.hpp>
#include <nostalgia/gfx/tilesheet.hpp>

#include "typeconv.hpp"

namespace nostalgia::gfx {

static class: public keel::Module {
	public:
		[[nodiscard]]
		ox::String id() const noexcept override {
			return ox::String{"net.drinkingtea.nostalgia.gfx"};
		}

		[[nodiscard]]
		ox::Vector<keel::TypeDescGenerator> types() const noexcept final {
			return {
				keel::generateTypeDesc<TileSheetV1>,
				keel::generateTypeDesc<TileSheetV2>,
				keel::generateTypeDesc<TileSheetV3>,
				keel::generateTypeDesc<TileSheetV4>,
				keel::generateTypeDesc<TileSheetV5>,
				keel::generateTypeDesc<CompactTileSheetV1>,
				keel::generateTypeDesc<PaletteV1>,
				keel::generateTypeDesc<PaletteV2>,
				keel::generateTypeDesc<PaletteV3>,
				keel::generateTypeDesc<PaletteV4>,
				keel::generateTypeDesc<PaletteV5>,
				keel::generateTypeDesc<CompactPaletteV1>,
			};
		}

		[[nodiscard]]
		ox::Vector<keel::Converter> converters() const noexcept final {
			return {
				keel::Converter::make<convertNostalgiaPaletteToPaletteV1>(),
				keel::Converter::make<convertPaletteV1ToPaletteV2>(),
				keel::Converter::make<convertPaletteV2ToPaletteV3>(),
				keel::Converter::make<convertPaletteV3ToPaletteV4>(),
				keel::Converter::make<convertPaletteV4ToPaletteV5>(),
				keel::Converter::make<convertPaletteToCompactPalette>(),
				keel::Converter::make<convertTileSheetV1ToTileSheetV2>(),
				keel::Converter::make<convertTileSheetV2ToTileSheetV3>(),
				keel::Converter::make<convertTileSheetV3ToTileSheetV4>(),
				keel::Converter::make<convertTileSheetV4ToTileSheetV5>(),
				keel::Converter::make<convertTileSheetToCompactTileSheet>(),
			};
		}

		[[nodiscard]]
		ox::Vector<keel::PackTransform> packTransforms() const noexcept final {
			return {
				// convert tilesheets to CompactTileSheets
				[](keel::Context &ctx, ox::Buffer &buff, ox::StringViewCR typeId) -> ox::Result<bool> {
					if (typeId == ox::ModelTypeId_v<TileSheetV1> ||
					    typeId == ox::ModelTypeId_v<TileSheetV2> ||
					    typeId == ox::ModelTypeId_v<TileSheetV3> ||
					    typeId == ox::ModelTypeId_v<TileSheetV4> ||
					    typeId == ox::ModelTypeId_v<TileSheetV5>) {
						OX_RETURN_ERROR(keel::convertBuffToBuff<CompactTileSheet>(
								ctx, buff, ox::ClawFormat::Metal).moveTo(buff));
						return true;
					}
					return false;
				},
				[](keel::Context &ctx, ox::Buffer &buff, ox::StringViewCR typeId) -> ox::Result<bool> {
					if (typeId == ox::ModelTypeId_v<NostalgiaPalette> ||
					    typeId == ox::ModelTypeId_v<PaletteV1> ||
					    typeId == ox::ModelTypeId_v<PaletteV2> ||
					    typeId == ox::ModelTypeId_v<PaletteV3> ||
					    typeId == ox::ModelTypeId_v<PaletteV4> ||
					    typeId == ox::ModelTypeId_v<PaletteV5>) {
						OX_RETURN_ERROR(keel::convertBuffToBuff<CompactPalette>(
								ctx, buff, ox::ClawFormat::Metal).moveTo(buff));
						return true;
					}
					return false;
				},
			};
		}

} const mod;

keel::Module const *keelModule() noexcept {
	return &mod;
}

}
