
typedef struct Camera Camera;
struct Camera {
    Vec2 zoom;
    Vec2 pos;
    Vec2 target_pos;
    Vec2 wheel;
};

typedef int VIS_Prototypes;
enum {
    VIS_Prototypes_Plot,
    VIS_Prototypes_TextEditor,
    VIS_Prototypes_DataHandling,
    VIS_Prototypes_Audio,
    VIS_Prototypes_Count,
};

struct MAP_Entry {
    MAP_Entry *next;
    void *pointer;
    uint64_t hash;
    uint64_t key;
};

struct MAP_Map {
    MAP_Entry *entries;
    int entry_count;
    int occupied_entry_count;
};

MAP_Entry *MAP_GetOrInsert(MA_Arena *arena, MAP_Map *map, uint64_t key) {
    if (map->entries == 0) {
        map->entry_count = 4096;
        map->entries = MA_PushArray(arena, MAP_Entry, map->entry_count);
    }

    uint64_t hash = HashBytes(&key, sizeof(key));
    if (hash == 0) hash += 1;

    int index = WRAP_AROUND_POWER_OF_2(hash, map->entry_count);
    MAP_Entry *it = map->entries + index;
    for (;;) {
        if (it->hash == 0) {
            it->key = key;
            it->hash = hash;
            map->occupied_entry_count += 1;
            return it;
        }
        if (it->hash == hash && it->key == key) {
            return it;
        }
        if (it->next == 0) {
            if (arena) {
                it->next = MA_PushStruct(arena, MAP_Entry);
            }
            else break;
        }
        it = it->next;
    }
    return 0;
}

S8_String VIS_GetString(uint32_t offset) {
    S8_String result = S8_MakeEmpty();
    VIS_String *str = (VIS_String *)VIS_Get(offset);
    if (str) {
        result.str = str->str;
        result.len = str->len;
    }
    return result;
}
