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

/* Includes */

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

/* Defines */

#define DRIVERS 51
#define CHASSIS 65
#define ENGINES 75
#define MAXTEAM 51

/* Variables */

char *ver = "$VER: FGP v2.03 (9/8/94) © S Austin"; /* Amiga Version String */
char *verst = "FGP2 by S Austin, Output format by J Simpson.\n"; 

FILE *grid_file, *results_file, *teams_file, *scores_file, *drives_file,
     *names_file, *other_file; /* Pointers to various files */

FILE *drivers_file, *chassis_file, *engine_file;

char grid_name[40], results_name[40], other_name[40], 
     teams_name[] = "teams.fgp2", scores_name[] = "scores.fgp2", 
     drives_name[] = "drives.fgp2", names_name[] = "names.fgp2";

char drivers_name[] = "drivers.fgp2", chassis_name[] = "chassis.fgp2",
     engine_name[] = "engine.fgp2";

char store[100], driver[100], owner[100], teamname[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[29], results[27], warmup[7], nominated, 
     finisher, qualifier; /* Results */

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

int  drchas[DRIVERS], dreng[DRIVERS]; /* chassis/engine for each driver */

int  points[] = { 0, 10, 6, 4, 3, 2, 1 }; /* Points for pos' 1-6 */
  
int  nteams, ndrivers, i, j, pos, update;

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

void disperr(char *);
int name2no(char *);
void no2name(int);
void getcar(int);
void getteam(int);
  
main(int argc, char *argv[])
{ 
  if(argc != 3)
  { 
    /* Incorrect command line, display message and quit */
    fputs(verst, stderr);
    fputs("Usage: FGP <+|->u <Race_Name>\n", stderr);
    exit(0);
  }
  else
  {
    /* Produce names of three input files */
    strcpy(grid_name, argv[2]);
    strcat(grid_name, ".grid");
    strcpy(results_name, argv[2]);
    strcat(results_name, ".rslt");
    strcpy(other_name, argv[2]);
    strcat(other_name, ".xtra");
    /* Do we update scores (+u) or not (-u) */
    update = 2;
    if(strcmp(argv[1], "+u") == 0)
      update = 1;
    if(strcmp(argv[1], "-u") == 0)
      update = 0;
    if(update == 2)
    {
      fputs(verst, stderr);
      fputs("Usage: FGP <+|->u <Race_Name>\n", stderr);
      exit(0);
    }
  }

  /* Open and parse teams file */
  teams_file = fopen(teams_name, "r");
  if(teams_file == 0)
  {
    disperr(teams_name);
    exit(0);
  }

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

  for(i = 1; i < nteams + 1; i+=1)
  {
    fgets(store, inlen, teams_file); /* skip over name and owner */
    fgets(store, inlen, teams_file); /* as they aren't required yet */
    fgets(store, inlen, teams_file);
    driver1[i] = name2no(store);
    fgets(store, inlen, teams_file);
    driver2[i] = name2no(store);
    fgets(store, inlen, teams_file);
    driver3[i] = name2no(store);
    fgets(store, inlen, teams_file);
    chassis[i] = name2no(store);
    fgets(store, inlen, teams_file);
    engine[i] = name2no(store);
  }

  fclose(teams_file);

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

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

  for(i = 1; i < ndrivers+1; i+=1)
  {
    fgets(store, inlen, grid_file);
    grid[i] = name2no(store);
    getcar(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)
  {
    fgets(store, inlen, other_file);
    warmup[i] = name2no(store);
  }
  fgets(store, inlen, other_file);
  nominated = name2no(store);
  fgets(store, inlen, other_file);
  finisher = atoi(store);
  fgets(store, inlen, other_file);
  qualifier = atoi(store);
  
  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)
  {
    fgets(store, inlen, results_file);
    results[i] = name2no(store);
  }

  fclose(results_file);

  /* clear scores */
  for(i = 0; i < 71; i+=1)
  {
    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 = 1; i < 7; i+=1)
    topsixpts[results[i]] = (points[i]+10);

  for(i = 1; i < qualifier+1; i+=1)
    for(j = i; j > 0; j-=1)
      if(j < finisher+1)
        if(results[j] == grid[i])
          incgridpts[grid[i]] = (i-j);

  awardpts[nominated] = 5;

  for(i = 1; i < 7; i+=1)
    warmuppts[warmup[i]] = (7 - i);

  for( i = qualifier; i > qualifier-5; i-=1)
    retirepts[results[i]] = (i - (qualifier-5));

  for( i = qualifier+1; i < ndrivers+1; i+=1)
    noqualpts[grid[i]] = 5;

  for(i = 0; i < 39; i+=1)
    racesc[i]=topsixpts[i]+awardpts[i]+incgridpts[i]+warmuppts[i]-
              retirepts[i]-noqualpts[i];

  /* reset chassis/engine flags */
  for(i = 0; i < ENGINES; i+=1)
  {
    eflags[i] = 0;  
  }

  for(i = 0; i < CHASSIS; i+=1)
  {
    cflags[i] = 0;  
  }

  pos = 1;
  i = 1;
  while(pos < 7 & i < finisher+1)
  {
    if(cflags[drchas[results[i]]] == 0)
    {
      carpts[results[i]] = points[pos]+10; /* Was points[pos]*2 */
      racesc[drchas[results[i]]] += points[pos]+10; /* ditto */
      cflags[drchas[results[i]]] = 1;
      pos+=1;
    }
    i+=1;
  }

  pos = 1;
  i = 1;
  while(pos < 7 & i <finisher+1)
  {
    if(eflags[dreng[results[i]]] == 0)
    {
      engpts[results[i]] = points[pos]+10; /* Was points[pos]*2 */
      racesc[dreng[results[i]]] += points[pos]+10; /* ditto */
      eflags[dreng[results[i]]] = 1;
      pos+=1;
    }
    i+=1;
  }

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

  pos = qualifier;
  i = qualifier;
  while(pos > (qualifier-5))
  {
    if(cflags[drchas[results[i]]] == 0)
    {
      carpts[results[i]] = -(pos-(qualifier-5));
      racesc[drchas[results[i]]] -= (pos-(qualifier-5));
      cflags[drchas[results[i]]] = 1;
      pos-=1;
    }
    i-=1;
  }

  printf("%s", verst);
  printf("\nStarting Grid\n\n");
  for(i = 1; i < qualifier+1; i+=1)
  {
    no2name(grid[i]);
    printf("%2d : %-13s", i, driver);
    no2name(drchas[grid[i]]);
    printf(" %s-", driver);
    no2name(dreng[grid[i]]);
    printf("%s\n", driver);
  }
  printf("\nResults\n\n");
  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");

  for( i = 1; i < finisher+1; i+=1)
  {
    no2name(results[i]);
    printf("%2d  %-13s %2d (%02d+%1d+%02d+%1d-%1d-%1d) ", i, driver,
           racesc[results[i]], topsixpts[results[i]],
           awardpts[results[i]], incgridpts[results[i]],
           warmuppts[results[i]], retirepts[results[i]],
           noqualpts[results[i]]);
    no2name(drchas[results[i]]);
    printf("%-9s %2d [%2d]", driver, racesc[drchas[results[i]]], 
           carpts[results[i]]);
    no2name(dreng[results[i]]);
    printf(" %-12s %2d [%2d]\n", driver, racesc[dreng[results[i]]],
           engpts[results[i]]);
  }

  for( i = finisher+1; i < qualifier+1; i+=1)
  {
    no2name(results[i]);    
    printf("rtd %-13s %2d (%02d+%1d+%02d+%1d-%1d-%1d) ", driver,
           racesc[results[i]], topsixpts[results[i]],
           awardpts[results[i]], incgridpts[results[i]],
           warmuppts[results[i]], retirepts[results[i]],
           noqualpts[results[i]]);
    no2name(drchas[results[i]]);
    printf("%-9s %2d [%2d]", driver, racesc[drchas[results[i]]],
           carpts[results[i]]);
    no2name(dreng[results[i]]);
    printf(" %-12s %2d [%2d]\n", driver, racesc[dreng[results[i]]],
           engpts[results[i]]);
  }

  for( i = qualifier+1; i < ndrivers+1; i+=1)
  {
    no2name(grid[i]);    
    printf("DNQ %-13s %2d (%02d+%1d+%02d+%1d-%1d-%1d) ", driver,
           racesc[grid[i]], topsixpts[grid[i]],
           awardpts[grid[i]], incgridpts[grid[i]],
           warmuppts[grid[i]], retirepts[grid[i]],
           noqualpts[grid[i]]);
    no2name(drchas[grid[i]]);
    printf("%-9s %2d [%2d]", driver, racesc[drchas[grid[i]]],
           carpts[grid[i]]);
    no2name(dreng[grid[i]]);
    printf(" %-12s %2d [%2d]\n", driver, racesc[dreng[grid[i]]],
           engpts[grid[i]]);
  }
  
  /* Calculate and display teams scores */
  /* If scores file doesn't exist reset scores, else load them */
  scores_file = fopen(scores_name, "r");
  if(scores_file == 0)
    for(i = 1; i < nteams+1; i+=1)
      scores[i] = 0;
  else
  {
    for(i = 1; i < nteams+1; i+=1)
      fscanf(scores_file, "%d", &scores[i]);
    fclose(scores_file);
  }

  for(i = 1; i < nteams+1; i+=1)
  {
    thisrce[i]=(racesc[driver1[i]]+racesc[driver2[i]]+
                racesc[driver3[i]]+racesc[chassis[i]]+racesc[engine[i]]);
    scores[i]+=thisrce[i];
  }

  if(update == 1)
  {
    scores_file = fopen(scores_name, "w");
    if(scores_file == 0)
    {
      disperr(scores_name);
      exit(0);
    }
  
    for(i = 1; i < nteams+1; i+=1)
      fprintf(scores_file, "%d\n", scores[i]);

    fclose(scores_file);
  }

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

  printf("\nTeam Scores\n\n");

  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("%s%s", owner, teamname);
    printf("Score (this race) : %d (%d)\n", scores[highest], 
            thisrce[highest]);
    no2name(driver1[highest]);
    printf("Driver one : %-13s (%d)\n", driver, racesc[driver1[highest]]);
    no2name(driver2[highest]);
    printf("Driver two : %-13s (%d)\n", driver, racesc[driver2[highest]]);
    no2name(driver3[highest]);
    printf("Test Driver: %-13s (%d)\n", driver, racesc[driver3[highest]]);
    no2name(chassis[highest]);
    printf("Car: %s/", driver);
    no2name(engine[highest]);
    printf("%s (%d/%d)\n\n", driver, racesc[chassis[highest]],
            racesc[engine[highest]]);
  }
 
  exit(0);
}

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

int name2no(char *name)
{
  char temp[100];
  int  n, maxnam;

  names_file = fopen(names_name, "r");
  if(names_file == 0)
  {
    disperr(names_name);
    exit(0);
  }

  fgets(temp, inlen, names_file);
  maxnam = atoi(temp);
  
  n = 1;
  fgets(temp, inlen, names_file);
  while((strncmp(temp, name, 6) != 0) && (n != maxnam+1))
  {
    fgets(temp, inlen, names_file);
    n+=1;
  }
  if(n == maxnam+1)
    n = 0;
  
  fclose(names_file);
  return(n);
}

void no2name(int number)
{
  int  n, maxnam;
  char temp[100];

  if(number == 0)
  {
    strcpy(driver, "Unknown");
    return;
  }

  names_file = fopen(names_name, "r");
  if(names_file == 0)
  {
    disperr(names_name);
    exit(0);
  }

  fgets(driver, inlen, names_file);
  maxnam = atoi(driver);
  
  for(n = 1; n < number+1; n+=1)
  {
    fgets(driver, inlen, names_file);
  }
  
  strcpy(temp, "");
  strncat(temp, driver, strlen(driver)-1);
  strcpy(driver, temp);
  fclose(names_file);
  return;
}

void getcar(int drnum)
{
  int n;
 
  drives_file = fopen(drives_name, "r");
  if(drives_file == 0)
  {
    disperr(drives_name);
    exit(0);
  }

  for(n = 1; n < drnum+1; n+=1)
    fscanf(drives_file, "%d %d", &drchas[drnum], &dreng[drnum]);

  return;
}

void getteam(int teamno)
{
  char null[100];
  int  n;

  teams_file = fopen(teams_name, "r");
  if(teams_file == 0)
  {
    disperr(teams_name);
    exit(0);
  }

  fgets(owner, inlen, teams_file);
  
  for(n = 1; n < teamno+1; n+=1)
  {
    fgets(owner, inlen, teams_file);
    fgets(teamname, inlen, teams_file);
    fgets(null, inlen, teams_file);
    fgets(null, inlen, teams_file);
    fgets(null, inlen, teams_file);
    fgets(null, inlen, teams_file);
    fgets(null, inlen, teams_file);
  }

  fclose(teams_file);
  return;
}
