/*
 * Report file generation utility code.
 * See report.doc for more info.
 *
 * (C)1998-1999 Peter Bengtsson
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GAP.h>

#include "report.h"

static const char * const exts[REPFILES] = {
	"avg",
	"med",
	"typ",
	"max",
	"min",
	"dev"
};

static const char * const descs[REPFILES] = {
	"Average",
	"Median",
	"TypeCount",
	"Max",
	"Min",
	"StdDev"
};

struct Report *MakeReport(char *);
void DoReport(struct Report *,struct Population *,unsigned int);
void EndReport(struct Report *rs);

struct Report *MakeReport(char *basename)
{
struct Report *rs;
char	*buf;
int i;

if(basename!=NULL) {
	buf = malloc((strlen(basename)+8)*sizeof(char));
	rs = malloc(sizeof(struct Report));
	rs->basename = malloc((strlen(basename)+1)*sizeof(char));
	strcpy(rs->basename,basename);

	if(rs!=NULL && rs->basename!=NULL && buf!=NULL) {
		for(i=0;i!=REPFILES;i++) {
			sprintf(buf,"%s.%s",basename,exts[i]);
			if((rs->files[i]=fopen(buf,"wb"))==NULL) {
				while(--i>=0) {
					fclose(rs->files[i]);
				}
				free(rs->basename);
				free(rs);
				rs = NULL;
				fprintf(stderr,"MakeReport: Error opening files for writing.\n");
			}
			rs->used[i]=0;
			fprintf(rs->files[i],"# Generation, %s\n",descs[i]);
		}
	} else {
		if(rs!=NULL) {
			if(rs->basename!=NULL) {
				free(rs->basename);
			}
			free(rs);
			rs = NULL;
		}
		fprintf(stderr,"MakeReport: No free store (malloc() failed).\n");
	}
} else {
	fprintf(stderr,"MakeReport: NULL basename.\n");
}

if(buf!=NULL) {
	free(buf);
}

return(rs);
}

void EndReport(struct Report *rs)
{
int i;
char *buf=NULL;

if(rs!=NULL) {
	buf=malloc((strlen(rs->basename)+8)*sizeof(char));
	for(i=0;i!=REPFILES;i++) {
		fclose(rs->files[i]);	/* fclose does an fflush. */
		if(rs->used[i]==0 && buf!=NULL) {
			sprintf(buf,"%s.%s",rs->basename,exts[i]);
			remove(buf);
		}
	}
	free(rs->basename);
	free(rs);
}

if(buf!=NULL) {
	free(buf);
} else {
	fprintf(stderr,"EndReport: No free store, continuing.\n");
}

}

void DoReport(struct Report *rs,struct Population *Pop,unsigned int flags)
{
int i,n;
struct Popstat *stat;

if(rs!=NULL && Pop!=NULL && flags!=0) {
	stat = &Pop->Stat;
	for(i=0;i!=REPFILES;i++) {
		n = flags&(1<<i);
		if(n!=0) {
			rs->used[i]=1;
			switch(n) {
			case	AVERAGE:
				fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->AverageFitness);
			break;
			case	MEDIAN:
				fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->MedianFitness);
			break;
			case	TYPECOUNT:
				fprintf(rs->files[i],"%ld %ld\n",stat->Generation,stat->TypeCount);
			break;
			case	MAX:
				fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->MaxFitness);
			break;
			case	MIN:
				fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->MinFitness);
			break;
			case	STDDEV:
				fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->StdDeviation);
			break;
			}
		}
	}
}

}

