/* (sc)gs.c - Written by Tom Wilson <wilson@cs.ucf.edu> */

#include <stdio.h>
#define N 100
#define NUM 10
#define SC 0

#if (SC)
char filename[] = "scgstats", progname[] = "scgs";
#else
char filename[] = "gstats", progname[] = "gs";
#endif

struct statsrec
 {int rank, mp, ga, so, w, l, t, sog;
  float gaa, sp, pct;
  char team[4], first[15], last[15];
 } players[N];

char team[4],
     *strings[10] =
      {"Lowest Goals Against Average", "Most Minutes Played",
       "Least Goals Against", "Most Shut Outs", "Most Wins", "Most Losses",
       "Most Ties", "Best Record", "Most Shots on Goal",
       "Best Save Percentage"};
int n, num, choice, minminutes, compgaa(), compmp(), compga(), compso(),
    compw(), compl(), compt(), comprec(), compsog(), compsp(),
    (*compfuncs[10])() =
     {compgaa, compmp, compga, compso, compw, compl, compt, comprec, compsog,
      compsp};

main(argc,argv)
  int argc;
  char *argv[];
{int rank, x, cnt, gp, pts;
 float oldgaa;
 FILE *fp;
 char *s, c;
 struct statsrec *p;

 if ((fp = fopen(filename,"r")) == 0)
  {printf("no %s file.\n",filename);
   return;
  }
 oldgaa = -1.0;
 while (1)
  {if (n > N)
    {printf("redefine N\n");
     return;
    }
   p = &players[n];
   fscanf(fp,"%d %d %d %d %d %d %d %s %s %s",&(p->mp),&(p->ga),&(p->so),
          &(p->w),&(p->l),&(p->t),&(p->sog),p->team,p->first,p->last);
   if (feof(fp))
     break;
   gp = p->w + p->t;
   pts = gp + p->w;
   gp += p->l;
   if (gp)
     p->pct = (float) pts / (float) (gp + gp);
   else p->pct = 0.0;
   if (p->mp)
     p->gaa = (float) (p->ga) / ((float) (p->mp) / 60.0);
   else p->gaa = 0.0;
   if (p->sog)
     p->sp = (float) (p->sog - p->ga) / (float) (p->sog);
   else p->sp = 0.0;
   n++;
   if (p->gaa != oldgaa)
    {rank = n;
     oldgaa = p->gaa;
    }
   p->rank = rank;
  }
 fclose(fp);
 num = NUM;
 choice = -1;
 cnt = 1;
 while (--argc > 0 && argv[cnt][0] == '-')
  {s = argv[cnt]+1;
   switch (*s)
    {case 'g':
       switch (*(s+1))
        {case 'a':
           choice = 0;
           break;
         default:
           choice = 2;
           break;
        }
       break;
     case 'l':
       choice = 5;
       break;
     case 'm':
       choice = 1;
       break;
     case 'M':
       if ((minminutes = atoi(argv[cnt]+2)) < 0)
         minminutes = 0;
       choice = -2;
       break;
     case 'n':
       if ((num = atoi(argv[cnt]+2)) > n || num == 0)
         num = n;
       choice = -1;
       break;
     case 'r':
       choice = 7;
       break;
     case 's':
       switch (*(s+1))
        {case 'o':
           choice = 3;
           break;
         case 'g':
           choice = 8;
           break;
         case 'p':
           choice = 9;
           break;
        }
       break;
     case 't':
       strcpy(team,argv[cnt]+2);
       choice = -1;
       break;
     case 'w':
       choice = 4;
       break;
     case 'T':
#if (!SC)
       choice = 6;
       break;
#endif
     default:
       printf("usage: gstats [-n# -t<team> ");
#if (SC)
       printf("[-g -ga -l -m -M# -r -sg -so -sp -w]\n");
#else
       printf("[-g -ga -l -m -M# -r -sg -so -sp -T -w]\n");
#endif
       printf("       #>0 (=0/<null> for all players)\n");
       printf("       <team>=BOS|BUF|CAL|CHI|DET|EDM|HAR|LA|MIN|MON|NJ|NYI|\n");
       printf("              NYR|PHI|PIT|QUE|SJ|STL|TOR|VAN|WAS|WIN|<null>\n");
       return;
    }
   cnt++;
   if (choice >= 0)
    {qsort((char *) players,(unsigned int) n,sizeof(struct statsrec),
           compfuncs[choice]);
     prtlist(choice);
    }
  }
 if (choice < 0)
  {if (choice == -2)
     qsort((char *) players,(unsigned int) n,sizeof(struct statsrec),
             compfuncs[0]);
   prtlist(0);
  }
}

prtlist(choice)
  int choice;
{int x, y, z;
 struct statsrec *p, *p1;

 putchar('\n');
 if (num != n)
   printf("Top %d ",num);
 printf("Goalies with %s",strings[choice]);
 if (team[0] != 0)
   printf(" for %s",team);
 if (minminutes > 0 && choice != 1)
   printf(" [min %d MP]",minminutes);
 putchar('\n');
 printf("Rnk  MP   GA SO  GAA   W  L");
#if (!SC)
 printf("  T");
#endif
 printf("  PCT   SoG Save%% Tm  Name\n");
 printf("--- ---- --- -- ----- -- --");
#if (!SC)
 printf(" --");
#endif
 printf(" ----- ---- ----- --- ----\n");
 for (x = y = 0; x < n && y < num; x++)
  {p = &players[x];
   if ((team[0] == 0 || strcmp(team,p->team) == 0))
    {y++;
#if (SC)
     printf("%3d %4d %3d %2d %5.2f %2d %2d %5.3f %4d %5.3f %-3s %s %s\n",
            p->rank,p->mp,p->ga,p->so,p->gaa,p->w,p->l,p->pct,p->sog,
            p->sp,p->team,p->first,p->last);
#else
     printf("%3d %4d %3d %2d %5.2f %2d %2d %2d %5.3f %4d %5.3f %-3s %s %s\n",
            p->rank,p->mp,p->ga,p->so,p->gaa,p->w,p->l,p->t,p->pct,p->sog,
            p->sp,p->team,p->first,p->last);
#endif
    }
  }
}

domin(e1,e2)
  struct statsrec *e1, *e2;
{if (e1->mp < minminutes && e2->mp >= minminutes)
   return 1;
 if (e1->mp >= minminutes && e2->mp < minminutes)
   return -1;
 return 0;
}

compgaa(e1,e2)
  struct statsrec *e1, *e2;
{int d;

 if ((d = domin(e1,e2)) != 0)
   return d;
 if (e1->gaa > e2->gaa) return 1;
 if (e1->gaa < e2->gaa) return -1;
 return compmp(e1,e2);
}

compmp(e1,e2)
  struct statsrec *e1, *e2;
{if (e1->mp < e2->mp) return 1;
 if (e1->mp > e2->mp) return -1;
 return strcmp(e1->last,e2->last);
}

compga(e1,e2)
  struct statsrec *e1, *e2;
{int d;

 if ((d = domin(e1,e2)) != 0)
   return d;
 if (e1->ga < e2->ga) return 1;
 if (e1->ga > e2->ga) return -1;
 return compgaa(e1,e2);
}

compso(e1,e2)
  struct statsrec *e1, *e2;
{int d;

 if ((d = domin(e1,e2)) != 0)
   return d;
 if (e1->so < e2->so) return 1;
 if (e1->so > e2->so) return -1;
 return compgaa(e1,e2);
}

compw(e1,e2)
  struct statsrec *e1, *e2;
{int d;

 if ((d = domin(e1,e2)) != 0)
   return d;
 if (e1->w < e2->w) return 1;
 if (e1->w > e2->w) return -1;
 return compgaa(e1,e2);
}

compl(e1,e2)
  struct statsrec *e1, *e2;
{int d;

 if ((d = domin(e1,e2)) != 0)
   return d;
 if (e1->l < e2->l) return 1;
 if (e1->l > e2->l) return -1;
 return compgaa(e1,e2);
}

compt(e1,e2)
  struct statsrec *e1, *e2;
{int d;

 if ((d = domin(e1,e2)) != 0)
   return d;
 if (e1->t < e2->t) return 1;
 if (e1->t > e2->t) return -1;
 return compgaa(e1,e2);
}

compsog(e1,e2)
  struct statsrec *e1, *e2;
{int d;

 if ((d = domin(e1,e2)) != 0)
   return d;
 if (e1->sog < e2->sog) return 1;
 if (e1->sog > e2->sog) return -1;
 return compgaa(e1,e2);
}

compsp(e1,e2)
  struct statsrec *e1, *e2;
{int d;

 if ((d = domin(e1,e2)) != 0)
   return d;
 if (e1->sp < e2->sp) return 1;
 if (e1->sp > e2->sp) return -1;
 return compgaa(e1,e2);
}

comprec(e1,e2)
  struct statsrec *e1, *e2;
{int d;

 if ((d = domin(e1,e2)) != 0)
   return d;
 if (e1->pct < e2->pct) return 1;
 if (e1->pct > e2->pct) return -1;
 return compgaa(e1,e2);
}

/*
qsort(s,n,size,compfunc)
  struct statsrec *s;
  unsigned int n;
  int size, (*compfunc)();
{int x, y, z;
 struct statsrec sr;

 z = n-1;
 for (x = 0; x < z; x++)
   for (y = z; y >= x; y--)
     if (compfunc(&s[y],&s[y+1]) == 1)
      {sr = s[y];
       s[y] = s[y+1];
       s[y+1] = sr;
      }
}
*/
