/* 
   A program to create an sc spreadsheet from a namelist file 
   required by the submit program 
  
      Bill Bynum
      December 1997

*/
#include <stdio.h>
#define __USE_FIXED_PROTOTYPES__
extern int fprintf(FILE*, const char*,...);
extern int printf(const char*,...);
extern int fputc(int,FILE*);
extern int fseek(FILE*,long,int);

#define BUFSIZE 1024
#define COMMENTLINE 2
#define OKLINE 1
#define EOFLINE 0

#define FIRSTSTUDENTLINE 4

char  classtitle[BUFSIZE];
char  buf[BUFSIZE];

char *fix_classtitle(char *buf)
{
char *cp = buf;
int  len;   
   if (cp[0] != '#') return NULL;
   cp++;
   while (*cp == ' ') cp++;
   len = strlen(cp);
   cp[len-1] = '\0';
   return cp; 
}
   
int read_line(FILE *fp, char *buf)
/* read a line from the file into the buffer */
/* blow off empty lines comment lines    */
/* return 1 if line was read successfully, 0 otherwise */
{
char *cp;
   for (;;) {
      cp = fgets(buf,BUFSIZE,fp);
      if (cp == NULL) return EOFLINE;
      switch (buf[0]) {
         case '#':   return COMMENTLINE;
         case '\n':  break; /* keep looping */
         default:    return OKLINE;
      }
   }
}  


void find_name_and_ids(char *buf, char **nameptr, char** uidptr,char** midptr)
{
char *p = buf;
   while ((*p == ' ')||(*p == '\t')) p++;  /* blow off leading blanks, tabs */
   *uidptr = p;
   while ((*p != '\n') && (*p != ' ') && (*p != '\t')) p++;
   *p++ = '\0';
   while ((*p == ' ')||(*p == '\t')) p++;  /* blow off leading blanks, tabs */
   *midptr = p;
   while ((*p != '\n') && (*p != ' ') && (*p != '\t')) p++;
   *p++ = '\0';
   while ((*p == ' ')||(*p == '\t')) p++;  /* blow off leading blanks, tabs */
   *nameptr = p;
   while (*p != '\n') p++;
   *p = '\0';
}

void get_lengths_and_title(FILE *fp,char *filename,char* classtitle,
   int *maxname, int *maxuid, int* maxmailid, int* studentct)
{
int len, ret;
char *nameptr;
char *uidptr;
char *midptr;
   *studentct = *maxname = *maxuid = *maxmailid = 0;
   ret = read_line(fp, classtitle);
   if (ret == EOFLINE){
      fprintf(stderr,"Could not find class title in file \"%s\"\n",filename);
      exit(1);
   }
   if (ret != COMMENTLINE) {
      fprintf(stderr,"Class title comment was not in file \"%s\"\n",filename);
      exit(1);
   }
   for (;;) {
      while ((ret = read_line(fp,buf)) == COMMENTLINE) ; 
      if (ret == EOFLINE) break;
      (*studentct)++;
      find_name_and_ids(buf,&nameptr,&uidptr,&midptr);
      len = strlen(nameptr);
      if (len > *maxname) *maxname = len;
      len = strlen(uidptr);
      if (len > *maxuid) *maxuid = len;
      len = strlen(midptr);
      if (len > *maxmailid) *maxmailid = len;
   }
}
  

void write_header(char* classtitle, int maxname)
{
   int acol_width = (maxname < 13 ? 14 : maxname+1); 
   printf("# This data file was generated by makegrsc\n");
   printf("# You should not edit it.\n");
   printf("format A %d 0 0\n",acol_width);
   printf("format B 5 0 0\n");
   printf("format C 5 0 0\n");
   printf("format D 5 0 0\n");
   printf("format E 5 0 0\n");
   printf("format F 5 0 0\n");
   printf("format G 5 0 0\n");
   printf("format H 5 0 0\n");
   printf("format I 5 0 0\n");
   printf("format J 6 0 0\n");
   printf("format K 6 1 0\n");
   printf("leftstring A0 = \"%s\"\n",classtitle);
   printf("rightstring B1 = \"Course Grades\"\n");
   printf("rightstring A2 = \"grade\"\n");
   printf("rightstring B2 = \"hw1\"\n");
   printf("rightstring C2 = \"hw2\"\n");
   printf("rightstring D2 = \"hw3\"\n");
   printf("rightstring E2 = \"hw4\"\n");
   printf("rightstring F2 = \"hw5\"\n");
   printf("rightstring G2 = \"hw6\"\n");
   printf("rightstring H2 = \"hw7\"\n");
   printf("rightstring I2 = \"fin\"\n");
   printf("rightstring J2 = \"total\"\n");
   printf("rightstring K2 = \" ave \"\n");
   printf("rightstring A3 = \"Best Possible\"\n");
   printf("let B3 = 100\n");
   printf("let C3 = 100\n");
   printf("let D3 = 100\n");
   printf("let E3 = 100\n");
   printf("let F3 = 100\n");
   printf("let G3 = 100\n");
   printf("let H3 = 100\n");
   printf("let I3 = 300\n");
   printf("let J3 = @sum(B3:I3)\n");
   printf("let K3 = 100*J3/$J$3\n");
}  /* write_header */

void write_students( FILE  *fp)
{
int ret;
int linecnt = FIRSTSTUDENTLINE; 
char *nameptr;
char *uidptr;
char *midptr;
/* need 1 space pad in case neither uid nor email address is there */
   while ((ret = read_line(fp,buf)) == COMMENTLINE) ;
   if (ret == EOFLINE) return;
   for (;;) {
      find_name_and_ids(buf,&nameptr,&uidptr,&midptr);
      printf("leftstring A%d = \"%s\"\n",linecnt,nameptr);
      printf("let B%d = 0\n",linecnt);
      printf("let J%d = @sum(B%d:I%d)\n",linecnt,linecnt,linecnt);
      printf("let K%d = 100*J%d/$J$3\n",linecnt,linecnt);
      linecnt++;
      while ((ret = read_line(fp,buf)) == COMMENTLINE) ;
      if (ret == EOFLINE) return;
   } 
}

void write_footer(int studentct)
{
   int rownum = FIRSTSTUDENTLINE + studentct;
   int rownummi1 = rownum-1;
   int rownumpl1 = rownum+1;
   printf("rightstring A%d = \"Class averages\"\n",rownum);
   printf("rightstring B%d = @fmt(\"%s\",@avg(B%d:B%d))\n",
      rownum,"%3.1f",FIRSTSTUDENTLINE,rownummi1);
   printf("rightstring C%d = @fmt(\"%s\",@avg(C%d:C%d))\n",
      rownum,"%3.1f",FIRSTSTUDENTLINE,rownummi1);
   printf("rightstring D%d = @fmt(\"%s\",@avg(D%d:D%d))\n",
      rownum,"%3.1f",FIRSTSTUDENTLINE,rownummi1);
   printf("rightstring E%d = @fmt(\"%s\",@avg(E%d:E%d))\n",
      rownum,"%3.1f",FIRSTSTUDENTLINE,rownummi1);
   printf("rightstring F%d = @fmt(\"%s\",@avg(F%d:F%d))\n",
      rownum,"%3.1f",FIRSTSTUDENTLINE,rownummi1);
   printf("rightstring G%d = @fmt(\"%s\",@avg(G%d:G%d))\n",
      rownum,"%3.1f",FIRSTSTUDENTLINE,rownummi1);
   printf("rightstring H%d = @fmt(\"%s\",@avg(H%d:H%d))\n",
      rownum,"%3.1f",FIRSTSTUDENTLINE,rownummi1);
   printf("rightstring I%d = @fmt(\"%s\",@avg(I%d:I%d))\n",
      rownum,"%3.1f",FIRSTSTUDENTLINE,rownummi1);
   printf("rightstring J%d = @fmt(\"%s\",@avg(J%d:J%d))\n",
      rownum,"%3.1f",FIRSTSTUDENTLINE,rownummi1);
   printf("rightstring K%d = @fmt(\"%s\",@avg(K%d:K%d))\n",
      rownum,"%3.1f",FIRSTSTUDENTLINE,rownummi1);
   printf("let A%d = @count(B%d:B%d)\n",rownumpl1,FIRSTSTUDENTLINE,rownummi1);
   printf("leftstring B%d = \" students\"\n",rownumpl1);
}

int
main(int argc, char *argv[])
{
   FILE  *fp;
   char  *fnameptr;
   char  *ct;
   int   maxname, maxuid,maxmailid;
   int   studentct;
   int   i;

   if (argc == 1) {
      fprintf(stderr,"Usage: %s <namelist>\n",argv[0]);
      fprintf(stderr,"      makes sc spreadsheet from <namelist>\n");
      fprintf(stderr,"Lines in the <namelist> file are of either of three forms\n");
      fprintf(stderr,"   # comment line (skipped)\n");
      fprintf(stderr,"   userid  emailaddress  Student's_first (zero or more middle) last_names\n");
      fprintf(stderr,"   a_null_line (skipped)\n");
      fprintf(stderr,"The first line of the file is expected to be a comment line\n");
      fprintf(stderr,"   that contains the class title\n");
      exit(1);
   }
   i = 1;
   while (i < argc) {
      if (argv[i][0] != '-') break;
      switch (argv[i][1]) {
         default:
            fprintf(stderr,"invalid option %s\n",argv[i]);
            exit(1);
      }
      i++;
   }
   if (i == argc) {  /* all options, no filename */
      fprintf(stderr,"No file name given!\n");
      exit(1);
   }
   fnameptr = argv[i];
   fp = fopen(fnameptr,"r");
   if (fp == NULL) {
      fprintf(stderr,"Can't open file %s\n",fnameptr);
      exit(1);
   }
   get_lengths_and_title(fp,fnameptr,classtitle,&maxname,&maxuid,&maxmailid,
      &studentct);    
   ct=fix_classtitle(classtitle);
   if (fseek(fp,0L,0) < 0) {
      fprintf(stderr,"Can't reseek to beginning of \"%s\"\n",fnameptr);
      exit(1);
   }
   write_header(ct,maxname);
   write_students(fp);
   write_footer(studentct);
   return 0;
}

/*
 * $Log: makegrsc.c,v $
 * Revision 1.6  1999/07/29 20:38:10  bynum
 * modify header comment
 *
 * Revision 1.5  1998/08/19 13:15:01  bynum
 * change fputc decl to get rid of warning
 *
 * Revision 1.4  1997/12/19 20:45:50  bynum
 * change usage() output
 *
 * Revision 1.3  1997/12/19 20:09:42  bynum
 * correct some row numbering
 *
 * Revision 1.2  1997/12/10 18:03:26  bynum
 * remove extraneous variables and parms, switch to fprint(stderr,..) for
 * error output
 *
 * Revision 1.1  1997/12/08 14:46:56  bynum
 * Initial revision
 *
 */
