#ifndef GREMLIN_GAME_H
#define GREMLIN_GAME_H

#include "common.h"

typedef struct team_t team_t;
typedef struct player_t player_t;
typedef struct game_t game_t;

#define GAME_TEAM_COUNT 2
#define GAME_PLAYER_COUNT 64
#define GAME_BOMB_COUNT (GAME_PLAYER_COUNT * 5)
#define GAME_POINT_COUNT 50

struct player_t {
	uint16_t id;
	uint16_t status;
	double x, y, z;
	double rx, ry, rz, rw;
	double vx, vy, vz;
	team_t *team;
	uint16_t points;
};

struct bomb_t {
	uint8_t status;
	double x, y, z;
	double vx, vy, vz;
	double ttl;
};

struct point_t {
	uint8_t status;
	double x, y, z;
};

struct team_t {
	uint16_t id;
	double x, y, z;
	float color[4];
	uint16_t points;
	uint16_t wins;
};

struct game_t {
	team_t team[GAME_TEAM_COUNT];
	player_t player[GAME_PLAYER_COUNT];
	bomb_t bomb[GAME_BOMB_COUNT];
	point_t point[GAME_POINT_COUNT];
	int16_t max_player_id;
	int master;
	double updateTime;
	player_t *local_player;
	void(*explosion_callback)(double x, double y, double z, void *data);
	void *explosion_callback_data;
};

extern void game_setup(game_t *game);
extern void game_reset(game_t *game);
extern team_t *game_team_with_least_players(game_t *game);
extern player_t *game_spawn_player(game_t *game, team_t *team);
extern player_t *game_spawn_player_id(game_t *game, team_t *team, uint16_t id);
extern team_t *game_team(game_t *game, uint16_t id);
extern player_t *game_player(game_t *game, uint16_t id);
extern bomb_t *game_bomb(game_t *game, uint16_t index);
extern void game_update_players(game_t *game, double dt);
extern bomb_t *game_spawn_bomb(game_t *game);
extern point_t *game_spawn_point(game_t *game);
extern void game_update_bombs(game_t *game, double dt);
extern void game_update_points(game_t *game, double dt);
extern void game_update(game_t *game, double dt);
extern void game_setup_explosion_callback(game_t *game,
		void(*explosion_callback)(double x, double y, double z, void *data),
		void *data);
extern void game_set_master(game_t *game, int master);
#endif
