#ifndef BREEZE_ARRAY_H
#define BREEZE_ARRAY_H

#include "../defines.h"

void *_bzArrayCreate(i32 startCapacity, i32 stride);
void _bzArrayDestroy(void *arr);
void _bzArrayClear(void *arr);

i32 _bzArraySize(void *arr);
i32 _bzArrayCapacity(void *arr);

void *_bzArrayResize(void **arr, i32 newSize);
void *_bzArrayEnsureCapacity(void **arr, i32 capacity);

i32 _bzArrayGet(void *arr, i32 idx);
void _bzArrayDelN(void *arr, i32 idx, i32 n);

i32 _bzArrayPush(void *arr);
i32 _bzArrayIns(void *arr, i32 idx);
i32 _bzArraySet(void *arr, i32 idx);
i32 _bzArrayPop(void *arr);

#define bzArrayCreate(T, n) (T*) _bzArrayCreate(n, sizeof(T))
#define bzArrayDestroy(arr) do {                                \
    _bzArrayDestroy(arr);                                       \
    arr = NULL;                                                 \
} while(0)
#define bzArrayClear(arr) _bzArrayClear(arr)

#define bzArraySize(arr) _bzArraySize(arr)
#define bzArrayCapacity(arr) _bzArrayCapacity(arr)

#define bzArrayResize(arr, size) _bzArrayResize((void **) &arr, size)
#define bzArrayEnsureCapacity(arr, capacity) _bzArrayEnsureCapacity((void **) &arr, capacity)

#define bzArrayGet(arr, idx) (arr)[_bzArrayGet(arr, idx)]
#define bzArrayDel(arr, idx) _bzArrayDelN(arr, idx, 1)
#define bzArrayDelN(arr, idx, n) _bzArrayDelN(arr, idx, n)

#define bzArrayPush(arr, e)                                     \
do {                                                            \
    (arr) = bzArrayEnsureCapacity(arr, bzArraySize(arr) + 1);   \
    (arr)[_bzArrayPush(arr)] = (e);                             \
} while (0)
#define bzArrayIns(arr, idx, e)                                 \
do {                                                            \
    (arr) = bzArrayEnsureCapacity(arr, bzArraySize(arr) + 1);   \
    (arr)[_bzArrayIns(arr, idx)] = (e);                         \
} while (0)
#define bzArraySet(arr, idx, e) (arr)[_bzArraySet(arr, idx)] = e
#define bzArrayPop(arr) (arr)[_bzArrayPop(arr)]

#define bzArrayFor(arr, it) for (i32 it = 0; it < bzArraySize(arr); it++)

#endif //BREEZE_ARRAY_H
