// JoeyLib file access: read-only game data, writable save files, and a disk-
// space query.
//
// Two directories sit next to the executable, staged there by the per-platform
// disk / directory packagers:
//   DATA/  -- read-only game content (levels, sprites, audio). jlDataOpen.
//   SAVES/ -- writable save / preference files. jlSave*.
// Both are addressed by a bare name relative to their directory; the prefix is
// forced here so callers never hard-code "DATA/" or "SAVES/".

#ifndef JOEYLIB_FILE_H
#define JOEYLIB_FILE_H

#include <stdio.h>

#include "types.h"

// ----- Read-only game data (DATA/) -----

// Open a data file by its name relative to the DATA/ directory. The DATA/
// prefix is prepended automatically; pass "levels/title.dat", not
// "DATA/levels/title.dat". mode is a standard fopen mode string. Returns NULL
// if the resulting path would overflow the internal buffer or the file cannot
// be opened.
FILE *jlDataOpen(const char *name, const char *mode);

// ----- Writable save files (SAVES/) -----
//
// Save / preference data lives under a SAVES/ directory beside the executable
// -- a writable sibling of the read-only DATA/ tree. Names are relative to
// SAVES/: pass "hero.sav", not "SAVES/hero.sav". Keep names portable across
// the retro filesystems: at most 8 characters plus a short extension, letters
// and digits only, so they fit ProDOS (15-char) and DOS 8.3.
//
// A failed open / write is non-fatal and simply reports failure (false / 0),
// so save code can degrade gracefully on a platform or volume where SAVES/ is
// unavailable.

// Open a save file for streaming, name relative to SAVES/. mode is a standard
// fopen mode string; for write / append modes the SAVES/ directory is created
// on demand first. Returns NULL on failure. Use this for large or incremental
// saves; for a whole-file blob prefer jlSaveWrite / jlSaveRead.
FILE *jlSaveOpen(const char *name, const char *mode);

// Write `len` bytes from `buf` to save file `name`, replacing any existing
// contents. Returns true only if all `len` bytes were written.
bool jlSaveWrite(const char *name, const void *buf, uint32_t len);

// Read up to `max` bytes from save file `name` into `buf`. Returns the number
// of bytes read (0 if the file is missing or empty).
uint32_t jlSaveRead(const char *name, void *buf, uint32_t max);

// True if save file `name` exists and can be opened for reading.
bool jlSaveExists(const char *name);

// Delete save file `name`. Returns true if the file was removed.
bool jlSaveDelete(const char *name);

// ----- Disk space -----

// Free space, in bytes, on the volume that holds SAVES/ (the program's
// volume). Returns 0 if it cannot be determined (e.g. the port has no query
// for it). Saturates at UINT32_MAX (4 GB - 1) on larger volumes.
uint32_t jlDiskFree(void);

#endif
