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

#pragma once

#include <ox/std/types.hpp>

#include <turbine/gfx.hpp>

#include <glutils/glutils.hpp>

#include <nostalgia/core/context.hpp>

namespace nostalgia::core::renderer {

constexpr uint64_t TileRows = 128;
constexpr uint64_t TileColumns = 128;
constexpr uint64_t TileCount = TileRows * TileColumns;
constexpr uint64_t BgVertexVboRows = 4;
constexpr uint64_t BgVertexVboRowLength = 7;
constexpr uint64_t BgVertexVboLength = BgVertexVboRows * BgVertexVboRowLength;
constexpr uint64_t BgVertexEboLength = 6;
constexpr uint64_t SpriteVertexVboRows = 4;
constexpr uint64_t SpriteVertexVboRowLength = 6;
constexpr uint64_t SpriteVertexVboLength = SpriteVertexVboRows * SpriteVertexVboRowLength;
constexpr uint64_t SpriteVertexEboLength = 6;

struct CBB: public glutils::BufferSet {
	bool updated = false;
	constexpr CBB() noexcept {
		vertices.resize(TileCount * BgVertexVboLength);
		elements.resize(TileCount * BgVertexEboLength);
	}
};

struct SpriteBlockset: public glutils::BufferSet {
	bool updated = false;
	constexpr SpriteBlockset(uint64_t spriteCount, uint64_t blocksPerSprite) noexcept {
		vertices.resize(spriteCount * SpriteVertexVboLength * blocksPerSprite);
		elements.resize(spriteCount * SpriteVertexEboLength * blocksPerSprite);
	}
};

struct Background {
	float priority = 0;
	bool enabled = false;
	unsigned cbbIdx = 0;
};

class Drawer: public turbine::gl::Drawer {
	private:
		Context &m_ctx;
	public:
		explicit Drawer(Context &ctx) noexcept;
		void draw(turbine::Context&) noexcept final;
};

}

namespace nostalgia::core {
ox::Error initGfx(Context &ctx, InitParams const&) noexcept;
void shutdownGfx(Context &ctx) noexcept;
}
