/* Generate all CAPA Ids for a class
   Copyright (C) 1992-2000 Michigan State University

   The CAPA system is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The CAPA system is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public
   License along with the CAPA system; see the file COPYING.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.

   As a special exception, you have permission to link this program
   with the TtH/TtM library and distribute executables, as long as you
   follow the requirements of the GNU GPL in regard to all of the
   software in the executable aside from TtH/TtM.
*/

/* ========================================================================== */
/*            allcapaid.c    created by Isaac Tsai                            */
/**************************************************************************** */
#ifdef NeXT
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>  
#else
#include <malloc.h>
double atof();
#endif

#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>  
 
#include <signal.h>
#include <time.h>
#include <math.h>
#include <string.h>
#ifdef NeXT
#include <bsd/curses.h>
#else
#include <curses.h>
#endif
#define   YES    1

#include "capaCommon.h"
#include "ranlib.h"

char  *progname;

/* filter out the number to be [1:999] */
int  scan_num(char *num_str,int *first, int *second) {
  char  tmp_str[SMALL_LINE_BUFFER], *ch;
  int   ii=0, a_num, b_num, result=0;
  
  ch = num_str;
  tmp_str[ii] = 0;
  while( isspace(*ch) ) ch++;
  while(isdigit(*ch)) { tmp_str[ii++] = *ch; ch++; }
  tmp_str[ii] = 0;
  sscanf(tmp_str,"%d",&a_num);
  if( a_num < 0 || a_num > 999 ) a_num = 1;
  *first = a_num;
  result = 1;
  while( isspace(*ch) ) ch++;
  if( *ch == ':' ) {
    ch++;
    while( isspace(*ch) ) ch++;
    ii=0; tmp_str[ii] = 0;
    while( isdigit(*ch) ) { tmp_str[ii++] = *ch; ch++; }
    tmp_str[ii] = 0;
    sscanf(tmp_str,"%d",&b_num);
    if( b_num < 0 || b_num > 999 ) b_num = 1;
    if( a_num > b_num )           b_num = a_num;
    *second = b_num;
    result = 2;
  }
  return (result);
}

void print_capaidplus (FILE *out,char* stunum,int set,int plus) 
{
  char fmt[SMALL_LINE_BUFFER];
  sprintf(fmt,"%%%dc",4+plus);
  fprintf(out,"%s ", capa_id_plus(stunum, set, plus));
}

void print_capaidplus_header1(FILE *dfp,int StartSet,int EndSet,int plus)
{
  int pluscnt,setIdx;
  for(setIdx = StartSet; setIdx <= EndSet; setIdx++)   
    {
      fprintf(dfp,"%3d",setIdx);
      for(pluscnt=0; pluscnt < (plus+2); pluscnt++)
	fprintf(dfp," ");
    }
}

void print_capaidplus_header2(FILE *dfp,int StartSet,int EndSet,int plus)
{
  int setIdx,pluscnt;
  for(setIdx = StartSet; setIdx <= EndSet; setIdx++) {
    for(pluscnt=0; pluscnt < (plus+4); pluscnt++)
      fprintf(dfp,"-");
    fprintf(dfp,"|");
  }
}

void usage()
{
  printf("USAGE: %s [-s start-set] [-e end-set] [-stu student-number] [-c class-directory] [-d output-directory] [-h] [-i] [-p number] [-sec [n|n:m]]\n", progname);
  printf("       start-set : default 1\n");
  printf("       end-set   : default 10\n");
  printf("       student-number  : no default\n");
  printf("       class-directory : no default\n");
  printf("       output-directory: class-directory/capaID\n");
  printf("       -Sec 3          : for section 3\n");
  printf("       -Sec 3:7        : from section 3 to section 7\n");
  printf("       -i              : don't create files, print to the screen\n");
  printf("       -p 2            : output 6 charatcer capaidplus instead of capaid\n");
  printf("       -checkopen      : check if set is open, fail if it isn't.\n");
  printf("       -checkdue       : check if set is due, fail if it isn't.\n");
  printf("       -checkans       : check if set's answers are available, fail if they aren't.\n");
  printf("       -h              : prints this message\n");
  printf("       CAPA version %s, %s\n",CAPA_VER,COMPILE_DATE);
  printf("       CAPA is released under the GNU GPL v2 see COPYING for details.\n");
}
#define  F_CLASS       1
#define  F_SECTIONS    2
#define  F_STUDENT     3
int main (int argc, char  **argv) 
{
  T_student  *students_p,*s_p,student_data;
  int         i, setIdx, numStudents, count, tmp_num, StartSec=1,EndSec=999;
  int         StartSet = 1, EndSet = 10, classnameOK=0,outputDir=0,plus=0;
  int         SecCntArry[MAX_SECTION_COUNT], sectionIdx;   
  char        filename[MAX_BUFFER_SIZE], path[MAX_BUFFER_SIZE], 
    outputPath[MAX_BUFFER_SIZE], fullpath[MAX_BUFFER_SIZE];
  char        StuNum[MAX_STUDENT_NUMBER+1], fmt[16];
  int         ForWhat=F_CLASS, interactive=0,CheckOpen=0,CheckDue=0,CheckAns=0;
  FILE       *dfp;
  
  if( argc == 0 ) {
    usage();
    exit(0);
  }
  
  for( progname = *argv++; --argc; argv++) {
    if ( argv[0][0] == '-' && (strlen(argv[0]) > 1 ) ) {
      switch(argv[0][1]) {
      case 'S':
      case 's':
	if( strncasecmp(argv[0],"-stu",4) == 0 ) {
	  for(i=0;i<MAX_STUDENT_NUMBER;i++) {
	    StuNum[i] = argv[1][i];
	  }
	  StuNum[i]=0;
	  ForWhat = F_STUDENT;
	} else if( strncasecmp(argv[0],"-sec",4) == 0 ) {
	  tmp_num = scan_num(argv[1],&StartSec,&EndSec);
	  if (tmp_num == 1 ) { EndSec = StartSec;  }
	  ForWhat = F_SECTIONS;
	} else if( strncasecmp(argv[0],"-s",2) == 0 ) {
	  StartSet = atol(argv[1]);
	  if( StartSet <= 0 ) StartSet = 1;
	}
	break;
      case 'p':
        plus = atol(argv[1]);
	break;
      case 'e':
	EndSet = atol(argv[1]);
	if( EndSet > 999 ) EndSet = 99;
	break;
      case 'c':
	if (strcmp(argv[0],"-checkopen")==0) { CheckOpen=1; break; }
	if (strcmp(argv[0],"-checkdue" )==0) { CheckDue=1;  break; }
	if (strcmp(argv[0],"-checkans" )==0) { CheckAns=1;  break; }
	strcpy(path,argv[1]);
	if( capa_access(path, F_OK) == -1 ) {
	  printf("No such class [%s] please specify it again:\n",path);
	  classnameOK = 0;
	} else {
	  classnameOK = 1;
	}
	break;
      case 'i':
	interactive = 1; 
	break;
      case 'd':
	strcpy(outputPath,argv[1]);
	outputDir=1;
	break;
      case 'u': case 'h': default:
	usage(); 
	exit(0);
	break;
      }
    }
  }
  if( StartSet > EndSet ) StartSet = EndSet;
  while ( !classnameOK ) {
    puts("Enter the ABSOLUTE path of class from root (/)");
    scanf("%s", path);
    if( capa_access(path, F_OK) == -1 ) {
      printf("No such class, please specify it again:\n");
    } else {
      classnameOK = 1;
    }
  }
  
  if (!interactive) {
    if (outputDir) {
      sprintf(fullpath,"%s",outputPath);
    } else {
      sprintf(fullpath,"%s/capaID",path);
    }
    if( capa_access(fullpath, F_OK) == -1 ) {
      if ( mkdir(fullpath, S_IREAD | S_IWRITE | S_IEXEC ) == -1 ) {
	printf("Unable to write to %s\n",fullpath);
	printf("Please check this directory and run %s again.\n",progname);
	return(-1);
      }
    }
  }
  
  chdir(path);
  switch(ForWhat) {
  case F_STUDENT:
    printf("\n");
    for(setIdx = StartSet; setIdx <= EndSet; setIdx++) {
      printf("%4d ", setIdx );
    }
    printf("\n");
    if (CheckOpen || CheckDue || CheckAns) {
      sprintf(fmt,"%%%ds ",plus+4);
      if ( capa_get_student(StuNum,&student_data) == 0 ) {
	fprintf(stderr,"Unable to find student, %s.\n",StuNum);
	exit(1);
      }
    }
    for(setIdx = StartSet; setIdx <= EndSet; setIdx++) {
      if ( CheckOpen && ( capa_check_date(CHECK_OPEN_DATE,StuNum,
					  student_data.s_sec,setIdx) < 0)) {
	printf(fmt,"Open");continue;
      }
      if ( CheckDue && ( capa_check_date(CHECK_DUE_DATE,StuNum,
					  student_data.s_sec,setIdx) < 0)) {
	printf(fmt,"Due");continue;
      }
      if ( CheckAns && ( capa_check_date(CHECK_ANS_DATE,StuNum,
					  student_data.s_sec,setIdx) < 0)) {
	printf(fmt,"Ans");continue;
      }
      if (plus) 
	print_capaidplus(stdout,StuNum,setIdx,plus);
      else 
	printf("%4d ", capa_PIN(StuNum, setIdx,0) );
    }
    printf("\n"); fflush(stdout);
    break;
  case F_CLASS:
    StartSec=1;EndSec=999;
  case F_SECTIONS:
    if (CheckOpen || CheckDue || CheckAns) {
      printf("Can only check dates in single student mode\n");
    }
    if ((count = capa_get_section_count( SecCntArry )) != 0 ) {
      if (count == -1 ) {
	printf("classl file not found in %s\n",path);
	exit (-1);
      }
      for(sectionIdx = StartSec; 
	  (sectionIdx <= SecCntArry[0]) && (sectionIdx <= EndSec);
	  sectionIdx++) {
	if( SecCntArry[sectionIdx] > 0 ) {
	  if ( interactive ) {
	    dfp=stdout;
	  } else {
	    sprintf(filename,"%s/section%d.capaid",fullpath,sectionIdx);
	    if((dfp=fopen(filename,"w"))==NULL) {
	      printf("Unable to create %s\n",filename);
	      exit(-2);
	    }
	  }
	  
	  numStudents = capa_get_section(&students_p, sectionIdx);
	  printf("Section %d, %d students\n",
		 sectionIdx, numStudents);
	  
	  fprintf(dfp,"Section %d   Student    NAME      NUMBER   ",sectionIdx);
	  if (plus) {
	    print_capaidplus_header1(dfp,StartSet,EndSet,plus);
	  } else {
	    for(setIdx = StartSet; setIdx <= EndSet; setIdx++)   
	      fprintf(dfp,"%3d  ",setIdx);
	  }
	  
	  fprintf(dfp,"\n");
	  fprintf(dfp,"------------------------------|----------|");
	  if (plus) {
	    print_capaidplus_header2(dfp,StartSet,EndSet,plus);
	  } else {
	    for(setIdx = StartSet; setIdx <= EndSet; setIdx++) 
	      fprintf(dfp,"----|");
	  }
	  fprintf(dfp,"\n");
	  for(s_p = students_p; s_p ; s_p = s_p->s_next ) {
	    fprintf(dfp,"%s %s  ",s_p->s_nm, s_p->s_sn);
	    for(setIdx = StartSet; setIdx <= EndSet; setIdx++) {
	      if (plus) 
		print_capaidplus(dfp,s_p->s_sn,setIdx,plus);
	      else 
		fprintf(dfp,"%4d ", capa_PIN(s_p->s_sn, setIdx,0) );
	    }
	    fprintf(dfp,"\n");
	  }
	  fflush(dfp);
	  if (!interactive) fclose(dfp); 
	}
      }
    }
  }
  return (0);
}

