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

#pragma once

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

#include "context.hpp"

namespace nostalgia::core {

extern ox::Array<char, 128> charMap;

struct Sprite {
	unsigned idx = 0;
	int x = 0;
	int y = 0;
	unsigned tileIdx = 0;
	unsigned spriteShape = 0;
	unsigned spriteSize = 0;
	unsigned flipX = 0;
};

oxModelBegin(Sprite)
	oxModelField(idx)
	oxModelField(x)
	oxModelField(y)
	oxModelField(tileIdx)
	oxModelField(spriteShape)
	oxModelField(spriteSize)
	oxModelField(flipX)
oxModelEnd()

[[nodiscard]]
uint8_t bgStatus(Context &ctx) noexcept;

void setBgStatus(Context &ctx, uint32_t status) noexcept;

bool bgStatus(Context &ctx, unsigned bg) noexcept;

void setBgStatus(Context &ctx, unsigned bg, bool status) noexcept;

void setBgCbb(Context &ctx, unsigned bgIdx, unsigned cbb) noexcept;

/**
 * @param section describes which section of the selected TileSheetSpace to use (e.g. MEM_PALLETE_BG[section])
 */
ox::Error loadBgTileSheet(
		Context &ctx,
		unsigned cbb,
		ox::FileAddress const&tilesheetAddr,
		ox::FileAddress const&paletteAddr = nullptr) noexcept;

ox::Error loadSpriteTileSheet(
		Context &ctx,
		ox::FileAddress const&tilesheetAddr,
		ox::FileAddress const&paletteAddr) noexcept;

ox::Error initConsole(Context &ctx) noexcept;

void puts(Context &ctx, int column, int row, ox::CRStringView str) noexcept;

void setTile(Context &ctx, unsigned bgIdx, int column, int row, uint8_t tile) noexcept;

void clearTileLayer(Context &ctx, unsigned bgIdx) noexcept;

void hideSprite(Context &ctx, unsigned) noexcept;

void setSprite(Context &ctx, unsigned idx, int x, int y, unsigned tileIdx,
               unsigned spriteShape = 0, unsigned spriteSize = 0, unsigned flipX = 0) noexcept;

void setSprite(Context &ctx, Sprite const&s) noexcept;

}

namespace nostalgia::core::gl {

constexpr ox::CStringView GlslVersion = "#version 330";

[[nodiscard]]
ox::Size drawSize(int scale = 5) noexcept;

void draw(core::Context &ctx, ox::Size const&renderSz) noexcept;

void draw(core::Context&, int scale = 5) noexcept;

}
