#ifndef GAME_H
#define GAME_H


#include <gint/display.h>
#include <stdint.h>

#include "events.h"



/* The direction where the player is going to. */
typedef enum {
    D_UP,
    D_DOWN,
    D_LEFT,
    D_RIGHT
} Direction;

typedef enum {
    P_LEFTUP = -1,
    P_CENTER = 0,
    P_RIGHTDOWN = 1
} Checkpos;



/* Struct that define player parameters */
typedef struct {
    int16_t x, y; /* The position of the player int the current map */
    uint16_t px, py; /* The position of the player on screen */
    int16_t wx, wy; /* position of the player in the world */
    int8_t life; /* How many lives the player still has between 0 and 100. */
    int8_t speed; /* The speed of the movement of the player. */


    /* set to true if a action can be done in the current position of the map */
    bool canDoSomething; 
    /* indicates which data are relevant to the current action in the */
    /* extradata layer of the map */
    int32_t whichAction; 
    /* the player is doing something */
    bool isDoingAction;
    /* the player is interacting with a NPC */
    bool isInteractingWithNPC;
} Player;


typedef struct {
    uint32_t ID;
    /* data to be shown in the dialog*/
    char *dialog;
    /* is it a question or a simple dialog ? */
    uint32_t isQuestion;
    /* if it is a question, then the choices for answering */
    char *choices;
    /* the conclusion of the dialog for answer 1 and 2 respectively */
    /* Note : it may contain a set of event with a dedicated syntax */
    char *conclusion1;
    int32_t next1;
    char *conclusion2;
    int32_t next2;
    int32_t nextOther;
} Dialog;


typedef struct {
    /* position of the item */
    uint32_t x;
    uint32_t y;
    /* its name */
    char *name;
    /* its class (NPC, SGN, INFO, ... )*/
    char *type;

    /* the ID of the first element of the dialog */
    /* (to be aligned with "dialogs.json" IDs)*/
    uint32_t dialogID;
    /* 0 if imperative dialog (story mode) */
    /* or 1 if the player need to press [SHIFT] to initiate the sequence*/
    uint32_t needAction;

    /* data for NPC's trajectories */
    uint32_t hasPath;
    uint32_t path_length;
    int16_t *xpath;
    int16_t *ypath;

    /* ... this can be extended as per needs ... */
} ExtraData;


typedef struct {
    /* width, height and the number of layer of the map */
    uint32_t w;
    uint32_t h;
    uint32_t nblayers;
    uint32_t tileset_size;

    /* world coordinates of the upper left and bootom right*/
    /* corners of the current map to be multiplied in game by PXSIZE */
    uint32_t xmin;
    uint32_t ymin;
    uint32_t xmax;
    uint32_t ymax;

    /* the tileset to use */
    bopti_image_t *tileset;

    /* contain the properties of the tiles */
    /* this is given by the layer Walkable of the map in Tiled */
    uint8_t *walkable;

    /* structure that contains all the items on the map to interract with */
    /* each portion of the map has its own list to avoid scrutinizing too much */
    /* data when lloking for proximity of items */
    uint32_t nbextradata;
    ExtraData *extradata;

    /* structure that contains all the dialogs for that part of the map */
    uint32_t nbdialogsdata;
    Dialog *dialogs;

    /* list of all the tiles to draw the background and the foreground layers */
    uint16_t *layers[];
} Map;



/* This struct will contain all the data of the game. It will make it possible
 * to pass it to the NPCs to let them interact with the player and the rest of
 * the world. */
typedef struct {
    Map *map_level; /* The level that the player is currently playing */
    Player player; /* The player data. */
    EventHandler handler; /* The event handler (see events.h). */
    /* Some global variables */
    /* Set to true when asked for exit */
    bool exittoOS;
    /* Set to true when screenshot is required */
    bool screenshot;
    /* Set to true when recording a video of the screen is required */
    bool record;
    /* How many ms the frame already took. */
    long int frame_duration;

    /* variables used for debuging */
    bool debug_map;
    bool debug_player;
    bool debug_extra;

    int mana; /* Only for testing events TODO: Remove this! */
} Game;

/* (Mibi88) TODO: Describe what this function is doing. */
void game_logic(Game *game);

/* Draws everything on screen. */
void draw(Game *game);

/* This render a small sign on the upper lecft corner of the screen */
/* if the player can do an action */
void render_indicator(Game *game);

/* Handle key presses. */
void get_inputs(Game *game);

#endif