/************************************************************************
 *									*
 *			MAKE_README.C					*
 *									*
 * MAKE_README.C contains the code for constructing the formatted  	*
 * README file from the Citation Database.  The functions reformat 	*
 * the "refer" (or "bib") entries to a more presentable format.    	*
 *									*
 ************************************************************************/


/************************************************************************
 ***								      ***
 ***		INTERFACE of file:				      ***
 ***								      ***
 ************************************************************************/

/***********************************************			*/
/* Header files and libraries utilized: 				*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "techrep.h"
#include "sitespec.h"
#include "util.h"
#include "citation.h"
#include "make_readme.h"


/***********************************************			*/
/* constant definitions:						*/

#define NIL	  '\0'
#define SPACE	   ' '

/* maximum string lengths:  */
#define MAXFIELD   300
#define MAXAUTH	   200
#define SH_FIELD    80
#define MAXSTRING  500
#define WORDLENGTH  50
#define STD_STRING_SIZE 80

/* special unique delimiter to separate tech. rep. number from other	*
 * fields:								*/
#define LEFT_MARKER_STR   "["
#define LEFT_MARKER_CHAR  '['
#define RIGHT_MARKER_STR  "]"
#define RIGHT_MARKER_CHAR ']'

/* offset to beginning of actual string, leading off header info...	*/
#define OFFSET       3

/* maximum line length for formatted output				*/
#define MAX_LINE    80


/**********************************************				*/
/* Internal function declarations:					*/

void append_author ( char *, char *, char * );
void make_field ( char *, char * );
void convert_format ( char *, char * );
void construct_file ( char *, char * );
void make_formatted_citation_list(char *, char *);




/************************************************************************
 ***								      ***
 ***		IMPLEMENTATION follows:				      ***
 ***								      ***
 ************************************************************************/


/* void append_author(char *, char *, char *) is a funct. that updates	*
 *  the temporary author lists automatically.  We maintain two author	*
 *  structures for later formatting.  "authors" is a comma delimited	*
 *  list of all authors up to but not including the most recent one.	*
 *  "last_author" is the most recent author that will be appended at	*
 *  the end of the citation with an "and".  This allows for 		*
 *  appropriate formatting.	     					*/

void append_author ( char *authors, char *last_author, char *buffer)
{
    /* if this is the first author encountered: 			*/
    if ( last_author[0] == NIL ) {
	/* make last_author equal to the new "input author"		*/
	strcpy ( last_author, buffer );
	return;
    }

    /* otherwise, check to see if authors contains any elements:       	*/
    if ( authors[0] == NIL ) {
	/* move the old author into the "authors" string and update	*
	 * the "last_author" field:					*/
	strcpy ( authors, last_author );
	strcpy ( last_author, buffer );
	return;
    }

    /* otherwise, we have the general case of third or greater author	*/
    else {
	/* in general, we move the old "last_author" to the "author"	*
	 * list by adding it on in a comma-delimited fashion.  We then	*
	 * can update the last_author field.				*/
	strcat ( authors, ", ");
	strcat ( authors, last_author );
	strcpy ( last_author, buffer );
    }
}



/* void make_field(char *, char *) is a procedure that simply copies 	*
   the buffer to the appropriate field passed in to "field".		*/

void make_field ( char *field, char *buffer )
{
    strcpy ( field, buffer );
}


/* void skip_info ( FILE * ) is a procedure that skips over the		*
 * multi-line informational segments that contain abstracts (%X), and	*
 * credits (%x).							*/



/* void convert_format (char *) takes the name of the Citation Database	*
 * file as input and produces a README-style output file to use for	*
 * screen output in the file by the name out_fname.			*/

void convert_format ( char *cit_fname, char *out_fname )
{
    FILE *cit_file;	/* the input citation file (in "refer" format)	*/
    FILE *out_file;	/* the README style output file			*/

    char buffer[MAXFIELD];  /* buffer to hold a line temporarily	*/

    char authors[MAXFIELD]; /* list of authors, delimited "," or "and"	*/
    char rec_auth[MAXAUTH]; /* most recent author encountered		*/
    char title[MAXFIELD];   /* title of report...		       	*/
    char trnum[SH_FIELD];   /* tech report number (for sorting)...     	*/
    char date[SH_FIELD];    /* date of tech report...			*/

    char out_string[MAXSTRING];  /* output for each entry for sorting 	*/

    short done = FALSE; /* boolean variable that is set to true on EOF	*/

    if ( ( cit_file = fopen ( cit_fname, "r" ) ) == NULL ) {
	printf("Could not find citation database file...");
	return;
    }

    if ( ( out_file = fopen ( out_fname, "w" ) ) == NULL ) {
	printf("Not enough room to create output file in CONVERT_FORMAT...");
	return;
    }

    /* loop through all citation entries...				*/
    while ( fgets ( buffer, MAXFIELD, cit_file ) ) {

	/* initialize all of our strings to NIL:		       	*/
	authors[0] = rec_auth[0] = title[0] = 
	    trnum[0] = date[0] = rec_auth[0] = NIL;

	/* loop until we reach a NEWLINE (end of citation entry) or the	*
	 * end of the database...					*/
	while ( ( buffer[0] != '\n' ) && !done) {

	    /* strip the newline character off of the string:		*/
	    buffer[ strlen(buffer) - 1 ] = NIL;

	    /* find out the type of entry:				*/
	    switch ( buffer[1] ) {
	      case REF_AUTHOR:
		if ( buffer[0] == '%')
		    append_author ( authors, rec_auth, buffer + OFFSET );
		break;
	      case REF_TITLE:
		if ( buffer[0] == '%')
		    make_field ( title, buffer + OFFSET );
		break;
	      case REF_REPORT:
		if ( buffer[0] == '%')
		    make_field ( trnum, buffer + OFFSET );
		break;
	      case REF_DATE:
		if ( buffer[0] == '%')
		    make_field ( date, buffer + OFFSET );
		break;
	      case REF_ABSTRACT:
	      case REF_KEYWORDS:
	      case REF_LASTMOD:
	      default:
		break;
	    }

	    /* check to see if we have reached the end-of-file */
	    if ( !fgets ( buffer, MAXFIELD, cit_file ) )
		done = TRUE;
	}

	/* we now create the appropriate output string for sorting:	*/

	/* place the tech. rep. number in appropriate format:		*/

	/* delimit the technical report number appropriately:		*/
	strcpy  ( out_string, LEFT_MARKER_STR );
	strcat ( out_string, trnum );
	strcat ( out_string, RIGHT_MARKER_STR );

	/* print remaining fields with appropriate format:		*/
	if ( ( authors[0] != NIL ) && ( authors[0] != '\n' ) ) {
	    strcat ( out_string, authors );
	    strcat ( out_string, " and " );
	    strcat ( out_string, rec_auth );
	}
	else {
	    strcat ( out_string, rec_auth );
	}
	strcat ( out_string, ", " );
	strcat ( out_string, title );
	strcat ( out_string, ", " );
	strcat ( out_string, date );
	strcat ( out_string, ".\n" );

	/* print this string to a file for sorting...			*/
	fprintf( out_file, "%s", out_string );
    }

    fclose( cit_file );
    fclose( out_file ); 
}




/* void construct_file(char *) is the file that actually constructs the	*
 * README file.  It first prints out the header "instruction text", and	*
 * then it prints out the sorted list from the file whose name is 	*
 * passed in as a parameter.  We print out the technical report number	*
 * on one line, and then the rest of the string is printed on following	*
 * lines, wrapped around at spaces between words.			*/

void construct_file ( char *source_name, char *dest_name )
{
    FILE *source_file;		/* sorted list whose name was passed in	  */
    FILE *dest_file;		/* dest_file is README...		  */

    char buffer[MAXSTRING];	/* buffer holding individual report names */
    char temp_buff[WORDLENGTH]; /* buffer to hold individual words	  */

    int counter, index, length; /* dummy counters keeping track of where   *
				 * we are in the procedure.  "counter"	   *
				 * keeps track of where we are in the main *
				 * string, "index" where we are in the     *
				 * current word, and "length" how far down *
				 * the line of text we are => newline...   */


    if ( ( source_file = fopen ( source_name, "r" ) ) == NULL ) {
	printf("Could not find file in CONSTRUCT_FILE...");
	return;
    }

    if ( ( dest_file = fopen ( dest_name, "w" ) ) == NULL ) {
	printf("Not enough room to create README file in CONSTRUCT_FILE...");
	return;
    }


    /* the following is the header information of the README file... 	*/
/*	$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$	*/



    /* loop while there are more citations to be printed		*/
    while ( fgets ( buffer, MAXSTRING, source_file ) ) {
	
	/* set the counter (keeping track within "buffer") to 0.	*/
	counter = 0;

	/* read the technical report number... */
	while ( buffer [counter] != RIGHT_MARKER_CHAR ) {
	    temp_buff [counter] = buffer [counter];
	    counter++;
	}

	/* read the right delimiter in... */
	temp_buff [counter] = buffer [counter];
	counter++;
	
	/* close off the temporary string... */
	temp_buff [counter] = NIL;

	/* write the tech report number to file */
	fprintf ( dest_file, "\n%s\n          ", temp_buff );

	/* this is the standard starting length at beginning of line */
	length = 10 ;

	/* loop until we have no more input: */
	while ( buffer [counter] != '\n' ) {

	    /* set the word length to 0 */
	    index = 0;

	    /* read characters until we get to the end of the word: */
	    while ( ( buffer [counter] != SPACE ) && 
		    ( buffer [counter] != '\n' ) ) {
		temp_buff [index++] = buffer [counter++];
		length++;
	    }
	    /* again, close off the temporary string */
	    temp_buff [index] = NIL;

	    /* check to see if we need a new line */
	    if ( length >= MAX_LINE ) {
		fprintf ( dest_file, "\n          %s ", temp_buff );
		length = 10 + strlen ( temp_buff ) + 1;
	    }
	    else {
		fprintf ( dest_file, "%s ", temp_buff );
		length++;
	    }

	    /* check to see if there are more words... */
	    if ( buffer [counter] == SPACE )
	      counter++;
	}
	fprintf ( dest_file,"\n");
    }

    fclose ( source_file );
    fclose ( dest_file );
}





void find_single_entry ( char *fname, char *dest_name )
{
    FILE *source_file;		/* sorted list whose name was passed in	  */
    FILE *dest_file;		/* dest_file is README...		  */

    char buffer[MAXSTRING];	/* buffer holding individual report names */
    char temp_buff[WORDLENGTH]; /* buffer to hold individual words	  */

    int counter, index, length; /* dummy counters keeping track of where   *
				 * we are in the procedure.  "counter"	   *
				 * keeps track of where we are in the main *
				 * string, "index" where we are in the     *
				 * current word, and "length" how far down *
				 * the line of text we are => newline...   */


    if ( ( source_file = fopen ( fname, "r" ) ) == NULL ) {
	printf("Could not find file in FIND_SINGLE_ENTRY...");
	return;
    }

    if ( ( dest_file = fopen ( dest_name, "w" ) ) == NULL ) {
	printf("Not enough room to create README file in CONSTRUCT_FILE...");
	return;
    }


    if ( fgets ( buffer, MAXSTRING, source_file ) ) {
	
	/* set the counter (keeping track within "buffer") to 0.	*/
	counter = 0;

	/* read the technical report number... */
	while ( buffer [counter] != RIGHT_MARKER_CHAR ) {
	    temp_buff [counter] = buffer [counter];
	    counter++;
	}

	/* read the right delimiter in... */
	temp_buff [counter] = buffer [counter];
	counter++;
	temp_buff [counter] = NIL;
	
	/* write the tech report number to file */
	fprintf ( dest_file, "%s\n          ", temp_buff );

	/* this is the standard starting length at beginning of line */
	length = 25 ;

	/* loop until we have no more input: */
	while ( buffer [counter] != '\n' ) {

	    /* set the word length to 0 */
	    index = 0;

	    /* read characters until we get to the end of the word: */
	    while ( ( buffer [counter] != SPACE ) && 
		    ( buffer [counter] != '\n' ) ) {
		temp_buff [index++] = buffer [counter++];
		length++;
	    }
	    /* again, close off the temporary string */
	    temp_buff [index] = NIL;

	    /* check to see if we need a new line */
	    if ( length >= MAX_LINE ) {
		fprintf ( dest_file, "\n          %s ", temp_buff );
		length = 25 + strlen ( temp_buff ) + 1;
	    }
	    else {
		fprintf ( dest_file, "%s ", temp_buff );
		length++;
	    }

	    /* check to see if there are more words... */
	    if ( buffer [counter] == SPACE )
		counter++;
	}
	fprintf ( dest_file,"\n");
    }
    else
	printf ("Error in find_single_entry: no data in %s", fname);

    fclose ( source_file );
    fclose ( dest_file );
}






/* void make_formatted_citation_list(char *) takes the name of the 	*
 * Citation Database file as input and constructs the a sorted file by 	*
 * using the convert_format function.					*/

void make_formatted_citation_list(char *cit_dbase, char *dest_dbase)
{

/* start mods - CLV 22 Oct 92 */
    char tmpFile1[STD_STRING_SIZE];
    char tmpFile2[STD_STRING_SIZE];
    char command[MAXSTRING];

    sprintf (tmpFile1, "/tmp/tr.FormCit.XXXXXX");
    mktemp (tmpFile1);    /* unique temporary filename */
    convert_format ( cit_dbase, tmpFile1 );
    sprintf (tmpFile2, "%s.sorted", tmpFile1);
    sprintf (command, "sort -o %s %s", tmpFile2, tmpFile1);
    system( command );
    construct_file ( tmpFile2, dest_dbase );
    unlink ( tmpFile1 );
    unlink ( tmpFile2 );
/* end mods */

/*
    convert_format ( cit_dbase, "README.temp" );
    system( "sort -o README.temp.sorted README.temp");
    construct_file ( "README.temp.sorted", dest_dbase );
    unlink ( "README.temp" );
    unlink ( "README.temp.sorted");
*/
}




/* void make_single_citation ( char *, int) makes a list of all the 	*
 * citations by taking the Citation Database file as input and then	*
 * find_single_entry () finds the proper entry and produces it.		*/

void make_single_citation ( char *cit_entry, char *one_cit )
{

/* start mods - CLV 22 Oct 92 */
    char tmpFile1[STD_STRING_SIZE];

    sprintf (tmpFile1, "/tmp/tr.SingCit.XXXXXX");
    mktemp (tmpFile1);    /* unique temporary filename */
    convert_format ( cit_entry, tmpFile1 );
    find_single_entry ( tmpFile1,  one_cit );
    unlink ( tmpFile1 );
/* end mods */

/*
    convert_format ( cit_entry, "README.temp" );
    find_single_entry ( "README.temp",  one_cit );
    unlink ( "README.temp" );
*/
}

/*
 * updates the formatted citation file.
 */
int
update_readme()
{
    FILE           *indexFp, *tmpIndexFp;
    char            citDbase[STRING_SIZE];
    char            reportDir[STRING_SIZE];
    char            command[STRING_SIZE];
    char            indexName[STRING_SIZE];
    char            tmpName[STRING_SIZE];
    char            line[STRING_SIZE];
    char            genHtmlCommand[STRING_SIZE];
    int             c, x, blankline;
    
    strcpy(reportDir, getReportDirectoryPath());

    /* copy readme header to ftp README file */
    sprintf(indexName, "%sREADME", reportDir);
    fileCopy(indexName, getIndexHeaderPath(), 0644);

    /* create index in tmp file */
    strcpy(citDbase, getCitationDataFilePath());
    sprintf(tmpName, "/tmp/%d-readme-tmp", getpid());
    make_formatted_citation_list(citDbase, tmpName);

     /* concatenate index onto readme header eliminating leading blanks */
    if ((indexFp = fopen(indexName, "a")) == NULL) {
	fclose(indexFp);
	return (NO_README);
    }
    if ((tmpIndexFp = fopen(tmpName, "r")) == NULL) {
	fclose(indexFp);
	fclose(tmpIndexFp);
	return (NO_TMP_README);
    }
    fprintf(indexFp, HEADER_DELIMITER);
    while ((c = fgetc(tmpIndexFp)) != EOF)	/* eliminate leading blanks */
	if (isspace(c) == 0)
	    break;

    /* concatenate rest onto readme */
    if (c >= 0) {
       fputc(c, indexFp);
       while ((fgets(line, STRING_SIZE, tmpIndexFp)) != NULL) {
	   blankline = TRUE;
	   for (x = 0; x < strlen(line); x++)	/* eliminate blank lines */
	       if (isspace(line[x]) == 0)
		   blankline = FALSE;
	   if (strlen(line) == 3)
	       blankline = TRUE;
	   if (!blankline) {
	       if (line[0] == '[')
		   fprintf(indexFp, "\n%s", line);
	       else
		   fprintf(indexFp, "%s", line);
	   }
       }
    } 
    fclose(indexFp);
    fclose(tmpIndexFp);

    /* delete tmp files */
    unlink(tmpName);

    sprintf (genHtmlCommand, "%s", getGenHtmlPath());
    system (genHtmlCommand);
    return (0);
}

#ifdef STANDALONETEST
int
main (int argc, char **argv)
{
   if (argc < 2)
   {
      fprintf (stderr, "usage: make_readme referFormatFile outputFile\n");
      exit (1);
   }

   make_single_citation (argv[1], argv[2]);  

}
#endif

#ifdef STANDALONETEST2
int
main (int argc, char **argv)
{
   FILE *fp;
   CitationPtr C;

   if (argc < 2)
   {
      fprintf (stderr, "usage: make_readme referFormatFile\n");
      exit (1);
   }

   fp = fopen (argv[1], "r");
   while ((C = read_one_citation (fp)) != NULL) {
      printf ("Number : %s\n", getTrId (C) );
      printf ("Author : %s\n", getAuthor (C) );
      printf ("Title  : %s\n", getTitle (C) );
      printf ("Poster : %s\n", getPoster (C) );
      printf ("Date   : %s\n", getDate (C) );
      printf ("KWords : %s\n", getKeywords (C) );
      printf ("KWords : %s\n", getCategories (C) );
      printf ("Attrib : %s\n", getAttrib (C) );
      printf ("Abstract : %s\n\n", getAbstract(C) );
      freeCitation (C);
   }
   fclose (fp);
}
#endif

