/*
   A program to create a class roll from the namelist file required
   by the submit program

      Bill Bynum
      September 1997
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

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

#define LINEWIDTH 88
#define LINESPERPAGE 60
#define LINESPERBLOCK 10

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

char *fix_classtitle(char *buf)
{
char *cp = buf;
int  len;   
   if (cp[0] != '#') return NULL;
   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,
   int *maxname, int *maxuid, int* maxmailid)
{
int len, ret;
char *nameptr;
char *uidptr;
char *midptr;
   *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;
      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;
      if (ret == COMMENTLINE) continue;
   }
}
   
void left_justify(char *s,int width)
{
int len=0;
int i;
   while (*s) { fputc(*s++,stdout);len++; }
   for (i = 0; i < width - len; i++) fputc(' ',stdout);
}

void write_line(char x)
{
int i;
   for (i = 0; i < LINEWIDTH; i++) fputc(x,stdout);
   fputc('\n',stdout);
}

void write_bars(int start)
{
int col = start;
   while (col < LINEWIDTH) {
            /*123456 */
      printf("|     "); col +=6;
   }
   fputc('\n',stdout);
}


int write_a_page(
   FILE  *fp, 
   char  *title, 
   int   *namecnt,
   int   *pageno, 
   int maxname, 
   int maxuid, int maxmid)
{
int linecnt;
int ret;
char *nameptr;
char *uidptr;
char *midptr;
int namewidth = maxname +1;
int uidwidth = (maxuid ? maxuid +1 : 0);
int midwidth = (maxmid ? maxmid +1 : 0);
/* need 1 space pad in case neither uid nor email address is there */
int pad = ((maxuid||maxmid) ? 0 : 1 ); 
int nidwidth = namewidth + uidwidth + midwidth + pad;
   while ((ret = read_line(fp,buf)) == COMMENTLINE) ;
   if (ret == EOFLINE) return 0;
   (*pageno)++;
   if ((*pageno) > 1) fputc(0x0c,stdout);
   printf("%s  p. %d\n\n",title, *pageno);
   left_justify("Quiz name ->",nidwidth); write_bars(nidwidth);
   write_line('-');
   left_justify("Best score ->",nidwidth); write_bars(nidwidth);
   write_line('*');linecnt = 6; 
   for (;;) {
      find_name_and_ids(buf,&nameptr,&uidptr,&midptr);
      left_justify(nameptr,namewidth);
      if (maxuid) 
         left_justify(uidptr,uidwidth);
      if (maxmid) 
         left_justify(midptr,midwidth);
      if ((!maxuid)&&(!maxmid))
         printf(" ");
      write_bars(nidwidth);
      (*namecnt)++;
      linecnt += 2;
      if (((*namecnt) % 5) == 0) 
      {

         write_line('*');
         if ((linecnt + LINESPERBLOCK) > LINESPERPAGE) return 1;
      }
      else
         write_line('-');
      while ((ret = read_line(fp,buf)) == COMMENTLINE) ;
      if (ret == EOFLINE) return 0;
   } 
}
   
int
main(int argc, char *argv[])
{
   FILE  *fp;
   char  *fnameptr;
   char  *ct;
   int   no_uid = 1;
   int   no_mailid = 1;
   int   pageno = 0;
   int   namecnt = 0;
   int   ret;
   int   maxname, maxuid,maxmailid;
   int   i;

   if (argc == 1) {
      fprintf(stderr,"Usage: %s [options] <namelist>\n",argv[0]);
      fprintf(stderr,"      makes class roll 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 (possibly 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");
      fprintf(stderr,"Options:\n");
      fprintf(stderr,"   -u  ==>  include the user id in the roll\n");
      fprintf(stderr,"   -e  ==>  include the e-mail address in the roll\n");
      fprintf(stderr,"   default ==> don't include user id or e-mail address\n");
      exit(1);
   }
   i = 1;
   while (i < argc) {
      if (argv[i][0] != '-') break;
      switch (argv[i][1]) {
         case 'u': no_uid = 0; break;
         case 'e': no_mailid = 0; break;
         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,&maxname,&maxuid,&maxmailid);    
   if (no_uid) maxuid = 0;
   if (no_mailid) maxmailid = 0;
   ct=fix_classtitle(classtitle);
   if (fseek(fp,0L,0) < 0) {
      fprintf(stderr,"Can't reseek to beginning of \"%s\"\n",fnameptr);
      exit(1);
   }
   ret = read_line(fp,buf); /* blow off first line, we have it */
   while (write_a_page(fp,ct,&namecnt,&pageno,maxname,maxuid,maxmailid));
   return 0;
}

/*
 * $Log: makeroll.c,v $
 * Revision 1.8  1999/07/29 20:36:49  bynum
 * add header comment
 *
 * Revision 1.7  1998/08/19 13:15:25  bynum
 * change fputc decl to get rid of warning
 *
 * Revision 1.6  1997/12/10 18:14:19  bynum
 * switch to fprintf(stderr,..) for all error output
 *
 * Revision 1.5  1997/12/08 12:20:50  bynum
 * replace argv[1] with fnameptr in a couple of places
 *
 * Revision 1.4  1997/09/04 05:53:32  bynum
 * fix blank padding for all combinations of -u and -e options
 *
 * Revision 1.3  1997/09/03  20:04:33  bynum
 * add log comment
 *
 */

