#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <cairo.h>
#include "common.h"
#include "sprite.h"
// globals
extern cairo_t *heliCairo;
// string
char* heliStringCopy(const char *x);
char* heliStringConcat3(const char *a, const char *b, const char *c);
int heliStringEndsWithLowcase(const char *s, const char *tail);
void heliLowercase(char *x);
void heliParseColor(const char *x, double *color);
// pointer array
typedef void (*HeliFreeCallback)(void*);
typedef struct _HeliPair {
void *key;
void *value;
HeliFreeCallback freeKey;
HeliFreeCallback freeValue;
} HeliPair;
typedef struct _HeliArray {
HeliPair *items;
int count;
int allocated;
} HeliArray;
void heliPairInit(HeliPair *p);
void heliPairDestroy(HeliPair *p);
void heliArrayInit(HeliArray *a);
void heliArrayClear(HeliArray *a);
void heliArrayDestroy(HeliArray *a);
HeliPair* heliArrayGet(HeliArray *a, int i);
void* heliArrayGetKey(HeliArray *a, int i);
void* heliArrayGetValue(HeliArray *a, int i);
HeliPair* heliArrayInsert(HeliArray *a, int i, void *v, HeliFreeCallback fv);
HeliPair* heliArrayInsertPair(HeliArray *a, int i, void *k, void *v, HeliFreeCallback fk, HeliFreeCallback fv);
void heliArrayRemove(HeliArray *a, int i);
HeliPair* heliStringmapFind(HeliArray *a, const char *k, int *gtOrEqIndex);
HeliPair* heliStringmapGet(HeliArray *a, const char *k);
HeliPair* heliStringmapAdd(HeliArray *a, const char *k, void *v, HeliFreeCallback fv);
int heliStringmapRemove(HeliArray *a, const char *k);
// animation
typedef struct _HeliAnimation {
char *path;
HeliArray frames;
int refcount;
} HeliAnimation;
HeliAnimation *heliCreateAnimation(const char *path);
void heliAnimationUnref(HeliAnimation *a);
void heliAnimationFinish();
// collider
typedef struct _HeliCollider {
Collider type;
double x;
double y;
double radius;
double width;
double height;
double rotation;
} HeliCollider;
int heliCheckCollision(HeliCollider *a, HeliCollider *b, double *normX, double *normY);
int heliPointCollision(HeliCollider *c, double x, double y);
// sprite
typedef void (*HeliSpriteEashInt)(Sprite, int);
typedef void (*HeliSpriteEashDouble)(Sprite, double);
typedef void (*HeliSpriteEashString)(Sprite, const char*);
HeliArray* heliSpriteGetGroups(Sprite sprite);
void heliSpriteUpdate(double dt);
void heliSpriteFinish();
// drawing
void heliDrawingClearFrame(cairo_t *cr);
void heliDrawingPrepareFrame();
void heliDrawingFinish();
// sound
void heliSoundUpdate();
void heliSoundFinish();
// test
void heliDoTests();