#include "../H/sfheader.h"
#include <stdio.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <errno.h>
#define  BUFSIZE 131072
#define  ABS(x) ((x < 0) ? (-x) : (x))

SFHEADER sfh;
int loopsize,bytestoread;
char buffer[BUFSIZE]; /* hard wire to keep sloppy users from bad uses*/

scanshort(buffer,segments,maxamps,chfirst,chlast)
float maxamps[2][4];
short *buffer;
{
	int i,j,sampleno,samplesize;
	samplesize = segments / (SF_SHORT * sfchans(&sfh));
	for(i=0,sampleno=0; i<samplesize; i += sfchans(&sfh)) {
		for(j=chfirst; j<=chlast; j++) { 
			if(buffer[sampleno+j] < 0 &&
		           buffer[sampleno+j] < maxamps[0][j])
				maxamps[0][j] = buffer[sampleno+j];
			if(buffer[sampleno+j] >= 0 &&
		           buffer[sampleno+j] > maxamps[1][j])
				maxamps[1][j] = buffer[sampleno+j];
                }  
		sampleno += sfchans(&sfh);
	}
}
scanfloat(buffer,segments,maxamps,chfirst,chlast)
float maxamps[2][4];
float *buffer;
{
	int i,j,sampleno,samplesize;
	samplesize = segments / (SF_FLOAT * sfchans(&sfh));
	for(i=0,sampleno=0; i<samplesize; i += sfchans(&sfh)) {
		for(j=chfirst; j<=chlast; j++) {
			if(buffer[sampleno+j] < 0.0 &&
		           buffer[sampleno+j] < maxamps[0][j])
				maxamps[0][j] = buffer[sampleno+j];
			if(buffer[sampleno+j] >= 0.0 &&
		           buffer[sampleno+j] > maxamps[1][j])
				maxamps[1][j] = buffer[sampleno+j];
                 } 
		sampleno += sfchans(&sfh);
	}
}

main(argc,argv)

int argc;
char *argv[];

{
	SFMAXAMP sfm;
	struct stat sfst;
	char *cp,*sfname,*getsfcode();
	int is_fft,i,j,bytes,sf,result;
	int bytenumber,next,total,segments,loopbytes;
	int shutup();
	double atof();

	float maxamps[2][4];
	float incr,start,hend;
	float jpeak,opeak;
        float amp,namp,pamp;
	int nskips,nnprints,pnprints,nstars,sampleflag;
	int chfirst,chlast,noplot=0;	

	if(argc == 1) {
		printf("usage: hist [-p] filename\n");
		printf("run-time args: increments [-nsamples], start [-sampletime], dur [-nsamples], [ch_first, ch_last], [overall_peak]\n");
		printf("run-time defaults: scan all channels (scan ch 0 for sampl scan), overall_peak read from header\n");
		exit(0);
	}

	while((*++argv)[0] == '-') {
		argc -= 2; /* Take away two args */
		for(cp = argv[0]+1; *cp; cp++) {
			switch(*cp) { /* Grap options */
			case 'p': 
				noplot = 1;
				break;
			}

		}
	}
	sfname = argv[0];
	readopensf(sfname,sf,sfh,sfst,"newhist",result);
	if(result < 0) {
		close(sf);
		exit(1);
	}
	cp = getsfcode(&sfh,SF_MAXAMP);
	bcopy(cp + sizeof(SFCODE), (char *) &sfm, sizeof(SFMAXAMP));
	opeak = 0;
	nstars = 50;
	printsf(&sfh);
	fflush(stdout);
	while(1) {
		is_fft=0;
		fprintf(stderr,
			"Enter increments, starting time, ending time:\t");
		gets(buffer);
		i = sscanf(buffer,
		    "%f %f %f %d %d %f",
				&incr,&start,&hend,&chfirst,&chlast,&opeak);
		if(i == 3) {
			chfirst = 0; 
			chlast = sfchans(&sfh) - 1;
		}
		if(i == 4) chlast = chfirst;
		if(i < 6) {
			for(i=chfirst; i<=chlast; i++)
				if(sfmaxamp(&sfm,i) > opeak)
					opeak = sfmaxamp(&sfm,i);
		}
		if(!opeak) opeak = 32678;  /* default for files with no amp */

		/* if increments is < 0 it means specify incr in samplesize
		   if starting time is < 0 it means sample number
		   if duration < 0 it indicates number of samples to look at */
		sampleflag = (incr < 0) ? 1 : 0;
		if(incr < 0.) incr = -incr/sfsrate(&sfh);
		if(start < 0.) start = -start/sfsrate(&sfh);
		if(hend < 0.) hend = start - hend/sfsrate(&sfh);

		bytes = start * sfclass(&sfh) * sfchans(&sfh) * sfsrate(&sfh);
		bytes -= bytes % (sfclass(&sfh) * sfchans(&sfh)); 
		signal(SIGINT, shutup);

		/* roundout to multiple of sampleblocksize */ 
		loopsize = incr * sfsrate(&sfh) + .5;
		loopbytes = loopsize * sfclass(&sfh) * sfchans(&sfh);
		if((bytenumber = sflseek(sf,bytes,0)) < 0) {
			printf("bad lseek on file %s\n",sfname);
			exit(-1);
		}
		bytenumber -= SIZEOF_HEADER;
		bytestoread = sfsrate(&sfh) * sfclass(&sfh) * sfchans(&sfh) *
		    (hend-start);
		while(bytestoread > 0) {
			total = next = 
			    (bytestoread > loopbytes) ? loopbytes : bytestoread;
			for(i=0; i<sfchans(&sfh);i++){
                             maxamps[0][i] = 0.0;
                             maxamps[1][i] = 0.0;
                        }
			while(next > 0) {
				segments = (next > BUFSIZE) ? BUFSIZE : next;
				if((read(sf,buffer,segments)) != segments) {
					fprintf(stderr,"Reached eof!\n");
					goto nextstep;
				}
				bytenumber += segments;

				if(sfclass(&sfh) == SF_SHORT) 
				     scanshort(buffer,segments,maxamps,
				               chfirst,chlast);
				else
				     scanfloat(buffer,segments,maxamps,
				               chfirst,chlast);
				next -= segments;
			}
			bytestoread -= total;
			if(sampleflag) {
			/* print with + & - along central axis */
                                namp = pamp = 0.0; 
				for(j=chfirst; j<=chlast; j++) { 
				    namp = (maxamps[0][j] < namp) ? 
				            maxamps[0][j] : namp;
                                    pamp = (maxamps[1][j] > pamp) ?
					    maxamps[1][j] : pamp;
                                }
				amp = (-namp > pamp) ? namp : pamp;
				printf("%6d %+8.3e ",(bytenumber-segments)/
				       sfclass(&sfh)/sfchans(&sfh),amp);
				if(!noplot) {
					nnprints = 
				           (float)nstars/2 * -namp/opeak;
				        pnprints =
					   (float)nstars/2 * pamp/opeak;
					nskips = nstars/2 - nnprints - 1;
					printf("\t");
					for(j=0;j<nskips;j++) printf(" ");
					for(j=0;j<nnprints;j++) printf("*");
					printf("|");
					for(j=0;j<pnprints;j++) printf("*");
				}
				printf("\n");
				fflush(stdout);
			}
			else {
				jpeak = 0;
				printf("%4.4f ",start);
				start += incr;
				for(i=chfirst; i<=chlast; i++) { 
					amp =
					(-maxamps[0][i] > maxamps[1][i]) ?
					 -maxamps[0][i] : maxamps[1][i];
					printf("%+8.3e ",amp);
					jpeak = (amp > jpeak) ? amp : jpeak;
				}
				if(!noplot) {
					pnprints = (float)nstars * jpeak/opeak;
					for(j=0;j<pnprints;j++) printf("*");
				}
				printf("\n");
				fflush(stdout);
			}
		}
nextstep:	
		fflush(stdout);	/*  RK was here	*/
		signal(SIGINT, SIG_DFL); 
	}
}
shutup() 
{
	bytestoread = 0;
}
