#ifndef HEADER_SCHEMAGAMEUTILITY
#define HEADER_SCHEMAGAMEUTILITY

/**
 * @file 
 * File containing the interface of schemaGameUtility module
 */


#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdbool.h>
#include <malloc.h>
#include <time.h>
#include <stdlib.h>
#include <limits.h>
#include <assert.h>
#include "define.h"
#include "gameIOManager.h"
#include "bestroute.h"


/* Start interface of schemaGameUtility module */

/** Number of the first level.*/
static const unsigned short int START_LEVEL = 1;
/** Number of points before start a tournament.*/
static const unsigned short int START_TOTAL_POINTS = 0;
/** Number of round before start a tournament.*/
static const unsigned short int START_ROUND_NUMBER = 1;


/** Data struct containing the game's state properties*/
struct stateOfGame{
    
    /** Current Row position in the game. */
    unsigned int currentRow;

    /** Current Column position in the game. */
    unsigned int currentCol;

    /** Minimum (or best) route in the game. */ 
    unsigned int bestrouteweight;

    /** Current number of visited cell in the game. */
    unsigned int iters;

    /** Current level in the tournament.*/
    unsigned short int currentlevel;
    
    /** Total points of the tournament.*/
    unsigned int totalpoints;

    /** Start time of current game.*/  
    unsigned long starttime;

    /** Says true if user is playing.*/              
    bool playing;

    /** Number of level in the tournament.*/
    unsigned short int numOfRound;
};


/* Definition of the type currentGameState.*/
typedef struct stateOfGame currentGameState;

/**
  * Initialize the variables in the data struct currentGameState.
*/
currentGameState initializeCurrentGameState();

/**
  * Start a new game, using ::loadCheckGame and ::bestroute functions. 
  * If debug mode is turned on use ::printschema function to print the schema.
  * @return execution time (double)
 */
double newgame( char schemafilename[],  /**< Name of the schema to start*/
                unsigned int *bestrouteweight /**< Best route weight*/
              );

/**
  * Checks if the number of rows and columns in the schema are corrects.
  * @return true if no errors occours
  *         false otherwise
*/
bool checkRowColValues( unsigned short int *errnum, /**< Number of errors*/
                        char *err                   /**< Error string message*/
                      );

/**
  * Set the values of the passed schema into the global 
  * variable schemaData.gameMap. Initialize also the global variable
  * schemaData.visitedCellInfo.
*/
void setSchemaDataStructures( char **schema_propr /**< Schema game map.*/
                            );

/**
  * Checks if the number of doors and start point are corrects.
*/
void checkDoorStartPoint( unsigned short int *errnum, /**< Number of errors*/
                          char *err                 /**< Error string message*/
                        );

/**
 * Function that uses the function ::readfile to get a vector of 
 * strings, which represent the data of the schema.
 * Store the read data in it's structure without memory loss.
 * @return number of error occurred (unsigned short int)
*/
unsigned short int loadCheckGame( char *file_name /**< Name of file 
                                                       that contains the game*/
                                );

                
/** Function that find all the DOORs in the schema
  * @return number of doors (unsigned int)  
*/
unsigned int getdoors(  unsigned int *doorsRow,  /**< Number of rows doors*/
                        unsigned int *doorsCol   /**< Number of column of the 
                                                   doors*/
                     );
  

/** Check if a path is a directory
    @return Negative value (false) if it isn't a directory or doesn't exist.
            Positive value (true) otherwise.
*/
bool isDirectory( char const *path /**< Path to check*/
                );


/** 
 *  Function that retrieval a schema name of specified level randomly
 *  @return Schema name (char *) 
*/
char *get_schema_name( unsigned short int level /**< Number of the level*/
                     );


/**
  * Function that checks if the character in input is allowed
  * Variable "selection" is used as bit mask.
  * Selection = 1 means characters from 'a' to 'z'
  * Selection = 2 means characters from 'A' to 'Z'
  * Selection = 4 means characters from '0' to '9'
  * Some other possible combination :
  *     - Selection = 3 means (2) and (1) (NB. 2+1=3)
  *     - Selection = 5 means (4) and (1) (NB. 4+1=5)
  *     - Selection = 6 means (4) and (2) (NB. 4+2=6)
  *     - Selection = 7 means (4) and (2) and (1) (NB. 4+2+1=7)
  *
  * @return Positive value (true) if the character is allowed.
            Negative value (false) otherwise.
*/
bool isallowedchar(unsigned short int typeCharSel , /**< Selection mask */
                   char char2check                  /**< Character to check*/
                  );

/**
  * Count number of digits of the variable "number"
  * @return number of digits
  */
inline unsigned int countDigits( unsigned int number /**< Number to analyze*/
                               );


/** Check if the passed text is composed by digits.
    If 'runme' is set to false the function skip
    the checks and return 'false'.
    @return true if pass the check, false otherwise
 */
bool check_if_text_is_number( const bool runme, /**< Execute the check*/
                              const char *text, /**< Text to check */
                              char *err_buff, /**< Error message */
                              const char *err_label /**< Label to put
                                                         into err_buff */
                            );
                            
/**
   Calculate the schema results (correctness, bonus, time, points)
   and print them into labeltxt.
*/
unsigned int calcSchemaResults( char *labeltxt,/**< Schema results output*/
                                currentGameState gameState /**< State of game*/
                              );

/* End interface of schemaGameUtility module */

#endif
