#pragma once
#include <cstdint>
#include <vector>

namespace bmp2tile
{

// Ported directly from sverx's gfxcomp_stm.c ("ShrunkTileMap",
// .stmcompr) -- the exact encoding devkitSMS's
// SMS_loadSTMcompressedTileMapatAddr expects.
//
// `input` is the tilemap's raw 2-bytes-per-cell little-endian PNT entries
// (PackTilemapEntry's output, concatenated -- the same layout
// SaveTilemapBin already flattens tilemaps into for ZX7). `widthInTiles`
// is the tilemap's width in tiles, written verbatim as the format's
// 1-byte header, so must be 0-255.
//
// The format run-length-encodes the tilemap as a flat, row-boundary-
// agnostic sequence of 16-bit words (input.size()/2 of them -- the
// reference doesn't treat it as a 2D grid at all, `width`/`height` are
// only ever multiplied together for a total count), using three run
// types:
//   - a run of 2-65 consecutive *identical* words
//   - a run of 2-65 consecutive words each one greater than the last
//     (useful for e.g. a horizontally-scrolling strip of sequential
//     tiles)
//   - 1-63 words that fit neither, stored literally ("raw")
// On top of that, each run only stores the entry's *low* byte -- the
// high byte (tile index bit 8 + h/v-flip + priority + sprite-palette,
// i.e. every bit an SMS tilemap entry's upper byte can meaningfully
// hold, which is why only its low 5 bits are ever encoded) is tracked
// separately and only re-emitted when it actually changes, with a
// "temporary change" mechanism so a one-run blip back to the previous
// high byte doesn't cost two control bytes.
//
// Throws std::runtime_error if widthInTiles is out of the 0-255 range
// the 1-byte header can hold.
std::vector<uint8_t> CompressStm(const std::vector<uint8_t>& input, int widthInTiles);

}  // namespace bmp2tile
