#ifndef BACK_CONSTS_H
#define BACK_CONSTS_H

typedef struct pt_2d {
    double x;
    double y;
    double z;
} pt_2d;

struct cube_0 {
    int red; int green; int blue;
    double x;
    double y;
    double z;
    double w;
    double h;
    double d;
    double hz_angle;
    double vt_angle;
};
typedef struct cube_0 cube_0;
typedef cube_0* cube;

typedef struct teleporter {
    cube_0* hitbox;
    int dest_chx;      // in the pool, these are offsets
    int dest_chy;
    double dest_x;
    double dest_y;
    double dest_z;
} teleporter;

typedef struct entity {
    int entity_type;
    cube_0* pos;
        // act as velocity function
    void (*updatePos)(double x, double y, double z, double w, double h, double d, double hz_angle, double vt_angle, float dtime, struct entity* ent, cube_0* ret);
        
        // triggers when object is hit
    void (*onHit)(float dtime, int* hp, int* dmg, struct entity* ent, cube_0* ret);

        // triggers when <hitpoints> goes negative (death)
    void (*onDeath)(float dtime);

    int metai1;
    int metai2;
    int metai3;
    int metai4;
    int metai5;
    int metai6;
    double metad1;
    double metad2;
    double metad3;
    double metad4;
    double metad5;
    double metad6;
    double metad7;
    double metad8;
    double metad9;
    char* metach1;
    char* metach2;

    int tex;
    int tex2;

    int damage;
    int* hitpoints;
} entity;

struct room {
    // (0, 0, 0) = bottom, left and down
    int chunk_x;
    int chunk_y;
    cube_0** map;
    int map_size;
    teleporter** tps;
    int tps_size;
    entity** ents;
    int ent_len;
    int ent_memlen;
};
typedef struct room room;

struct cell {
    int chx;
    int chy;
    room* area;
    struct cell* next;
};

typedef struct cell cell;
typedef struct cell* linkedList;

struct hashtbl_0 {
    int tabLength;
    int insertedElts;
    int maxInserted;
    linkedList* tab;
};
typedef struct hashtbl_0 hashtbl_0;
typedef hashtbl_0* hashtbl;

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

extern double sim_time;

extern double camx;
extern double camy;
extern double camz;

extern double camvx;
extern double camvy;
extern double camvz;

extern double friction;
extern double vtmult;
extern double gravity_factor;

extern double rot_hz;
extern double rot_vt;

extern double tan_fov;

extern bool has_changed;

extern hashtbl visited;
extern room* current_room;

extern int player_chx;
extern int player_chy;

extern int* drawOrder;

extern int coins;

extern int draw_type;

extern int player_hp;

extern int fade_dmg;

extern bool stop_evetything;
extern double room_width;
// no height yet (requires a rewrite oh hashtbl)
extern double room_depth;

// ---------------------------------------------------------------------------------------------------- //
extern double sensitivity;
extern double fov;
extern double speed;
extern double creative_speed;
extern double min_dist;
// ---------------------------------------------------------------------------------------------------- //

extern float vertices[180];
extern float rectDefault[18];

extern int triCount;

extern bool updateForces;

extern double fx;
extern double fy;
extern double fz;

extern int njumps;

extern unsigned int fffff;
extern unsigned int fShader;
extern int gamemode;

extern float incr;

extern char* newRoomName;
extern int newRoomCount;
extern bool switchRoom;

extern int loc_scale;
extern int loc_model;
extern int loc_view;
extern int loc_proj;

extern int loc_frag;
extern int loc_tex;

extern bool is_one_room;

extern unsigned int textures[16];

extern float dmgCD;
extern int lastDmg;

extern bool buttonSwitch[16];
extern float buttonTimes[16];

#endif