/*===========================================================================
  Copyright (C) 1995-2009 European Southern Observatory (ESO)
 
  This program 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.
 
  This program 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 this program; if not, write to the Free 
  Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, 
  MA 02139, USA.
 
  Corresponding concerning ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY
===========================================================================*/

/*
 * HEADER : ag_hist.c      - Vers 3.6.000  - Oct 1991 -  L. Fini, Oss. Arcetri
 *
 * AGL high level routine. Histogram generation

 .VERSION

 090630		last modif
 */

#include <aglenvr.h>


static void drwbin(xvaux,yvaux,xcurr,xnext,ynext,yzero,mode)
float xvaux[],yvaux[];
float xcurr,xnext,ynext,yzero;
int mode;
{
xvaux[1] = xcurr+(xnext-xcurr)*0.5;
yvaux[1] = yvaux[0];
(void)AG_GPLL(xvaux,yvaux,2);

xvaux[0]=xvaux[1];

if(mode!=0) {
	float max,min;
	if(yvaux[1]<yzero) {
		max=yzero;
		min=yvaux[1];
	} else {
		min=yzero;
		max=yvaux[1];
	}
	if(ynext<min)
		min=ynext;
	else if(ynext>max)
		max=ynext;
	yvaux[0]=min;
	yvaux[1]=max;
} else {
	yvaux[0]=yvaux[1];
	yvaux[1]=ynext;
}

(void)AG_GPLL(xvaux,yvaux,2);

yvaux[0]=ynext;
}
  

/*****************************************************************************/
/*++                          AG_HIST (User callable)                        */

/* AG_HIST                                                                   */


/* This module draws various forms of histogram plots from a couple of       */
/* coordinate vectors.                                                       */

/* NOTE: a window must be defined and the mode USER must be selected before  */
/*       calling AG_HIST (see: AG_WDEF and AG_SSET).                         */

/* Here follows a typical calling sequence for histogram plotting:           */

/*    AG_VDEF (.......)          Define graphic device                       */
/*    AG_AXES(x0,x1,y0,y1,sel)   Define and draw axes                        */
/*    AG_HIST(xv,yv,np,0,0)      Draw the histogram from data in vectors     */
/*                               xv,yv (length=np)                           */
/*    AG_CLS()                   Close AGL                                   */


void AG_HIST(xv,yv,np,mode,join)

float xv[],yv[];              /* Coordinate arrays                           */

int np;                       /* Array length                                */

int mode;                     /* Histogram type selection.                   */
                              /* Types available are the following:          */

                              /* mode=0  simple staircase.                   */
                              /* mode=1  staircase steps joined to x-axis.   */
                              /* mode<=2 data points joined to x-axis with   */
                              /*         boxes (current line width and style)*/
                              /*         with width starting from 0 (simple  */
                              /*         line) and increasing with mode      */
                              /*         value in steps of small character   */
                              /*         width                               */
int join;                     /* Flag to join more than one call into a      */
                              /* single histogram (used with modes: 0, 1)    */
                              /* join=0 : histogram closed at both ends.     */
                              /*          (used when all data points are     */
                              /*           plotted with a single call)       */
                              /* join=1 : histogram opened at the right end  */
                              /*          (used for the first block of an    */
                              /*           histogram built with many calls)  */
                              /* join=2 : histogram opened at the left end   */
                              /*          (used for the final block of an    */
                              /*           histogram built with many calls)  */
                              /* join=3 : histogram opened at both ends      */
                              /*          (used for the middle blocks of an  */
                              /*           histogram built with many calls)  */
                              /* N.B.: when using the join feature to plot a */
                              /*       long histogram built up with pieces   */
                              /*       DO NOT intermix calls to other AGL    */
                              /*       routines between calls to AG_HIST.    */
                                                                         /*--*/ 
{
static char *modnam = "HIST";
static float xvaux[4],yvaux[4];
static float xcurr,xnext,ynext,yzero;
float delta=0.0;
int i;

AG_DMSG(modnam,(char *)0);
  
AGL_push(modnam);

if(mode>0) {
	float wndl[4];
	(void)AG_RGET("wndl",wndl);
/*
	yzero=wndl[2];
*/
	yzero=0;
}

if(np>0) {
	if(mode<2) {
		if((join&02)==0) {
			delta = (xv[1]-xv[0])*0.5;	/* deal with left  */
			xvaux[0] = xv[0]-delta; 	/* edge of histogram */
  
			if(mode==0)
				yvaux[0] = yv[0];
			else {
				yvaux[0] = yzero;
				xvaux[1] = xvaux[0];
				yvaux[1] = yv[0];
				AG_GPLL(xvaux,yvaux,2);
				yvaux[0] = yvaux[1];
			}
		} else {
			xnext=xv[0];		/* xcurr is the last point  */
			ynext=yv[0];		/* of previous block        */
			drwbin(xvaux,yvaux,xcurr,xnext,ynext,yzero,mode);
		}

		for(i=0; i<np-1; i++) {		/* This for the central part */
			register int ii=i+1;
			xcurr=xv[i];
			xnext=xv[ii];
			ynext=yv[ii];
			drwbin(xvaux,yvaux,xcurr,xnext,ynext,yzero,mode);
		}
		xcurr=xv[np-1];			/* needed for joining        */

	} else {				/* Modes >= 2                 */
		int bw = mode-2;
		if(bw==0) {
			for(i=0; i<np; i++) {
				xvaux[0]=xv[i];
				yvaux[0]=yzero;
				xvaux[1]=xvaux[0];
				yvaux[1]=yv[i];
				(void)AG_GPLL(xvaux,yvaux,2);
			}
		} else {
			float fv[2],hbin;

			(void)AG_RGET("nchdim",fv);
			(void)AG_SSET("normal");
			hbin = fv[0]/4.0*bw;
			for(i=0; i<np; i++) {
				AG_VU2N(xv[i],yzero,xvaux,yvaux);
				AG_VU2N(xv[i],yv[i],xvaux+1,yvaux+1);
				xvaux[2] = xvaux[0]+hbin;
				xvaux[3] = xvaux[0]+hbin;
				xvaux[0] -= hbin;
				xvaux[1] -= hbin;
				yvaux[2] = yvaux[1];
				yvaux[3] = yvaux[0];
				(void)AG_GPLL(xvaux,yvaux,4);
			}
		}
	}
}
      
if(((join&01)==0)&&(mode<2)) {		/* deal with right edge of histogram */
	xnext=xcurr+2.0*delta;
	ynext=yvaux[0];
	drwbin(xvaux,yvaux,xcurr,xnext,ynext,yzero,mode);
}
AGL_pop();
}
