#ifndef GLERMINAL_H
#define GLERMINAL_H

#include <glerminal-config.h>

#ifdef __cplusplus
extern "C"
{
#endif

typedef void (*glerminal_init_cb)();
typedef void (*glerminal_main_cb)(double dt);
typedef void (*glerminal_keys_cb)(int key);
typedef void (*glerminal_mousemoved_cb)(double x, double y);
typedef void (*glerminal_mousepress_cb)(int button, double x, double y);

typedef struct {
 glerminal_init_cb init;
 glerminal_main_cb main;
 glerminal_keys_cb keypress, keyrelease;
 glerminal_mousemoved_cb moved;
 glerminal_mousepress_cb mousepress, mouserelease;
} glerminal_init_params;

/**
 * @brief Call init once, then run the application's mainloop
 * @param params Initialization parameters
 */
void glerminal_run(glerminal_init_params params);

void glerminal_quit();

/**
 * @brief Update the displayed screen contents to the current state of the library
 */
void glerminal_flush();

/**
 * @brief Set a cell's sprite
 * @param x position of the cell in the range [0, GRID_WIDTH)
 * @param y position of the cell in the range [0, GRID_HEIGHT)
 * @param layer layer of the cell in the range [0, LAYER_COUNT)
 * @param sprite sprite's index in the range [0, 4096)
 */
void glerminal_set(int x, int y, int layer, unsigned short sprite);
/**
 * @brief Get a cell's sprite
 * @param x position of the cell in the range [0, GRID_WIDTH)
 * @param y position of the cell in the range [0, GRID_HEIGHT)
 * @param layer layer of the cell in the range [0, LAYER_COUNT)
 * @return sprite index currently assigned to the cell
 */
unsigned short glerminal_get(int x, int y, int layer);
/**
 * @brief Set a cell's offset
 * @param x position of the cell in the range [0, GRID_WIDTH)
 * @param y position of the cell in the range [0, GRID_HEIGHT)
 * @param layer layer of the cell in the range [0, LAYER_COUNT)
 * @param x_offset offset of the cell on the x axis in cells
 * @param y_offset offset of the cell on the y axis in cells
 */
void glerminal_offset(int x, int y, int layer, float x_offset, float y_offset);

/**
 * @brief Set a cell's color
 * @param x position of the cell in the range [0, GRID_WIDTH)
 * @param y position of the cell in the range [0, GRID_HEIGHT)
 * @param layer layer of the cell in the range [0, LAYER_COUNT)
 * @param color The new color
 */
void glerminal_color(int x, int y, int layer, unsigned int color);
/**
 * @brief Set a cell's scale
 * @param x position of the cell in the range [0, GRID_WIDTH)
 * @param y position of the cell in the range [0, GRID_HEIGHT)
 * @param layer layer of the cell in the range [0, LAYER_COUNT)
 * @param scale The new scale
 */
void glerminal_scale(int x, int y, int layer, float scale);

/**
 * @brief Load sprites from a png file
 * @param filename Name of the png file
 */
int glerminal_load_sprites_file(const char* filename);

/**
 * @brief Load sprites from memory
 * @param width width of the atlas in sprites
 * @param height height of the atlas in sprites
 * @param buffer the in-memory atlas
 */
int glerminal_load_sprites_buffer(unsigned char width, unsigned char height, const unsigned int* buffer);

void glerminal_sound(const char* name);

#ifdef __cplusplus
}
#endif

#endif//GLERMINAL_H