/**
 * @file 
 * File containing main() function
 */

#include "guihandler.h"

/** 
 * @mainpage SMLabyrinth
 * <IMG SRC="../../img/SMLabyrinth.png">
 This program is a complete version of a labyrinth game.

 The goal of the game is to reach the nearest door from the start point in all 
 the different levels, in order to gain an higher score.
 Every schema, in which the difficult increase compared to the increasing of 
 the number of the level, contain an unique start point and more doors.
 The player, to gain the highest score, has to reach with the minimum possible
 number of steps and in the minimum time, the nearest door. Once a schema is
 finished, it will be shown the gained score and then another schema will be
 reach until the completion of the all (10) levels. At the end of the game it
 will be possible to save the achieved record, in order to keep a record chart,
 displayable using the Options menu.
 The player can starts a new game using the entry "New game" from the File 
 menu, or open a single schema using the entry "Open game".

 The best route is estimate using the function ::bestroute, which uses a 
 recursive algorithm to locate the nearest door to the start point.

 In all the schemas, the cost of every step in the route has an unitary value 
 and the final score for each schema is calculated in following way:
 The percentage of correctness of a route made by a player is calculated with 
 this formula:
 \n perc = (num_step_best_routes) / (num_step_player) * 100
 \n If the rusultant percentage is longer or equals then a set value 
 (see default), a bonus (see default) is added to the final score. 
 Otherwise, it's possible to score a penality (see default).
 For the current level (current_level), the gained score is calculated with
 this formula:
 \n   points = ceil( current_level * ( bonus + perc ) / ( elapsed_time / ( 1 +
 SEC_PER_LEVEL * current_level ) + 1 ) ) 
 \n where elapsed_time correspons to the elapsed time to finisch the level and 
 SEC_PER_LEVEL (see default) to the maximum number of seconds allowed to finish
 the schema.

 The program is composed by the following modules:
 
 - SMLabyrinth.c, which contains the ::main class of the project and the 
    function ::showUsage_and_setTracingVerbosity;
 
 - guihandler.c, which contains all the code that create and manage the Graphic
    User Interface of the project, using the functionality offerd by the other 
    modules; list of functions that this module contains:
    ::gui, ::delete_event, ::new_tournament, ::drawschema, ::configure_event, 
    ::expose_event, ::draw_brush, ::keypressed, ::checkKeyPressed, 
    ::updateSchemaCell, ::win, ::show_records, ::get_player_name, 
    ::checkResponseNameError, ::drawingAndSetSchemaInfo, ::open_game, 
    ::generate_game, ::request_generate_parameters, 
    ::checkResponseErrorGenerateParameters, ::set_gtk_entry_text_from_num, 
    ::show_help, ::show_about; 
    
 - bestroute.c, which calculate the best route between a start point and the
    neatest door; list of functions that this module contains:
    ::bestroute, ::bestroute_check_in_data, ::schema_round_search, 
    ::reverse_route_length;
     
 - define.h, which includes all the data program definitions;
 
 - schemaGameUtility.c, containing the game utility functions; 
    list of functions that this module contains:
    ::newgame, ::checkRowColValues, ::setSchemaDataStructures, 
    ::checkDoorStartPoint, ::loadCheckGame, ::getdoors, 
    ::isDirectory, ::get_schema_name, ::isallowedchar,
    ::countDigits, ::check_if_text_is_number, ::calcSchemaResults.
 
 - schemaGameGenerator.c used to generate a schema with certains features
    inserted by users from GUI; list of functions that this module contains:
    ::generateSchema, ::check_generateSchema, ::gameMap_alloc_and_set,
    ::create_routes, ::get_denyArea, ::getRouteNumber, 
    ::set_number_of_available_cells, ::get_MaxRouteLen, 
    ::point_in_random_direction, ::get_direction_from_point,
    ::increase_schema_difficult, ::save_schema_to_file.
   
 - object.c, which includes all the functionality for manage the schema 
    objects. List of own functions:
    ::weight that return the weight of the request object; 
    ::isaccessible that check if the request object is accessible; 
    ::color that returns a string's pointer that contains the request
            object's color (used to schema objects); 
    ::colorVisited that returns a string's pointer that contains the request
                   object's color (used to mark cell along a route); 
    ::visitCell used to mark (with colors) the route made in the game.
 
 - gameIOManager.c, which includes the functions that works with Input/Output.
    It contains the following functions:
    ::readfile used to read data from files, especially dedicated to schemas,
    ::allocResetVariable, ::skipCharacters, ::readCharacters, 
    ::checkDifferentColLen, ::setGameRecordStructValue, ::readSetGameRecord,
    ::save_record used to save the users record in it's file,
    ::printschema that works only in debug mode; used to print the schemas
    on standard output.
   

 The dependences between the different 
 modules are shown in the following graph:                
 <IMG SRC="../../img/schema_modules.png">                

 The compiling process and the generation 
 of the documentation of the project are
 managed using the command <i>make</i>.

 @author  <A href="mailto:info[AT]pietris[DOT]net">private</A>, <A href="mailto:info[AT]pietris[DOT]net">MrC</A>
*/

/* Start function definition of SMLabyrinth module */

/** Using a bit mask (MASK) to activate specified function(s) 
    (Eg. 255 = all, ... ,3=D1 & D2, 2 = D2, 1 = D1 , 0 = none) 
    The value of MASK is set in ::main function and can be
    changed by user using appropriate command.
*/
unsigned int MASK = 1;

/**
    Function that show the program usage, invoked by command line.
    If no arguments, starts the graphic user interface.
    @return Positive value (true) if the user invokes the function with arguments.
            Negative value (false) otherwise.
*/
bool showUsage_and_setTracingVerbosity( int argc,   /**< The same of main
                                                         function (int)*/
                                        char **argv /**< The same of main 
                                                         function (char **)*/
                                      );


/** Main function of the program.
    Check if the user has invoked the program passing some kind of 
    arguments using the function ::showUsage_and_setTracingVerbosity,
    then exit. Otherwise, if the user has called the program
    without arguments start the ::gui function to generate the
    Graphic User Interface; user will decide later when exit.
*/
int main( int argc, char **argv )
{

  bool quit = showUsage_and_setTracingVerbosity( argc, argv );

  if( quit )
     return 0;

  assert( !quit );

#ifdef DEBUG
  printf("\n");
  if( MASK==0 )
   printf("DEBUG flag is active but no output will show (MASK = 0).\n\n");
  else
  {   
      printf("Debug output will show:");
      D1(printf("\n%s",ID1));
      D2(printf("\n%s",ID2));
      D3(printf("\n%s",ID3));
      D4(printf("\n%s",ID4));
      D5(printf("\n%s",ID5));
      D6(printf("\n%s",ID6));
      D7(printf("\n%s",ID7));
      D8(printf("\n%s",ID8));
  }
  D1(printf("\n***** START DEBUG OUTPUT ************************************\n"));
  D1(printf("\nmain function START\n"));
#endif

  gui( argc, argv ); // Initialize Graphic User Interface

#ifdef DEBUG    
  D1(printf("\nmain funtion END.\n\n"));
  D1(printf("\n***** END DEBUG OUTPUT ************************************\n\n"));
#endif

  return 0;
}



bool showUsage_and_setTracingVerbosity( int argc, char **argv )
{   
    // Check arguments (if any)
    int i = 1;
    for(; i<argc; i++)
        if( ( strcmp( argv[i] , "-h") == 0 )        ||
            ( strcmp( argv[i] , "--help") == 0 )
          ){
                printf("\n\nRead README for more informations.\n"\
                       "Use the options -n to show program usage.\n\n");
                return true;
        }
        else
        if( ( strcmp( argv[i] , "-v") == 0 )        ||
            ( strcmp( argv[i] , "--version") == 0 )
          ){
                printf("\n\nVersion: %s\n\n",PRGVERS);
                return true;
        }
        else
        if( ( strcmp( argv[i] , "-l") == 0 )        ||
            ( strcmp( argv[i] , "--license") == 0 )
          ){
                printf("\n\nLicense:\n\n%s\n\n",PRGLICS);
                return true;
        }    
        else
        if( ( strcmp( argv[i] , "-c") == 0 )        ||
            ( strcmp( argv[i] , "--credits") == 0 ) 
          ){
                printf( "\n\nCredits:\n\n"\
                        "%s\n\n",PRGAUTH     );
                return true;
        }
        else
        if( ( strcmp( argv[i] , "-V") == 0 )        ||
            ( strcmp( argv[i] , "--verbosity") == 0 ) 
          ){
                double control = -1;
                if( argc <= (i+1) ){ // Needs an other argument
                    printf( "\n\nMissing argument [VALUE]!\n\n"\
                            "Please, show the program usage.\n\n" );

                    return true;
                }

                // Overcast to prevent a return value that exceed MASK type range
                control = atoi( argv[ i+1 ] );
                if( ( control < 0 ) || ( control > BITMASK_MAX ) ){
                    printf( "\n\nArgument [VALUE] (%.0lf) out of range (0-%u)!"\
                            "\n\n",             control,         BITMASK_MAX );

                    return true;
                }

                assert( ( control >= 0 ) && ( control <= BITMASK_MAX ) );

                MASK = (unsigned int)control;

                return false; // Program must start
        }
        else
        {
            printf("\n\n"\
                   "%s v%s\n%s\n"\
                   "%s\n%s\n\n"\
                   " Usage: %s [OPTION]\n\n"\
                   " Default (no options and no values):\n"\
                   "                      Run the program using the Graphic User Interface\n"\
                   "                      and default tracing verbosity level (%u).\n\n"\
                   " OPTIONS:\n"\
                   "   -V [VALUE],\n"\
                   "   --verbosity [VALUE]  : Set tracing verbosity level\n"\
                   "                          to [VALUE] (0-%u) and run\n"\
                   "   -v, --version        : Display program version\n"\
                   "   -l, --license        : Display program license\n"\
                   "   -h, --help           : Display a little help\n"\
                   "   -c, --credits        : Display program credits\n"\
                   "   -n, *                : Display this informations\n\n"\
                   "   * = all parameters except just showed.\n\n"
                   ,PRGNAME, PRGVERS, PRGCPYR
                   ,PRGAIMS, PRGWBLK
                   ,argv[0]
                   ,MASK
                   ,BITMASK_MAX
                  );
            return true;
        }
   
   // There aren't arguments except the first (name of executable) 
   return false;
}

/* End function definition of SMLabyrinth module */

