/* @(#)agldash.c	19.1 (ES0-DMD) 02/25/03 13:53:03 */
/*===========================================================================
  Copyright (C) 1995 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
===========================================================================*/

/* @(#)agldash.c	19.1  (OAA-ASTRONET) 02/25/03 13:53:03   */
/*
 * HEADER : agldash.c      - Vers 3.6.000  - Nov 1991 -  L. Fini, Oss. Arcetri
 */




/*                            DOT DASH SUPPORT                               */




#include <aglenvr.h>
#include <aglstat.h>




static int dot[2] = { 1, 3 };
static int dash[2] = { 6, 3 };
static int dotdash[4] = { 8, 3, 1, 3 };
static int longdash[2] = { 12, 4 };
static int dotdotdash[6] = { 10, 3, 1, 3, 1, 3 };

static int ndashelm[MAXLSTYL] = 
             { 2,2,4,2,6 };             /*  Number of definition elements    */

static double dotting[6];            /* NB: dimension to max pattern length  */

static int nelements;
static double dashspan;
static int dashdraw;
static int dotindex = 0;

static float X1polybuf[CHARPOLYBUFLNG];
static float Y1polybuf[CHARPOLYBUFLNG];

static struct polyline A1poly = {	CHARPOLYBUFLNG, 0, (-1), 
					X1polybuf,Y1polybuf,
					NORMAL, NORMAL, FALSE, NULL
};
  
static void addcoo(xc,yc)           /* Add point to polyline              */
double xc,yc;
{
if(dashdraw)
	AGL_pcoo(xc,yc,&A1poly);
else {
	*(A1poly.XV)=xc;
	*(A1poly.YV)=yc;
	A1poly.nvects = 1;
}
}

void AGL_dshz()		/* prepare dash polyline                    */
{
dotindex=0;
dashspan=dotting[0];
dashdraw = TRUE;
A1poly.nvects=0;
A1poly.join=FALSE;
A1poly.marker=(-1);
A1poly.grmode=NORMAL;
A1poly.clipmode=DY(modeflag);
}


/*****************************************************************************/
/*                       AGL_sstyl (Internal AGL use)                        */

/* Reset dash parameters                                                     */

int AGL_sstyl(ldot)
double ldot;			/* Normalized dot length                     */
{
int *dashpt;
int i;

if(DY(lstyle)==0) { 
	AGL_status.dashon=FALSE; 
	return AGLNOERR; 
}

switch(DY(lstyle)) {
	case 1: 
		dashpt = dot; 
		break;
	case 2: 
		dashpt = dash; 
		break;
	case 3: 
		dashpt = dotdash; 
		break;
	case 4: 
		dashpt = longdash; 
		break;
	case 5: 
		dashpt = dotdotdash; 
		break;
	default:
		AGL_status.dashon=FALSE;
		return(UNSFEATWNG);
}

AGL_status.dashon = TRUE;

nelements=ndashelm[DY(lstyle)-1];

for(i=0; i<nelements; i++) 
/*
	dotting[i] = ldot * (dashpt[i]) *DY(scale);
*/
	dotting[i] = ldot * (dashpt[i]);
   
return AGLNOERR;
}


static double nextdash()
{
if(dashdraw) {
	AGL_pflsh(&A1poly);		/* Draw polyline built up to now     */
	dashdraw=FALSE;
} else
	dashdraw=TRUE;

if(++dotindex==nelements) 
	dotindex=0;
return(dotting[dotindex]);
}
  

void AGL_dpll (poly)
struct polyline *poly;		/* Polyline to draw                         */
{
double xp1,yp1;
double xp0,yp0;
double ratio ;
double dx,dy,distance;
float *XX, *YY;
int n;
void AGL_gpll();
int AGL_cnvt();

n=poly->nvects;

if ( n <= 1 ) { 
	AGL_status.errstat=VECLNGWNG; 
	return; 
}

if(AGL_status.curvwp == VWPEMPTY) { 
	AGL_status.errstat=NOVWPERR; 
	return; 
}


AGL_spfls(AGL_gpll,&A1poly);        /* set up flushing routine for AGL_pcoo   */

ratio = RATYX(AGL_status.devid); ratio *= ratio;

AGL_status.errstat = AGLNOERR;

XX = poly->XV;
YY = poly->YV;

xp0 = *XX++; 
yp0 = *YY++; 
n--;

if(DY(modeflag)!=NORMAL) 
	AGL_cnvt(&xp0,&yp0);  

addcoo(xp0,yp0);

while(n-->0) {
	xp1 = *XX++; 
	yp1 = *YY++; 

	if(DY(modeflag)!=NORMAL) 
		AGL_cnvt(&xp1,&yp1); 

	dx = xp1-xp0;  
	dy = yp1-yp0;
	distance = sqrt((double)(dx*dx+ratio*dy*dy));

	if(distance<=dashspan) {	/* This branch when the segment is  */
					/* shorter than the remaining dash  */
					/* length                           */
		addcoo(xp1,yp1);	/* Add one more point to polyline   */
		xp0 = xp1; yp0 = yp1;
		dashspan -= distance; 
		distance=0.0;
	} else {			/* This branch when the segment is  */
					/* made up with more than one dash  */
		register double rest=distance;
		double xs,ys;

		while(rest>dashspan) {
			double step = dashspan/distance;
  
			xs = xp0+dx*step; 
			ys = yp0+dy*step;	/* End of current dash     */

			addcoo(xs,ys);

			xp0=xs; yp0=ys;
			rest -= dashspan;
			dashspan = nextdash();
		}
		addcoo(xp1,yp1);
		xp0=xp1; yp0=yp1;
		dashspan -= rest;
		if(dashspan<=0.0) 
			dashspan=nextdash();
	}
}
AGL_pflsh(&A1poly);			/* Draw the last piece of polyline */
}
