#pragma once

// previous node in a doubly linked list
.entity list_prev;
// next node in a linked list
.entity list_next;

entity minigame_get_descriptor(string id);

// Get letter index of a tile name
int minigame_tile_letter(string id);

// Get number index of a tile name
// Note: this is 0 based, useful for mathematical operations
// Note: Since the tile notation starts from the bottom left,
//	you may want to do number_of_rows - what_this_function_returns or something
int minigame_tile_number(string id);

// Get relative position of the center of a given tile
vector minigame_tile_pos(string id, int rows, int columns);

// Get a tile name from indices
string minigame_tile_buildname(int letter, int number);

// Get the id of a tile relative to the given one
string minigame_relative_tile(string start_id, int dx, int dy, int rows, int columns);

// Get tile name from a relative position (matches the tile covering a square area)
string minigame_tile_name(vector pos, int rows, int columns);

// Get the next team number (note: team numbers are between 1 and n_teams, inclusive)
int minigame_next_team(int curr_team, int n_teams);

// Get the previous team number
int minigame_prev_team(int curr_team, int n_teams);

// set send flags only when on server
// (for example in game logic which can be used both in client and server
void minigame_server_sendflags(entity ent, int mgflags);

// count the number of players in a minigame session
int minigame_count_players(entity minigame);

/// For minigame sessions: minigame descriptor object
.entity descriptor;

/// For minigame sessions/descriptors: execute the given event
/// Client events:
/// 	mouse_moved(vector mouse_pos)
///			return 1 to handle input, 0 to discard
/// 	mouse_pressed/released(int K_Keycode)
///			return 1 to handle input, 0 to discard
/// 		note: see dpdefs/keycodes.qc for values
/// 	key_pressed/released(int K_Keycode)
/// 		return 1 to handle input, 0 to discard
/// 		note: see dpdefs/keycodes.qc for values
/// 	activate()
/// 		executed when the minigame is activated for the current client
/// 	deactivate()
/// 		executed when the minigame is deactivated for the current client
/// 	network_receive(entity received,int flags)
/// 		executed each time a networked entity is received
/// 		note: when this is called self == ...(0,entity)
/// 		You can use the MINIG_SF_ constants to check the send flags
/// 		IMPORTANT: always read in client everything you send from the server!
/// 	menu_show(entity parent_menu_item)
/// 		executed when the Current Game menu is shown, used to add custom entries
/// 		Call HUD_MinigameMenu_CustomEntry to do so (pass ...(0,entity) as first argument)
/// 	menu_click(string arg)
/// 		executed when a custom menu entry is clicked
/// Server events:
/// 	start()
/// 		executed when the minigame session is starting
/// 	end()
/// 		executed when the minigame session is shutting down
/// 	join(entity player)
/// 		executed when a player wants to join the session
/// 		return the player team number to accept the new player, 0 to discard
/// 	part(entity player)
/// 		executed when a player is going to leave the session
/// 	network_send(entity sent,int flags)
/// 		executed each time a networked entity is sent
/// 		note: when this is called self == ...(0,entity)
/// 		You can use the MINIG_SF_ constants to check the send flags
/// 		IMPORTANT: always read in client everything you send from the server!
/// 	cmd(entity minigame_player, int argc, string command)
/// 		self = client entity triggering this
/// 		argv(n) = console token
/// 		argc: number of console tokens
/// 		command: full command string
/// 		triggered when a player does "cmd minigame ..." with some unrecognized command
/// 		return 1 if the minigame has handled the command
/// 	impulse(entity minigame_player,int impulse)
/// 		self = client entity triggering this
/// 		triggered when a player does "impulse ..."
/// 		return 1 if the minigame has handled the impulse
.int(entity,string,...)   minigame_event;

// For run-time gameplay entities: Whether to be removed when the game is deactivated
.bool minigame_autoclean;

// For run-time gameplay entities: some place to store flags safely
.int minigame_flags;

// Send flags, set to .SendFlags on networked entities to send entity information
// Flag values for customized events must be powers of 2 in the range
// [MINIG_SF_CUSTOM, MINIG_SF_MAX] (inclusive)
const int MINIG_SF_CREATE  = 0x01; // Create a new object
const int MINIG_SF_UPDATE  = 0x02; // miscellaneous entity update
const int MINIG_SF_CUSTOM  = 0x10; // a customized networked event
const int MINIG_SF_MAX     = 0x80; // maximum flag value sent over the network
const int MINIG_SF_ALL     = 0xff; // use to resend everything


// Spawn linked entity on the server or local entity on the client
// This entity will be removed automatically when the minigame ends
entity msle_spawn(entity minigame_session, entity e);

#include "minigame/all.qh"

int msle_id(string class_name);
string msle_classname(int id);
