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

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

#if (SC)
char filename[] = "scipstats", progname[] = "scips";
#else
char filename[] = "ipstats", progname[] = "ips";
#endif

struct statsrec
 {int rank, pts, g, a, pg, sg, eg, ps, gp, pims;
  char team[4], pos[3], first[15], last[15], rookie, num[3], country[4];
  float ppg, gpg, apg, pimspg;
 } players[N];

char team[4], pos[3], country[4],
     *strings[12] =
      {"Point", "Goal", "Assist", "Power-play Goal", "Short-handed Goal",
       "Empty-net Goal", "Penalty-shot Goal", "Points/Game", "Goals/Game",
       "Assists/Game", "Penalty Minute", "Penalty Minutes/Game"};
int n, num, choice, comppts(), compgoals(), compassists(), compppgoals(),
    compshgoals(), compengoals(), comppsgoals(), rookie, compppg(), compgpg(),
    compapg(), comppims(), comppimspg(), mingp,
    (*compfuncs[12])() =
     {comppts, compgoals, compassists, compppgoals, compshgoals, compengoals,
      comppsgoals, compppg, compgpg, compapg, comppims, comppimspg};

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

 if ((fp = fopen(filename,"r")) == 0)
  {printf("no %s file.\n",filename);
   return;
  }
 while (1)
  {if (n == N)
    {printf("redefine N\n");
     return;
    }
   p = &players[n];
   fscanf(fp,"%d %d %d %d %d %d %d %d %d %s %s %s %s%c%c%s %s",&(p->gp),
          &(p->pts),&(p->g),&(p->a),&(p->pg),&(p->sg),&(p->eg),&(p->ps),
          &(p->pims),p->country,p->team,p->pos,p->num,&c,&(p->rookie),p->first,
          p->last);
   if (feof(fp))
     break;
   n++;
   if (p->gp)
    {gp = (float) (p->gp);
     p->ppg = (float) (p->pts) / gp;
     p->gpg = (float) (p->g) / gp;
     p->apg = (float) (p->a) / gp;
     p->pimspg = (float) (p->pims) / gp;
    }
   if (p->pts != oldpts)
    {rank = n;
     oldpts = p->pts;
    }
   p->rank = rank;
  }
 fclose(fp);
 num = NUM;
 choice = -1;
 cnt = 1;
 while (--argc > 0 && argv[cnt][0] == '-')
  {s = argv[cnt]+1;
   switch (*s)
    {case 'p':
       switch (*(s+1))
        {case 'p':
           choice = 3;
           break;
         case 's':
           choice = 6;
           break;
         case 'g':
           choice = 7;
           break;
         case 'm':
           choice = 10;
           break;
         case 'M':
           choice = 11;
           break;
         default:
           choice = 0;
           break;
        }
       break;
     case 'g':
       if (*(s+1) == 'g')
         choice = 8;
       else choice = 1;
       break;
     case 'a':
       if (*(s+1) == 'g')
         choice = 9;
       else choice = 2;
       break;
     case 's':
       choice = 4;
       break;
     case 'e':
       choice = 5;
       break;
     case 'n':
       if ((num = atoi(argv[cnt]+2)) > n || num == 0)
         num = n;
       choice = -1;
       break;
     case 'G':
       if ((mingp = atoi(argv[cnt]+2)) > 80 || mingp == 0)
         mingp = 0;
       choice = -1;
       break;
     case 'P':
       strcpy(pos,argv[cnt]+2);
       choice = -1;
       break;
     case 't':
       strcpy(team,argv[cnt]+2);
       choice = -1;
       break;
     case 'r':
       rookie = 1;
       choice = -1;
       break;
     case 'R':
       rookie = 0;
       choice = -1;
       break;
     case 'c':
       strcpy(country,argv[cnt]+2);
       choice = -1;
       break;
     default:
       printf("usage: %s [player-option] [stat-type]\n",progname);
       printf("  player-option = [-n# -t<team> -P<pos> -c<cty> -r -R -G#]\n");
       printf("  stat-type = [-p -g -a -pp -s -e -ps -pg -gg -ag -pm -pM]\n");
       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");
       printf("    <pos>=C|D|G|LW|RW|<null>\n");
       printf("    <cty>=CAN|CIS|FIN|FRA|GBR|GER|HAI|JAM|KOR|LAT|POL|SUI|SWE|TCH|USA|<null>\n");
       return;
    }
   cnt++;
   if (choice >= 0)
    {qsort((char *) players,(unsigned int) n,sizeof(struct statsrec),
           compfuncs[choice]);
     prtlist(choice);
    }
  }
 if (choice == -1)
  {qsort((char *) players,(unsigned int) n,sizeof(struct statsrec),
         compfuncs[0]);
   prtlist(0);
  }
}

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

 putchar('\n');
 if (num != n)
   printf("Top %d ",num);
 if (rookie)
   printf("Rookie ");
 if (choice >= 10)
   printf("%s Leaders",strings[choice]);
 else printf("%s Scorers",strings[choice]);
 if (country[0] != 0)
   printf(" from %s",country);
 if (team[0] != 0)
   printf(" for %s",team);
 if (pos[0] != 0)
   printf(" (%s)",pos);
 if (mingp != 0)
   printf(" [min %d GP]",mingp);
 putchar('\n');
 printf("Rnk  GP Pts");
 if (choice != 8 && choice != 9 && choice != 11)
   printf(" P/g");
 printf("  G");
 if (choice == 8)
   printf(" G/g");
 printf("   A");
 if (choice == 9)
   printf(" A/g");
 printf(" PG SG EG PS PIM");
 if (choice == 11)
   printf(" PM/g");
 printf(" Cty Tm  Ps  #  Player\n");
 printf("---  -- ---");
 if (choice != 8 && choice != 9 && choice != 11)
   printf(" ---");
 printf(" --");
 if (choice == 8)
   printf(" ---");
 printf(" ---");
 if (choice == 9)
   printf(" ---");
 printf(" -- -- -- -- ---");
 if (choice == 11)
   printf(" ----");
 printf(" --- --- -- --  ------\n");
 for (x = y = val = 0; x < n && y < num; x++)
  {p = &players[x];
   switch (choice)
    {case 1:
       if (p->g == 0) return;
       dorank(&val,p->g,&rank,x);
       break;
     case 2:
       if (p->a == 0) return;
       dorank(&val,p->a,&rank,x);
       break;
     case 3:
       if (p->pg == 0) return;
       dorank(&val,p->pg,&rank,x);
       break;
     case 4:
       if (p->sg == 0) return;
       dorank(&val,p->sg,&rank,x);
       break;
     case 5:
       if (p->eg == 0) return;
       dorank(&val,p->eg,&rank,x);
       break;
     case 6:
       if (p->ps == 0) return;
       dorank(&val,p->ps,&rank,x);
       break;
     case 7:
       if (p->ppg == 0.0) return;
       dorank(&val,(int) (p->ppg * 10.0 + 0.5),&rank,x);
       break;
     case 8:
       if (p->gpg == 0.0) return;
       dorank(&val,(int) (p->gpg * 10.0 + 0.5),&rank,x);
       break;
     case 9:
       if (p->apg == 0.0) return;
       dorank(&val,(int) (p->apg * 10.0 + 0.5),&rank,x);
       break;
     case 10:
       if (p->pims == 0) return;
       dorank(&val,p->pims,&rank,x);
       break;
     case 11:
       if (p->pimspg == 0.0) return;
       dorank(&val,(int) (p->pimspg * 10.0 + 0.5),&rank,x);
       break;
     default:
       rank = p->rank;
    }
   if ((team[0] == 0 || strcmp(team,p->team) == 0) && (pos[0] == 0 ||
       strcmp(pos,p->pos) == 0) && (rookie == 0 || p->rookie == '*') &&
       (country[0] == 0 || strcmp(country,p->country) == 0))
    {y++;
     printf("%3d  %2d %3d",rank,p->gp,p->pts);
     if (choice != 8 && choice != 9 && choice != 11)
       printf(" %3.1f",p->ppg);
     printf(" %2d",p->g);
     if (choice == 8)
       printf(" %3.1f",p->gpg);
     printf(" %3d",p->a);
     if (choice == 9)
       printf(" %3.1f",p->apg);
     printf(" %2d %2d %2d %2d %3d",p->pg,p->sg,p->eg,p->ps,p->pims);
     if (choice == 11)
       printf(" %4.1f",p->pimspg);
     printf(" %-3s %-3s %2s %2s %c%s %s\n",p->country,p->team,p->pos,p->num,
            p->rookie,p->first,p->last);
    }
  }
 for (y = 0; x < n; x++)
  {p = &players[x];
   p1 = &players[x-1];
   switch (choice)
    {case 0:
       z = (p->pts == p1->pts);
       break;
     case 1:
       z = (p->g == p1->g);
       break;
     case 2:
       z = (p->a == p1->a);
       break;
     case 3:
       z = (p->pg == p1->pg);
       break;
     case 4:
       z = (p->sg == p1->sg);
       break;
     case 5:
       z = (p->eg == p1->eg);
       break;
     case 6:
       z = (p->ps == p1->ps);
       break;
     case 7:
       z = (p->ppg == p1->ppg);
       break;
     case 8:
       z = (p->gpg == p1->gpg);
       break;
     case 9:
       z = (p->apg == p1->apg);
       break;
     case 10:
       z = (p->pims == p1->pims);
       break;
     case 11:
       z = (p->pimspg == p1->pimspg);
       break;
    }
   if (z)
     y += ((team[0] == 0 || strcmp(team,p->team) == 0) && (pos[0] == 0 ||
       strcmp(pos,p->pos) == 0) && (rookie == 0 || p->rookie == '*') &&
       (country[0] == 0 || strcmp(country,p->country) == 0));
   else break;
  }
 if (y)
  {printf("%d other",y);
   if (y != 1)
     putchar('s');
   printf(" tied\n",y);
  }
}

dorank(val,pval,rank,x)
  int *val, pval, *rank, x;
{if (*val != pval)
  {*rank = x+1;
   *val = pval;
  }
}

domingp(e1,e2)
  struct statsrec *e1, *e2;
{if (e1->gp < mingp && e2->gp >= mingp)
   return 1;
 if (e1->gp >= mingp && e2->gp < mingp)
   return -1;
 return 0;
}

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

 if ((d = domingp(e1,e2)) != 0)
   return d;
 if (e1->pts < e2->pts) return 1;
 if (e1->pts > e2->pts) return -1;
 if (e1->g < e2->g) return 1;
 if (e1->g > e2->g) return -1;
 return strcmp(e1->last,e2->last);
}

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

 if ((d = domingp(e1,e2)) != 0)
   return d;
 if (e1->ppg < e2->ppg) return 1;
 if (e1->ppg > e2->ppg) return -1;
 return comppts(e1,e2);
}

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

 if ((d = domingp(e1,e2)) != 0)
   return d;
 if (e1->gpg < e2->gpg) return 1;
 if (e1->gpg > e2->gpg) return -1;
 return comppts(e1,e2);
}

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

 if ((d = domingp(e1,e2)) != 0)
   return d;
 if (e1->apg < e2->apg) return 1;
 if (e1->apg > e2->apg) return -1;
 return comppts(e1,e2);
}

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

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

 if ((d = domingp(e1,e2)) != 0)
   return d;
 if (e1->g < e2->g) return 1;
 if (e1->g > e2->g) return -1;
 dopts(e1,e2);
}

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

 if ((d = domingp(e1,e2)) != 0)
   return d;
 if (e1->a < e2->a) return 1;
 if (e1->a > e2->a) return -1;
 dopts(e1,e2);
}

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

 if ((d = domingp(e1,e2)) != 0)
   return d;
 if (e1->pg < e2->pg) return 1;
 if (e1->pg > e2->pg) return -1;
 dopts(e1,e2);
}

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

 if ((d = domingp(e1,e2)) != 0)
   return d;
 if (e1->sg < e2->sg) return 1;
 if (e1->sg > e2->sg) return -1;
 dopts(e1,e2);
}

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

 if ((d = domingp(e1,e2)) != 0)
   return d;
 if (e1->eg < e2->eg) return 1;
 if (e1->eg > e2->eg) return -1;
 dopts(e1,e2);
}

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

 if ((d = domingp(e1,e2)) != 0)
   return d;
 if (e1->ps < e2->ps) return 1;
 if (e1->ps > e2->ps) return -1;
 dopts(e1,e2);
}

comppims(e1,e2)
  struct statsrec *e1, *e2;
{if (e1->pims < e2->pims) return 1;
 if (e1->pims > e2->pims) return -1;
 return comppts(e1,e2);
}

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

 if ((d = domingp(e1,e2)) != 0)
   return d;
 if (e1->pimspg < e2->pimspg) return 1;
 if (e1->pimspg > e2->pimspg) return -1;
 return comppts(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;
      }
}
*/
