/***************************
 * Fantasy Grand Prix v2.0 *
 *   © 1994 Simon Austin   *
 ***************************/

/* Includes */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

/* Defines */

#define DRIVERS 100
#define CHASSIS 50
#define ENGINES 50
#define MAXTEAM 100

/* Variables */

char *ver = "$VER: FGP v2.10 (18/9/94) © S Austin"; /* Amiga Version String */
char *verst = "FGP2 by S Austin, additional design by J Simpson.\n";
char *errst = "Usage: FGP <[-r[n]] [-t[n]] [-d[n]] [filename]>\n";

FILE *data_file, *teams_file, *scores_file, *drivers_file, *old_scores,
     *chassis_file, *engine_file; /* Pointers to various files */

FILE *grid_file, *results_file, *other_file; /* Old data file pointers */

char data_name[256], grid_name[256], results_name[256], other_name[256];

char *teams_name = "teams.fgp2", *scores_name = "scores.fgp2", 
     *drivers_name = "drivers.fgp2", *chassis_name = "chassis.fgp2",
     *engine_name = "engine.fgp2", *temp_name = "_tempscores";

char store[100], car[100], eng[100], fullname[100], name[100], fnam[100],
     racename[100], code[4], racecheck[100];
 
char owner[MAXTEAM][100], teamname[MAXTEAM][100], namea[DRIVERS][100],
     fnama[DRIVERS][100], chassisa[CHASSIS][100], enginesa[ENGINES][100],
     racenames[16][100];

int  highest, highscore; /* used to produce league table */

int  driver1[MAXTEAM], driver2[MAXTEAM], driver3[MAXTEAM], 
     chassis[MAXTEAM],engine[MAXTEAM], scores[MAXTEAM], thisrce[MAXTEAM]; 
                                            /* Team details */

int  eflags[ENGINES], cflags[CHASSIS], sflags[MAXTEAM]; 
                                     /* Flags for points calculation */

int  grid[DRIVERS], position[DRIVERS], status[DRIVERS], warmup[DRIVERS], 
     nominated, finisher, qualifier; /* Results */

int  topsixpts[DRIVERS], awardpts[DRIVERS], incgridpts[DRIVERS],
     warmuppts[DRIVERS], racesc[DRIVERS], retirepts[DRIVERS],
     noqualpts[DRIVERS], carscr[CHASSIS], engscr[ENGINES],
     carpts[DRIVERS], engpts[DRIVERS]; /* Scores */

int  drcar[DRIVERS], dreng[DRIVERS], whichcar[DRIVERS], whicheng[DRIVERS]; 
                                   /* chassis/engine for each driver */

int  teamscores[MAXTEAM][16], driverscore[DRIVERS][16], 
     drivertotal[DRIVERS];

int  points[] = { 0, 10, 6, 4, 3, 2, 1 }; /* Points for pos' 1-6 */
  
int  last, nteams, ndrivers, i, j, k, pos, point, normal, teams, drive, 
     number, totwarm, exists_flag, racedrivers, old_grid, old_car, old_eng,
     maxdrivers, maxchassis, maxengines, nraces;

char state, nom; /* variables used to work out flags */
int  end, warm;

int  inlen = 80; /* Max input length */

void disperr(char *);
void errorinfile(char *, char *, int);
int driver2no(char *);
int chassis2no(char *);
int engine2no(char *);
int strcasencmp(char *, char *, int);
void capitalise(char *);
unsigned int readline(char *, int, FILE *);
  
main(int argc, char *argv[])
{ 
  if(argc < 2 || argc > 5)
  { 
    /* Incorrect command line, display message and quit */
    fputs(verst, stderr);
    fputs(errst, stderr);
    exit(0);
  }
  else
  {   
    /* clear output flags */
    normal = 255;
    teams = 255;
    drive = 255;
    strcpy(data_name, "no_name");
    
    for(i = 1; i < argc; i+=1)
    {
      if(!strcasencmp(argv[i], "-r", 2))
      { 
        if(normal == 255)
        {
          /* Normal output wanted */
          strncpy(argv[i], "00", 2);
          normal = atoi(argv[i]);
        }
        else
        {
          /* Incorrect command line, display message and quit */
          fputs(verst, stderr);
          fputs(errst, stderr);
          exit(0);
        }
      }
      else if(!strcasencmp(argv[i], "-t", 2))
      {
        if(teams == 255)
        {
          /* Teams output wanted */
          strncpy(argv[i], "00", 2);
          teams = atoi(argv[i]);
        }
        else
        {
          /* Incorrect command line, display message and quit */
          fputs(verst, stderr);
          fputs(errst, stderr);
          exit(0);
        }
      }
      else if(!strcasencmp(argv[i], "-d", 2))
      {
        if(drive == 255)
        {
          /* Driver output wanted */
          strncpy(argv[i], "00", 2);
          drive = atoi(argv[i]);
        }
        else
        {
          /* Incorrect command line, display message and quit */
          fputs(verst, stderr);
          fputs(errst, stderr);
          exit(0);
        }
      }
      else
      {
        if(!strcmp(data_name, "no_name"))
        {
          /* Set data filename */
          strcpy(data_name, argv[i]);
        }
        else
        {
          /* Incorrect command line, display message and quit */
          fputs(verst, stderr);
          fputs(errst, stderr);
          exit(0);
        }
      }
    }  
  }

  /* Clear arrays */
  for(i = 1; i < DRIVERS; i+=1)
  {
    grid[i] = 0;
    position[i] = 0;
    status[i] = 0;
    drcar[i] = 0;
    dreng[i] = 0;
    warmup[i] = 0;
    topsixpts[i] = 0;
    awardpts[i] = 0;
    incgridpts[i] = 0;
    warmuppts[i] = 0;
    retirepts[i] = 0;
    noqualpts[i] = 0;
    carpts[i] = 0;
    engpts[i] = 0;
    racesc[i] = 0;
  }
      
  for(i = 0; i <= CHASSIS; i+=1)
  {
    carscr[i] = 0;
  }
      
  for(i = 0; i <= ENGINES; i+=1)
  {
    engscr[i] = 0;
  }

  for(i = 0; i <= MAXTEAM; i+=1)
  {
    scores[i] = 0;
  }

  /* Read in chassis names */
  chassis_file = fopen(chassis_name, "r");
  if(chassis_file == 0)
  {
    disperr(chassis_name);
    exit(0);
  }
  
  i=1;
  readline(store, inlen, chassis_file);
  while(i <= CHASSIS && !feof(chassis_file))
  {
    strcpy(chassisa[i], store);
    readline(store, inlen, chassis_file);
    i+=1;
  }
  maxchassis = i-1;
  
  /* Read in engines names */
  engine_file = fopen(engine_name, "r");
  if(engine_file == 0)
  {
    disperr(engine_name);
    exit(0);
  }
  
  i=1;
  readline(store, inlen, engine_file);
  while(i <= ENGINES && !feof(engine_file))
  {
    strcpy(enginesa[i], store);
    readline(store, inlen, engine_file);
    i+=1;
  }
  maxengines = i-1;

  fclose(engine_file);

  /* Read in driver details */
  drivers_file = fopen(drivers_name, "r");
  if(drivers_file == 0)
  {
    disperr(drivers_name);
    exit(0);
  }
  
  i=1;
  readline(store, inlen, drivers_file);
  while(i <= DRIVERS && !feof(drivers_file))
  {
    strcpy(namea[i], store);
    readline(store, inlen, drivers_file);
    strcpy(fnama[i], store);
    readline(store, inlen, drivers_file);
    whichcar[i] = chassis2no(store);
    readline(store, inlen, drivers_file);
    whicheng[i] = engine2no(store);
    readline(store, inlen, drivers_file);
    i+=1;
  }
  maxdrivers = i-1;
  
  fclose(drivers_file);

  if(strcmp(data_name, "no_name") != 0)
  {
    /* Get details from data file */
    data_file = fopen(data_name, "r");
    if(data_file == 0)
    {
      /* file named on command line does not exist */
      /* try old style files */
      /* Produce names of three input files */
      strcpy(grid_name, data_name);
      strcat(grid_name, ".grid");
      strcpy(results_name, data_name);
      strcat(results_name, ".rslt");
      strcpy(other_name, data_name);
      strcat(other_name, ".xtra");

      /* Use root name of file as race name */
      strcpy(racename, data_name);

      /* open and parse starting grid file */
      grid_file = fopen(grid_name, "r");
      if(grid_file == 0)
      {
        disperr(grid_name);
        exit(0);
      }

      readline(store, inlen, grid_file);
      ndrivers = atoi(store);

      for(i = 1; i < ndrivers+1; i+=1)
      {
        readline(store, inlen, grid_file);
        grid[i] = driver2no(store);
        if(grid[i] == 0)
        {
          errorinfile(grid_name, "Unknown driver", i+1);
          exit(0);
        }
        drcar[i] = whichcar[grid[i]];
        dreng[i] = whicheng[grid[i]];
      }

      fclose(grid_file);
    
      /* open and parse other details file */
      other_file = fopen(other_name, "r");
      if(other_file == 0)
      {
        disperr(other_name);
        exit(0);
      }

      for(i = 1; i < 7; i+=1)
      {
        readline(store, inlen, other_file);
        number = driver2no(store);
        if(number == 0)
        {
          errorinfile(other_name, "Unknown driver", i);
          exit(0);
        }
        j = 0;
        do
        {
          j+=1;
        }
        while(grid[j] != number);
        warmup[j] = i;
      }
      readline(store, inlen, other_file);
      nominated = driver2no(store);
      if(nominated > maxdrivers)
      {
        errorinfile(other_name, "Illegal nominated driver", 7);
        exit(0);
      }
      readline(store, inlen, other_file);
      finisher = atoi(store);
      if(finisher > ndrivers)
      {
        errorinfile(other_name, "Illegal final classified driver", 8);
        exit(0);
      }
      readline(store, inlen, other_file);
      qualifier = atoi(store);
      if(qualifier > ndrivers)
      {
        errorinfile(other_name, "Illegal last qualified driver", 9);
        exit(0);
      }
      if(qualifier < finisher)
      {
        errorinfile(other_name, "Final classified/last qualified driver mismatch", 8);
        exit(0);
      }
      totwarm = 6;
  
      fclose(other_file);

      /* open and parse final results file */
      results_file = fopen(results_name, "r");
      if(results_file == 0)
      {
        disperr(results_name);
        exit(0);
      }

      for(i = 1; i < qualifier+1; i+=1)
      {
        readline(store, inlen, results_file);
        number = driver2no(store);
        if(number == 0)
        {
          errorinfile(results_name, "Unknown driver", i);
          exit(0);
        }
        j = 0;
        do
        {
          j+=1;
        }
        while(grid[j] != number);
        position[j] = i;
      }

      fclose(results_file);
  
      for(i = 1; i < ndrivers+1; i+=1)
      {
        if(position[i] <= finisher)
          status[i] = 1;
        if(position[i] > finisher && position[i] <= qualifier)
          status[i] = 2;
        if(position[i] == 0)
          status[i] = 3;
      }
    }
    else
    {
      /* read in name of race */
      readline(racename, inlen, data_file);
 
      i = 0;
      totwarm = 0;
      nominated = 0;
      readline(store, inlen, data_file);

      do
      {
        i+=1;
        grid[i] = driver2no(store);
        if(grid[i] == 0)
        {
          errorinfile(data_name, "Unknown driver", i*2);
          exit(0);
        }
        drcar[i] = whichcar[grid[i]];
        dreng[i] = whicheng[grid[i]];
      
        /* Check finished/retired/DNQ/dis-qualified flag */
        readline(store, inlen, data_file);
        sscanf(store, "%c %d %d %c", &state, &end, &warm, &nom);
       
        state = tolower(state);
        status[i] = 4;
        if(state == 'd')
          status[i] = 0;
        if(state == 'f')
          status[i] = 1;
        if(state == 'r')
          status[i] = 2;
        if(state == 'n')
          status[i] = 3;
        if(status[i] == 4)
        {
          errorinfile(data_name, "Flag not one of FRDN", 1+2*i);
          exit(0);
        }
    
        /* Get final position */
        if(end < 0 || end > 26)
        {
          errorinfile(data_name, "Illegal finishing position", 1+2*i);
          exit(0);
        }
        position[i] = end;
    
        /* Warmup positions */
        if(warm < 0 || warm > 26)
        {
          errorinfile(data_name, "Illegal warmup position", 1+2*i);
          exit(0);
        }
        warmup[i] = warm;
        if(warm != 0 && status[i] != 0)
          totwarm+=1;
      
        if(nom != '-' && nom != '+')
        {
          errorinfile(data_name, "Nominated flag not - or +", 1+2*i);
          exit(0);
        }
      
        if(nom != '-')
          if(nom == '+' && nominated == 0)
            nominated = grid[i];
          else
          {
            errorinfile(data_name, "Too many nominated drivers", 1+2*i);
            exit(0);
          }
        
        readline(store, inlen, data_file);
      
      }
      while(!feof(data_file));
  
      ndrivers = i;
      fclose(data_file);
    }
  
    /* Check for correct number of warmup positions */
    if(totwarm < 6)
    {
      errorinfile(data_name, "Not enough warmup positions", 0);
      exit(0);
    }

    /* clear scores */
    for(i = 0; i < DRIVERS; i+=1)
    {
      topsixpts[i] = 0;
      awardpts[i] = 0;
      incgridpts[i] = 0;
      warmuppts[i] = 0;
      retirepts[i] = 0;
      noqualpts[i] = 0;
      racesc[i] = 0;
    }
  
    /* points for finishing in top six */
    k = 1;
    pos = 1;
    point = 1;
    do
    {
      while(position[k] != point)
        k = k + 1;
      if(status[k] == 1)
      {
        topsixpts[grid[k]] = 10 + points[pos];
        pos+=1;
      }
      point+=1;
      k = 1;
    }
    while(pos < 7 && point <= ndrivers);

    /* points for increasing on grid position */
    for(i = 1; i < ndrivers+1; i+=1) /* look through grid... */
      if(status[i] == 1)             /* ...for drivers who finish... */
        if(position[i] < i)          /* ...and beat their grid position */
          incgridpts[grid[i]] = (i-position[i]);

    /* adjust grid position increase due to disqualifications */
    for(i = 1; i < ndrivers+1; i+=1)    /* check all drivers for... */
      if(status[i] == 0)                /* ...disqualification and... */
        for(j = 1; j <ndrivers+1; j+=1) /* ...adjust the scores of... */
          if(position[j] > position[i] && status[j] == 1 && position[j] <= j)
            incgridpts[grid[j]]+=1;     /* ...those who finish after them */
  
    /* nominated driver points */
    awardpts[nominated] = 5;

    /* points for first 6 places in Sunday warmup */
    pos = 1;
    point = 1;
    i = 1;
    do
    {
      while(warmup[i] != point) 
        i+=1; /* if a driver came at position 'point' in the warmup */
      if(status[i] == 1 || status[i] == 2) /* and was not disqualified */
      {
        warmuppts[grid[i]] = 7 - pos;
        pos+=1;
      }
      point+=1;
      i = 1;
    }
    while(pos < 7 && point <= ndrivers);

    /* find position of last driver (usually 26) */
    last = 0;
    for(i = 1; i < ndrivers+1; i+=1)
      if(status[i] == 2)       /* if a driver retired */
        if(position[i] > last) /* and has the highest position number */
          last = position[i];  /* then he was in last place */
  
    /* points for first 5 to retire */
    for(i = 1; i < ndrivers+1; i+=1)
    {
      if(status[i] == 2)
      {
        if(position[i] == last)
          retirepts[grid[i]] = 5;
        if(position[i] == last-1)
          retirepts[grid[i]] = 4;
        if(position[i] == last-2)
          retirepts[grid[i]] = 3;
        if(position[i] == last-3)
          retirepts[grid[i]] = 2;
        if(position[i] == last-4)
          retirepts[grid[i]] = 1;
      }
    }

    /* points for non-qualification */
    for(i = 1; i < ndrivers+1; i+=1)
      if(status[i] == 3)
        noqualpts[grid[i]] = 5;
      
    /* move non-qualifiers to end of results */
    pos = last+1;
    for(i = 1; i < ndrivers+1; i+=1)
    {
      if(status[i] == 3)
      {
        position[i] = pos;
        pos+=1;
      }
    }
  
    /* reset chassis/engine flags/scores */
    for(i = 0; i < ENGINES; i+=1)
    {
      eflags[i] = 0;  
      engscr[i] = 0;
    }

    for(i = 0; i < CHASSIS; i+=1)
    {
      cflags[i] = 0;
      carscr[i] = 0;  
    }
  
    for(i = 0; i < DRIVERS; i+=1)
    {
      carpts[i] = 0;
      engpts[i] = 0;
    }
  
    pos = 1;
    point = 1;
    i = 1;
    do
    {
      while(position[i] != point)
        i+=1; /* find driver who finished in position 'point' */
      if(cflags[drcar[i]] == 0 && status[i] == 1)
      {
        /* if car hasn't already scored and driver did finish award points */
     /* carpts[i] = points[pos]*2; */          /* Version 1 rules */
        carpts[i] = points[pos]+10;            /* Version 2 rules */
     /* carscr[drcar[i]] += points[pos]*2; */  /* Version 1 rules */
        carscr[drcar[i]] += points[pos]+10;    /* Version 2 rules */
        cflags[drcar[i]] = 1;
        pos+=1;
      }
    point+=1;
      i = 1;
    }
    while( pos < 7 && point <= ndrivers);

    pos = 1;
    point = 1;
    i = 1;
    do
    {
      while(position[i] != point)
        i+=1;
      if(eflags[dreng[i]] == 0 && status[i] == 1)
      {
     /* engpts[i] = points[pos]*2; */          /* Version 1 rules */
        engpts[i] = points[pos]+10;            /* Version 2 rules */
     /* engscr[dreng[i]] += points[pos]*2; */  /* Version 1 rules */
        engscr[dreng[i]] += points[pos]+10;    /* Version 2 rules */
        eflags[dreng[i]] = 1;
        pos+=1;
      }
      point+=1;
      i = 1;
    }
    while( pos < 7 && point <= ndrivers);

    /* reset chassis flags */
    for(i = 0; i < CHASSIS; i+=1)
    {  
      cflags[i] = 0;
    }

    pos = last;
    point = last;
    i = 1;
    do
    {
      while(position[i] != point)
        i+=1;
      if(cflags[drcar[i]] == 0 && status[i] == 2)
      {
        carpts[i] = -(pos-(last-5));
        carscr[drcar[i]] -= (pos-(last-5));
        cflags[drcar[i]] = 1;
        pos-=1;
      }
      point-=1;
      i = 1;
    }
    while(pos > last-5 && point > 0);

    scores_file = fopen(scores_name, "r");
    if(scores_file == 0)
    {
      /* If the scores file doesn't exists, create it */
      scores_file = fopen(scores_name, "w");
      exists_flag = 0;
    } 
    else 
    {
      /* if it does exists, open a temporary file to move the scores to */
      fclose(scores_file);
      scores_file = fopen(temp_name, "w");
      exists_flag = 1;
      old_scores = fopen(scores_name, "r");
    
      /* get the original scores and move them to the temp file until we
         find a race with the same name or the end of the file */
      readline(racecheck, inlen, old_scores);
    
      while(strcasencmp(racecheck, racename, 6) && !feof(old_scores))
      {
        readline(store, inlen, old_scores);
        racedrivers = atoi(store);
        fprintf(scores_file, "%s\n", racecheck);
        fprintf(scores_file, "%d\n", racedrivers);
        for(i = 1; i <= racedrivers; i+=1)
        {
          fgets(store, inlen, old_scores);
          fputs(store, scores_file);
        }
        readline(racecheck, inlen, old_scores);
      }
    
      if(!feof(old_scores))
      {
        /* If we haven't reached the end-of-file compare the old results
           with the new results */
        readline(store, inlen, old_scores);
        racedrivers = atoi(store);
        for(i = 1; i <= racedrivers; i+=1)
        {
          fscanf(old_scores, "%d %d %d", &old_grid, &old_car, &old_eng);
          readline(store, inlen, old_scores);
          if(old_car != whichcar[old_grid])
          {
            /* a driver had a different car before - send a non-fatal
               message explaining this */
            printf("** %s's car has changed from %s to %s.\n", 
              namea[old_grid], chassisa[old_car], 
              chassisa[whichcar[old_grid]]);
          }
          if(old_eng != whicheng[old_grid])
          {
            printf("** %s's engine has changed from %s to %s.\n", 
              namea[old_grid], enginesa[old_eng], 
              enginesa[whicheng[old_grid]]);
          }
        }
      }
    }
  
    /* put the new scores in the correct file */
    fprintf(scores_file, "%s\n", racename);
    fprintf(scores_file, "%d\n", ndrivers);
    for(i = 1; i <= ndrivers; i+=1)
    {
      fprintf(scores_file, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
        grid[i], drcar[i], dreng[i], position[i], status[i], 
        topsixpts[grid[i]], awardpts[grid[i]], incgridpts[grid[i]],
        warmuppts[grid[i]], retirepts[grid[i]], noqualpts[grid[i]],
        carpts[i], carscr[drcar[i]], engpts[i], engscr[dreng[i]]);
    }

    if(exists_flag == 1)
    {
      readline(racecheck, inlen, old_scores);
      while(!feof(old_scores))
      {
        fprintf(scores_file, "%s\n", racecheck);
        readline(store, inlen, old_scores);
        racedrivers = atoi(store);
        fprintf(scores_file, "%d\n", racedrivers);
        for(i = 1; i <= racedrivers; i+=1)
        {
          fgets(store, inlen, old_scores);
          fputs(store, scores_file);
        }
        readline(racecheck, inlen, old_scores);
      }
      fclose(old_scores);
      if(unlink(scores_name) == -1)
      {
        fputs("Unable to delete \"scores.fgp2\".\n", stderr);
        exit(0);
      }
    }
  
    fclose(scores_file);
  
    if(exists_flag == 1)
      if(rename(temp_name, scores_name) == -1)
      {
        fputs("Unable to rename \"_tempscores\".\n", stderr);
        exit(0);
      }
  }
    
  /* Open teams.fgp2 */
  teams_file = fopen(teams_name, "r");

  /* Get the number of teams competing */
  readline(store, inlen, teams_file);
  nteams = atoi(store);

  for(i = 1; i < nteams + 1; i+=1)
  {
    readline(store, inlen, teams_file); 
    strcpy(owner[i], store);
    readline(store, inlen, teams_file);
    strcpy(teamname[i], store);
    readline(store, inlen, teams_file);
    driver1[i] = driver2no(store);
    readline(store, inlen, teams_file);
    driver2[i] = driver2no(store);
    readline(store, inlen, teams_file);
    driver3[i] = driver2no(store);
    readline(store, inlen, teams_file);
    chassis[i] = chassis2no(store);
    readline(store, inlen, teams_file);
    engine[i] = engine2no(store);
  }

  fclose(teams_file);
 
  if(normal != 255)
  {
    j = 0;
    if(normal == 0)
      normal = 255;
    
    scores_file = fopen(scores_name, "r");
    if(scores_file == 0)
    {
      disperr(scores_name);
      exit(0);
    }
    
    for(i = 0; i <= MAXTEAM; i+=1)
    {
      scores[i] = 0;
    }

    readline(store, inlen, scores_file);
    while(j != normal && !feof(scores_file))
    {
      /* Clear arrays */
      for(i = 1; i < DRIVERS; i+=1)
      {
        grid[i] = 0;
        position[i] = 0;
        status[i] = 0;
        drcar[i] = 0;
        dreng[i] = 0;
        warmup[i] = 0;
        topsixpts[i] = 0;
        awardpts[i] = 0;
        incgridpts[i] = 0;
        warmuppts[i] = 0;
        retirepts[i] = 0;
        noqualpts[i] = 0;
        carpts[i] = 0;
        engpts[i] = 0;
      }
      
      for(i = 0; i <= CHASSIS; i+=1)
      {
        carscr[i] = 0;
      }
      
      for(i = 0; i <= ENGINES; i+=1)
      {
        engscr[i] = 0;
      }
      
      strcpy(racename, store);
      readline(store, inlen, scores_file);
      ndrivers = atoi(store);
      
      for(i = 1; i <= ndrivers; i+=1)
      {
        fscanf(scores_file, "%d %d %d", &grid[i], &drcar[i], &dreng[i]);
        fscanf(scores_file, " %d %d %d %d %d %d %d %d %d %d %d %d",
          &position[i], &status[i], &topsixpts[grid[i]], 
          &awardpts[grid[i]], &incgridpts[grid[i]], &warmuppts[grid[i]], 
          &retirepts[grid[i]], &noqualpts[grid[i]], &carpts[i], 
          &carscr[drcar[i]], &engpts[i], &engscr[dreng[i]]);
        readline(store, inlen, scores_file);
      }

      /* total up scores */
      for(k = 0; k < DRIVERS; k+=1)
        racesc[k]=topsixpts[k]+awardpts[k]+incgridpts[k]+warmuppts[k]-
          retirepts[k]-noqualpts[k];

      /* Calculate teams' scores */
      for(k = 1; k <= nteams; k+=1)
      {
        thisrce[k]=(racesc[driver1[k]]+racesc[driver2[k]]+
          racesc[driver3[k]]+carscr[chassis[k]]+engscr[engine[k]]);
        scores[k]+=thisrce[k];
      }
      
      j+=1;
      readline(store, inlen, scores_file);
    }
    
    fclose(scores_file);

    printf("%s\n", verst);
    capitalise(racename);
    printf("%s Starting Grid\n\n", racename);
    for(i = 1; i < ndrivers+1; i+=1) 
    {
      if(status[i] != 3)
      {
        sprintf(fullname, "%s %s", fnama[grid[i]], namea[grid[i]]);
        printf("%2d : %-30s", i, fullname);
        printf(" %s-", chassisa[drcar[i]]);
        printf("%s\n", enginesa[dreng[i]]);
      } 
    }
    printf("\n%s Results\n\n", racename);
    printf("    NAME      POINTS BREAKDOWN       CHASSIS    POINTS ENGINE");
    printf("        POINTS\n");
    printf("                      Top Six\n");
    printf("                      |  Award                Driver's          ");
    printf("   Driver's\n");
    printf("                      |  | Grid Increase       Chassis          ");
    printf("     Engine\n");
    printf("                      |  | |  Warm-up               |           ");
    printf("         |\n");
    printf("                      |  | |  | Retirement          |           ");
    printf("         |\n");
    printf("                      |  | |  | | Non-qualification |           ");
    printf("         |\n");
    printf("                      |  | |  | | |                 |           ");
    printf("         |\n");

    pos = 1;
    j = 1;
    do
    {
      while(position[j] != pos)
        j+=1;
      if(status[j] == 0)
        strcpy(code, "DIS");
      if(status[j] == 1)
        sprintf(code, "%-3d", pos);
      if(status[j] == 2)
        strcpy(code, "rtd");
      if(status[j] == 3)
        strcpy(code, "DNQ");
         
      printf("%s %-13s %2d (%02d+%1d+%02d+%1d-%1d-%1d) ", code, namea[grid[j]],
        racesc[grid[j]], topsixpts[grid[j]], awardpts[grid[j]], 
        incgridpts[grid[j]], warmuppts[grid[j]], retirepts[grid[j]],
        noqualpts[grid[j]]);
      printf("%-9s %2d [%2d]", 
        chassisa[drcar[j]], carscr[drcar[j]], carpts[j]);
      printf(" %-12s %2d [%2d]\n", 
        enginesa[dreng[j]], engscr[dreng[j]], engpts[j]);
      pos+=1;
      j = 1;
    }
    while(pos < ndrivers+1); 

    for(i = 1; i < MAXTEAM; i+=1)
      sflags[i] = 0;

    printf("\n%s Team Scores\n\n", racename);

    for(i = 1; i < nteams+1; i+=1)
    {
      highest = 0;
      highscore = -500;
      for(j = 1; j < nteams+1; j+=1)
        if(sflags[j] == 0)
          if(scores[j] > highscore)
          {
            highscore = scores[j];
            highest = j;
          }
      sflags[highest] = 1;
      /* getteam(highest); */
      printf("Team Owner   : %s\nTeam Name    : %s\n", owner[highest],
        teamname[highest]);
      printf("Series Score : %3d\n", scores[highest]); 
      printf("Race Score   : %3d\n", thisrce[highest]);
      printf("Race Details : Driver one    - %-13s = %2d\n", namea[driver1[highest]], 
        racesc[driver1[highest]]);
      printf("               Driver two    - %-13s = %2d\n", namea[driver2[highest]], 
        racesc[driver2[highest]]);
      printf("               Test Driver   - %-13s = %2d\n", namea[driver3[highest]], 
        racesc[driver3[highest]]);
      printf("               Car's Chassis - %-13s = %2d\n", 
        chassisa[chassis[highest]], carscr[chassis[highest]]);
      printf("               Car's Engine  - %-13s = %2d\n\n", 
        enginesa[engine[highest]], engscr[engine[highest]]);
    }
  }

  if(teams != 255)
  {
    j = 0;
    if(teams == 0)
      teams = 255;
    
    scores_file = fopen(scores_name, "r");
    if(scores_file == 0)
    {
      disperr(scores_name);
      exit(0);
    }
    
    for(i = 0; i <= MAXTEAM; i+=1)
    {
      scores[i] = 0;
    }

    readline(store, inlen, scores_file);
    while(j != teams && !feof(scores_file))
    {
      /* Clear arrays */
      for(i = 1; i < DRIVERS; i+=1)
      {
        grid[i] = 0;
        position[i] = 0;
        status[i] = 0;
        drcar[i] = 0;
        dreng[i] = 0;
        warmup[i] = 0;
        topsixpts[i] = 0;
        awardpts[i] = 0;
        incgridpts[i] = 0;
        warmuppts[i] = 0;
        retirepts[i] = 0;
        noqualpts[i] = 0;
        carpts[i] = 0;
        engpts[i] = 0;
        racesc[i] = 0;
      }
      
      for(i = 0; i <= CHASSIS; i+=1)
      {
        carscr[i] = 0;
      }
      
      for(i = 0; i <= ENGINES; i+=1)
      {
        engscr[i] = 0;
      }
      
      capitalise(store);
      strcpy(racenames[j], store);
      readline(store, inlen, scores_file);
      ndrivers = atoi(store);
      
      for(i = 1; i <= ndrivers; i+=1)
      {
        fscanf(scores_file, "%d %d %d", &grid[i], &drcar[i], &dreng[i]);
        fscanf(scores_file, " %d %d %d %d %d %d %d %d %d %d %d %d",
          &position[i], &status[i], &topsixpts[grid[i]], 
          &awardpts[grid[i]], &incgridpts[grid[i]], &warmuppts[grid[i]], 
          &retirepts[grid[i]], &noqualpts[grid[i]], &carpts[i], 
          &carscr[drcar[i]], &engpts[i], &engscr[dreng[i]]);
        readline(store, inlen, scores_file);
      }

      /* total up scores */
      for(k = 0; k < DRIVERS; k+=1)
        racesc[k]=topsixpts[k]+awardpts[k]+incgridpts[k]+warmuppts[k]-
          retirepts[k]-noqualpts[k];

      /* Calculate teams' scores */
      for(k = 1; k <= nteams; k+=1)
      {
        teamscores[k][j]=(racesc[driver1[k]]+racesc[driver2[k]]+
          racesc[driver3[k]]+carscr[chassis[k]]+engscr[engine[k]]);
        scores[k]+=teamscores[k][j];
      }
      
      j+=1;
      readline(store, inlen, scores_file);
    }
    nraces = j-1;
    
    fclose(scores_file);

    printf("%s\n", verst);
    printf("Team scores table\n");
    
    for(i = 0; i <= nraces; i+=1)
    {
      printf("                        ");
      if(i > 0)
        for(j = 0; j < i; j+=1)
          printf(" |  ");
      printf("%s\n", racenames[i]);
    }
    
    printf("+----------------------+");
    for(i = 0; i <= nraces; i+=1)
      printf("---+");
    printf("-----+\n");
    
    for(i = 1; i <= nteams; i+=1)
    {
      printf("| %-20s |", teamname[i]);
      for(j = 0; j <= nraces; j+=1)
        printf("%3d|", teamscores[i][j]);
      printf("%5d|\n", scores[i]);
    
      printf("+----------------------+");
      for(k = 0; k <= nraces; k+=1)
        printf("---+");
      printf("-----+\n");
    }
    printf("\n");
  }

  if(drive != 255)
  {
    j = 0;
    if(drive == 0)
      drive = 255;
    
    scores_file = fopen(scores_name, "r");
    if(scores_file == 0)
    {
      disperr(scores_name);
      exit(0);
    }

    for(i = 0; i <= MAXTEAM; i+=1)
    {
      scores[i] = 0;
    }
    
    readline(store, inlen, scores_file);
    while(j != drive && !feof(scores_file))
    {
      /* Clear arrays */
      for(i = 1; i < DRIVERS; i+=1)
      {
        grid[i] = 0;
        position[i] = 0;
        status[i] = 0;
        drcar[i] = 0;
        dreng[i] = 0;
        warmup[i] = 0;
        topsixpts[i] = 0;
        awardpts[i] = 0;
        incgridpts[i] = 0;
        warmuppts[i] = 0;
        retirepts[i] = 0;
        noqualpts[i] = 0;
        carpts[i] = 0;
        engpts[i] = 0;
      }
      
      for(i = 0; i <= CHASSIS; i+=1)
      {
        carscr[i] = 0;
      }
      
      for(i = 0; i <= ENGINES; i+=1)
      {
        engscr[i] = 0;
      }
      
      capitalise(store);
      strcpy(racenames[j], store);
      readline(store, inlen, scores_file);
      ndrivers = atoi(store);
      
      for(i = 1; i <= ndrivers; i+=1)
      {
        fscanf(scores_file, "%d %d %d", &grid[i], &drcar[i], &dreng[i]);
        fscanf(scores_file, " %d %d %d %d %d %d %d %d %d %d %d %d",
          &position[i], &status[i], &topsixpts[grid[i]], 
          &awardpts[grid[i]], &incgridpts[grid[i]], &warmuppts[grid[i]], 
          &retirepts[grid[i]], &noqualpts[grid[i]], &carpts[i], 
          &carscr[drcar[i]], &engpts[i], &engscr[dreng[i]]);
        readline(store, inlen, scores_file);
      }

      /* total up scores */
      for(k = 0; k < DRIVERS; k+=1)
      {
        driverscore[k][j]=topsixpts[k]+awardpts[k]+incgridpts[k]
          +warmuppts[k]-retirepts[k]-noqualpts[k];
        drivertotal[k]+=driverscore[k][j];
      }
      
      j+=1;
      readline(store, inlen, scores_file);
    }
    nraces = j-1;
    
    fclose(scores_file);

    printf("%s\n", verst);
    printf("Driver scores table\n");
     
    for(i = 0; i <= nraces; i+=1)
    {
      printf("                        ");
      if(i > 0)
        for(j = 0; j < i; j+=1)
          printf(" |  ");
      printf("%s\n", racenames[i]);
    }
    
    printf("+----------------------+");
    for(i = 0; i <= nraces; i+=1)
      printf("---+");
    printf("-----+\n");
    
    for(i = 1; i <= maxdrivers; i+=1)
    {
      printf("| %-20s |", namea[i]);
      for(j = 0; j <= nraces; j+=1)
        printf("%3d|", driverscore[i][j]);
      printf("%5d|\n", drivertotal[i]);
    
      printf("+----------------------+");
      for(k = 0; k <= nraces; k+=1)
        printf("---+");
      printf("-----+\n");
    }
    printf("\n");
  }
  
  exit(0);
}

void disperr(char *file_name)
{
  fputs(verst, stderr);
  fputs("Unable to open \"", stderr);
  fputs(file_name, stderr);
  fputs("\".\n", stderr);
  return;
}

void errorinfile(char *file_name, char *error, int line)
{
  fputs(verst, stderr);
  fputs("Error in file \"", stderr);
  fputs(file_name, stderr);
  fputs("\" on line ", stderr);
  fprintf(stderr, "%d", line);
  fputs(". ", stderr);
  fputs(error, stderr);
  fputs(".\n", stderr);
}  

int driver2no(char *driname)
{
  int  n;

  n = 1; 
  while((strcasencmp(namea[n], driname, 6)) && n <= maxdrivers)
    n+=1;
    
  if(n > maxdrivers)
    n = 0;
  
  return(n);
}

int chassis2no(char *chaname)
{
  int n;
  
  n = 1;
  while((strcasencmp(chassisa[n], chaname, 6)) && n <= maxchassis)
    n+=1;
  
  if(n > maxchassis)
    n=0;
    
  return(n);
}
  
int engine2no(char *engname)
{
  int n;
  
  n = 1;
  while((strcasencmp(enginesa[n], engname, 6)) && n <= maxengines)
    n+=1;
  
  if(n > maxengines)
    n=0;
    
  return(n);
}
  
int strcasencmp(char *stringa, char *stringb, int testnum)
{
  int  i;
  char string1[100], string2[100];
  
  strcpy(string1, stringa);
  strcpy(string2, stringb);
  
  for(i = 0; i <= strlen(string1); i+=1)
    string1[i] = tolower(string1[i]);
  for(i = 0; i <= strlen(string2); i+=1)
    string2[i] = tolower(string2[i]);
    
  return(strncmp(string1, string2, testnum));
}

void capitalise(char *word)
{
  word[0] = toupper(word[0]);
  return;
}

unsigned int readline(char *in_string, int chars_2_read, FILE *file_pointer)
{
  char temp[100];
  
  fgets(temp, chars_2_read, file_pointer);
  
  while(temp[0] == '#' && temp[1] == '#')
    fgets(temp, chars_2_read, file_pointer);
  
  strcpy(in_string, temp);
  in_string[strlen(in_string)-1] = 0;
  
  return(strlen(temp)-1);
}
