#ifndef lint
static char Sccsid[] = "@(#)cardfile.c	3.2    DeltaDate 12/9/90    ExtrDate 12/9/90";
#endif

/*      CARDFILE.C      */
/*      This is the main routine for cardfile
*/
#include	"ascii.h"
#include	"stdio.h"
#include	"cardfile.h"
#include	<signal.h>

#define FIND    0
#define ADD     1
#define CHANGE  2
#define DELETE  3
#define PRINT   4
#define MAINT   5
#define EXIT    6

FILE    *def_fp;
int	readonly;
char    fname[FNSIZE];
extern  char *getfield();
char    *functs[]    = {"FIND       ",
			"ADD        ",
			"CHANGE     ",
			"DELETE     ",
			"PRINT      ",
			"MAINTENANCE",
			"EXIT       ",
			0
			};

char	datadir[FNSIZE];
char	*dbname;
void	setupscr();
void	exit();
unsigned sleep();
static	usage();

main(argc, argv)
int     argc;
char    **argv;
{
    int 	num_flds, i;
    char	line_buf[133];
    struct      Fdata fields[MAXFLDS+1], *fp;
    int 	num_ak;
    struct      AKdata ak_data[MAXAK+1];
    int		fn;
    int 	func;
    char	*cp;
    extern char *optarg;
    extern int optind, opterr;
    
    opterr = 0;
    while ((i = getopt(argc, argv, "r")) != EOF) {
	switch (i) {
	case 'r':
	    ++readonly;
	    break;
	case '?':
	    usage(argv[0]);
	    exit(1);
	}
    }
    if (optind != argc-1) {
	usage(argv[0]);
	exit(1);
    }
    signal(SIGINT, getout);
    signal(SIGQUIT, getout);
    signal(SIGTERM, getout);
    setupscr();		/* from here on use getout, not exit to reset screen */
    if ((cp = strrchr(argv[optind], '/')) != NULL) {
	*cp = '\0';
	sprintf(datadir, "%s/", argv[optind]);
	dbname = cp + 1;
    } else {
	*datadir = '\0';
	dbname = argv[optind];
    }
    if (strlen(dbname) > 10) {
	printf("Database name cannot be longer than 10 characters.\n");
	sleep(5);
	getout();
    }
    /* build definition file name */
    sprintf(fname, "%s%s.def", datadir, dbname);
    if ((def_fp = fopen(fname,"r")) == NULL) {
	db_define(dbname);
	getout();
    }
    /* The format of the definition file is:
     * Num_of_fields
     * Field1_Name:Key:Sub_Seps:Req:Data_Len
     * ...
     * Num_of_Alt_Keys
     * Field_Num:AK1_File_Name
     * ...
     * %%
     * Field_Num:Label_Row:Label_Col:Data_Row:Data_Col:Data_Fmt
     * ...
     */
    if (fgets(line_buf, 132, def_fp) == NULL) {
	printf("Unable to read DEF file\n");
	sleep(5);
	getout();
    }
    if (! readonly && access(fname, 06) != 0) {
	printf("You can not write to the database, try\n%s -r %s%s\n",
	    argv[0], datadir, dbname);
	sleep(5);
	getout();
    }
    strcpy(fname, getfield(line_buf, ":"));
    num_flds = atoi(getfield(0, ":"));

    /* get definition of each field */
    for (i = 0, fp = &fields[0]; i < num_flds; i++, fp++) {
	if (fgets(line_buf, 132, def_fp) == NULL) {
	    printf("DEF file syntax error, field defs\n");
	    sleep(5);
	    getout();
	}
	strcpy(fp->F_title, getfield(line_buf, ":"));
	fp->F_key = *getfield(0, ":");
	strcpy(fp->F_seps, getfield(0, ":"));
	fp->F_required = *getfield(0, ":");
	fp->F_length = atoi(getfield(0, ":"));
	/* set defaults */
	fp->F_page = -1;
	fp->F_Lrow = -1;
	fp->F_Lcol = -1;
	fp->F_Drow = -1;
	fp->F_Dcol = -1;
	fp->F_Dfmt[0] = '\0';
    }
    fp->F_title[0] = '\0';

    fgets(line_buf, 10, def_fp);
    num_ak = atoi(line_buf);
    for (i=0; i<num_ak; i++) {          /* get definition of each AK file */
	if (fgets(line_buf, 132, def_fp) == NULL) {
	    printf("DEF file syntax error, AK files\n");
	    sleep(5);
	    getout();
	}
	line_buf[strlen(line_buf)-1] = '\0';	/* truncate newline */
	ak_data[i].A_fldnum = atoi(getfield(line_buf, ":"));
	strcpy(ak_data[i].A_akname, getfield(0, ":"));
    }
    ak_data[i].A_fldnum = -1;

    fgets(line_buf, 10, def_fp);
    if (strcmp(line_buf, "%%\n") == 0) {
	for (i=0; i<num_flds; i++) {	/* Get screen layout for each field */
	    if (fgets(line_buf, 132, def_fp) == NULL) {
		break;
	    }
	    line_buf[strlen(line_buf)-1] = '\0';	/* truncate newline */
	    fn = atoi(getfield(line_buf, ":"));
	    if (fn < 0 || fn >= num_flds) {
		printf("DEF file syntax error, screen layout\n");
		sleep(5);
		getout();
	    }
	    if ((cp = getfield(0, ":")) != NULL && *cp != '\0')
		fields[fn].F_page = atoi(cp);
	    if ((cp = getfield(0, ":")) != NULL && *cp != '\0')
		fields[fn].F_Lrow = atoi(cp);
	    if ((cp = getfield(0, ":")) != NULL && *cp != '\0')
		fields[fn].F_Lcol = atoi(cp);
	    if ((cp = getfield(0, ":")) != NULL && *cp != '\0')
		fields[fn].F_Drow = atoi(cp);
	    if ((cp = getfield(0, ":")) != NULL && *cp != '\0')
		fields[fn].F_Dcol = atoi(cp);
	    if ((cp = getfield(0, ":")) != NULL) {
		strcpy(fields[fn].F_Dfmt, cp);
	    }
	}
    }
    fclose(def_fp);
#ifdef DEBUG
    fprintf(stderr, "%d fields in the %s database\n", num_flds, dbname);
    for (i=0; i<num_flds; ++i) {
	fprintf(stderr, "%8d  %s\n", i, fields[i].F_title);
    }
#endif
    
    /* get function to be performed */
    while ((func = menu(dbname, functs)) != EXIT) {
	switch (func) {
	case FIND:
	    find(fields, dbname);
	    continue;
	case ADD:
	    add(fields, dbname);
	    continue;
	case CHANGE:
	    change(fields, dbname);
	    continue;
	case DELETE:
	    delete(fields, dbname);
	    continue;
	case PRINT:
	    printdb(fields, dbname);
	    continue;
	case MAINT:
	    maint(fields, dbname, ak_data);
	    continue;
	default:
	    msg("Illegal function chosen");
	    getout();
	}
    }
    getout();
/*NOTREACHED*/
}


static
usage(prog)
char	*prog;
{
    printf("Usage: %s [-r] file\n", prog);
}
