// The MIT License (MIT)
//
// Copyright (C) 2026 Scott Duensing
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

// dvxRes.h  -- DVX resource format and runtime API
//
// Resources are appended to DXE3 files (.app, .wgt, .lib) after the
// normal DXE content. dlopen never reads past the DXE header-specified
// sections, so the appended data is invisible to the loader.
//
// File layout:
//   [DXE3 content]           -- untouched, loaded by dlopen
//   [resource data entries]  -- sequential, variable length
//   [resource directory]     -- fixed-size entries, one per resource
//   [footer]                 -- magic + directory offset + count
//
// Reading starts from the end: seek to EOF - sizeof(footer), verify
// the magic, then seek to the directory and read entries.

#ifndef DVX_RES_H
#define DVX_RES_H

#include <stdint.h>

#include "dvxPlat.h"

// Resource type IDs
#define DVX_RES_ICON     1   // image data (BMP icon: 16x16, 32x32, etc.)
#define DVX_RES_TEXT     2   // null-terminated string (author, copyright, etc.)
#define DVX_RES_BINARY   3   // arbitrary binary data (app-specific)

// Footer magic: "DVXR" as a 32-bit little-endian value
#define DVX_RES_MAGIC    0x52585644UL

// Maximum resource name length (including null terminator)
#define DVX_RES_NAME_MAX 32

// Directory entry (48 bytes each)
typedef struct {
    char     name[DVX_RES_NAME_MAX];  // resource name (e.g. "icon16", "author")
    uint32_t type;                    // DVX_RES_ICON, DVX_RES_TEXT, DVX_RES_BINARY
    uint32_t offset;                  // absolute file offset of data
    uint32_t size;                    // data size in bytes
    uint32_t reserved;                // padding for future use
} DvxResDirEntryT;

// Footer (16 bytes, at the very end of the file)
typedef struct {
    uint32_t magic;       // DVX_RES_MAGIC
    uint32_t dirOffset;   // absolute file offset of directory
    uint32_t entryCount;  // number of resources
    uint32_t reserved;
} DvxResFooterT;

// Runtime resource handle (opaque to callers)
typedef struct {
    char              path[DVX_MAX_PATH];
    DvxResDirEntryT  *entries;
    uint32_t          entryCount;
} DvxResHandleT;

// Open a resource handle by reading the footer and directory.
// Returns NULL if the file has no resource block.
DvxResHandleT *dvxResOpen(const char *path);

// Find a resource by name and read its data into a malloc'd buffer.
// Sets *outSize to the data size. Returns NULL if not found.
// Caller must free the returned buffer.
void *dvxResRead(DvxResHandleT *h, const char *name, uint32_t *outSize);

// Find a resource by name and return its directory entry.
// Returns NULL if not found. The returned pointer is valid until
// dvxResClose is called.
const DvxResDirEntryT *dvxResFind(DvxResHandleT *h, const char *name);

// Close the handle and free all associated memory.
void dvxResClose(DvxResHandleT *h);

// Append a resource to an existing DXE file.
// Preserves existing resources and adds the new one.
// Returns 0 on success, -1 on error.
int32_t dvxResAppend(const char *path, const char *name, uint32_t type, const void *data, uint32_t dataSize);

// Remove a resource by name from a DXE file.
// Returns 0 on success, -1 on error (not found or I/O failure).
int32_t dvxResRemove(const char *path, const char *name);

#endif // DVX_RES_H
