#ifndef CONSTS_H
#define CONSTS_H

// ------------------------------------------------------------------------ //
// SDL-related struct

typedef struct imgs {
    int len; 
    SDL_Texture** arr;
} imgs;

// ------------------------------------------------------------------------ //
// car shenanigans
typedef struct pt_t {int ix; int iy;} pt;

typedef struct ptf_t {double fx; double fy;} ptf;

typedef struct car_t car;

// unused for now
typedef struct item_t {
    const char* name;
    void (*onCollect)(car* user);
    void (*onUse)(car* user);
} item;

typedef struct car_t {
    ptf pos;                // remains in [0, ROOM_SIZE[
    ptf lastPos;            // last static position for the car (used when barriers are off)
    int chx;
    int chy;
    int lastChx;
    int lastChy;
    ptf vel;
    int nCoins;
    item* itm; // either NULL or a pointer to an item
} car;

// ------------------------------------------------------------------------ //
// (take a) map
typedef struct color_t {
    uint8_t red;
    uint8_t green;
    uint8_t blue;
} color;

// one chunk
typedef enum road_t {NONE, START, END, STR_V, STR_H, TURN_NE, TURN_SE, TURN_SW, TURN_NW, STR_VB, STR_HB} road;

typedef struct level_t {
    int lines;
    int cols;
    road** map;
} level;

// global car data
typedef struct carData_t {
    car* c;
    color rgb;
} carData;

// meta
typedef struct next_t {int dx; int dy; int deep;} next;

// path
typedef struct path_t {
    int lines;
    int cols;
    pt start;
    int maxDepth;
    double maxD;
    double singleDist;
    next** nxts;
} path;

// ------------------------------------------------------------------------ //
extern imgs* digits;        // SDL data
extern imgs* letters;       // SDL data

extern int currentTurn;     // name explains

extern carData* players;    // contains each player and its corresponding data
extern int nPlayers;        // size of players

extern bool* offTheMap;     // offTheMap[p] = true <==> the player p is off the map (groundbreaking I know)
// ------------------------------------------------------------------------ //
// constants
extern const int WIDTH;
extern const int HEIGHT;

extern const int ROOM_SIZE;
extern const int MAX_SPEED;

extern const double STR2_W;

extern int START_CHX;
extern int START_CHY;
extern int FINISH_CHX;
extern int FINISH_CHY;
extern int START_DIR;       // (0, 1, 2, 3) = (N, E, S, W)
extern const int MAX_THETA_SPAWN;

extern const int PLAYER_R;  // radius

extern const double DIST_EDGE;
extern const double START_EDGE;
extern const double RESTITUTION_WALL;
extern const double RESTITUTION_PLAYER;
extern const int BARRIERS;
extern const int ONEATATIME;
extern const double BARRIER_WIDTH;

extern const double FRICTION;
extern const double DV;
extern const double DT;
extern const double EPSILON;

extern const double DELTA_V;
extern const double DELTA_THETA;

extern int* winners;
extern int nextRank;
extern int remainingTurns;
extern double* remainingD;
extern double minRemD;
extern double maxRemD;

extern const double WIND_X;
extern const double WIND_Y;

extern double B;

// -------------------------------------------------------------------------------- //

void write_output(char* stream, level* lvl, int nPl);
void updateLeaderBoard(char** execs, int* ranks);

#endif