#ifndef SPRITE_H
#define SPRITE_H

#include "util.h"

struct renderer_startup_receipt;
struct resource_startup_receipt;

/* ========================== *
 * Startup
 * ========================== */

struct sprite_startup_receipt { i32 _; };
struct sprite_startup_receipt sprite_startup(struct renderer_startup_receipt *renderer_sr,
                                             struct resource_startup_receipt *resource_sr);

/* ========================== *
 * Tag
 * ========================== */

struct sprite_tag sprite_tag_from_path(struct string path);
b32 sprite_tag_is_nil(struct sprite_tag tag);
b32 sprite_tag_eq(struct sprite_tag t1, struct sprite_tag t2);

/* ========================== *
 * Scope
 * ========================== */

struct sprite_scope {
    struct sprite_scope_reference **reference_buckets;
    struct sprite_scope *next_free;
};

struct sprite_scope *sprite_scope_begin(void);
void sprite_scope_end(struct sprite_scope *scope);

/* ========================== *
 * Texture
 * ========================== */

struct sprite_texture {
    b32 loaded;
    b32 valid;
    struct renderer_handle renderer_handle;
    u32 width;
    u32 height;
};

struct sprite_texture *sprite_texture_from_tag_await(struct sprite_scope *scope, struct sprite_tag tag);
struct sprite_texture *sprite_texture_from_tag_async(struct sprite_scope *scope, struct sprite_tag tag);

/* ========================== *
 * Sheet
 * ========================== */

struct sprite_sheet {
    b32 loaded;
    b32 valid;
    struct v2 image_size;
    struct v2 frame_size;
    u32 frames_count;
    struct sprite_sheet_frame *frames;
    u32 spans_count;
    struct fixed_dict spans_dict;
};

struct sprite_sheet_span {
    struct string name;
    u32 start;
    u32 end;
};

struct sprite_sheet_frame {
    u32 index;
    f64 duration;
    struct clip_rect clip;
};

/* Load */
struct sprite_sheet *sprite_sheet_from_tag_await(struct sprite_scope *scope, struct sprite_tag tag);
struct sprite_sheet *sprite_sheet_from_tag_async(struct sprite_scope *scope, struct sprite_tag tag);

/* Index */
struct sprite_sheet_span sprite_sheet_get_span(struct sprite_sheet *sheet, struct string name);
struct sprite_sheet_frame sprite_sheet_get_frame(struct sprite_sheet *sheet, u32 index);

#endif
