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

#pragma once

#include <ox/std/array.hpp>
#include <ox/std/point.hpp>
#include <ox/std/size.hpp>
#include <ox/std/types.hpp>
#include <ox/std/vector.hpp>
#include <ox/model/def.hpp>

#include <turbine/turbine.hpp>

#include "color.hpp"

namespace nostalgia::core {

struct NostalgiaPalette {
	static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.NostalgiaPalette";
	static constexpr auto TypeVersion = 1;
	ox::Vector<Color16> colors = {};
};

struct PaletteV1 {
	static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.Palette";
	static constexpr auto TypeVersion = 1;
	ox::Vector<Color16> colors;
};

struct PaletteV2 {
	static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.Palette";
	static constexpr auto TypeVersion = 2;
	static constexpr auto Preloadable = true;
	ox::Vector<ox::Vector<Color16>> pages;
};

using Palette = PaletteV2;

[[nodiscard]]
constexpr Color16 color(Palette const&pal, size_t page, size_t idx) noexcept {
	if (page < pal.pages.size() && idx < pal.pages[page].size()) [[likely]] {
		return pal.pages[page][idx];
	}
	return 0;
}

[[nodiscard]]
constexpr Color16 color(Palette const&pal, size_t idx) noexcept {
	auto constexpr page = 0;
	return color(pal, page, idx);
}

[[nodiscard]]
constexpr size_t colors(Palette const&pal, size_t page = 0) noexcept {
	if (page < pal.pages.size()) [[likely]] {
		return pal.pages[page].size();
	}
	return 0;
}

[[nodiscard]]
constexpr size_t largestPage(Palette const&pal) noexcept {
	size_t out{};
	for (auto const&page : pal.pages) {
		out = ox::max(out, page.size());
	}
	return out;
}

oxModelBegin(NostalgiaPalette)
	oxModelField(colors)
oxModelEnd()

oxModelBegin(PaletteV1)
	oxModelField(colors)
oxModelEnd()

oxModelBegin(PaletteV2)
	oxModelField(pages)
oxModelEnd()

}
