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

/* @(#)rastdrv.c	19.1  (OAA-ASTRONET) 02/25/03 13:53:08   */
/*
 * HEADER : rastdrv.c      - Vers 3.6.001  - Sep 1993 -  L. Fini, OAA
 *                         - Vers 3.6.000  - Oct 1991 -  L. Fini, OAA
 *
 *
 * AGL Driver for rasterizing printers.
 *
 * This driver writes a standard ascii file which must be processed with the
 * Device specific program to send output to the printer
 *
 * The output file is made up with lines with the following format:
 *
 * <char> w0 l0 w1 l1 widht
 *
 * Where <char> is a character code which specifies the strip containing
 *              the segment (only ascii 33 to 126 are used)
 *
 *        w0 l0 are the coordinates of the starting point
 *        w1 l1 are the coordinates of the end point
 * 
 *        widht is line widht (0 is the minimum)
 *
 * w is the direction along paper widht, l is along paper length or paper
 * motion.
 *
 * The driver will guarantee that l0 <= l1 and the segment will be entirely
 * contained within the strip.
 *
 * Coordinates are expressed in millimeters with floating point values
 * with two decimals. All distances are referred to the origin of the plot
 * (upper left corner of the plotting area).
 *
 * The first line of the file has a special meaning: 
 *
 * <blank>total_widht total_length strip_length
 *
 * The blank at the beginning ensure that the sort of the file will not move
 * this line.
 *      
 * Default dimension settings are coded in the following lines:
 */
        
#define DEF_P_WIDHT  190.0     /* Default drawing widht  (portrait)(mm)  */
#define DEF_P_LENGTH 130.0     /* Default drawing length (portrait)(mm)  */
        
#define DEF_L_WIDHT  190.0     /* Default drawing widht  (landscape)(mm) */
#define DEF_L_LENGTH 275.0     /* Default drawing length (landscape)(mm) */
        
#define MAX_WIDHT  2000.0      /*   Maximum drawing widht (mm)           */
#define MAX_LWIDHT 5           /* Maximum line style code                */

#define DEF_STRIP  120.0       /*   Default strip length (mm)            */

#define DEF_MODE   'L'         /*   Default mode (Landscape)             */
        
#define TRUE  1
#define FALSE 0

#define VERSCODE 36			/* Declare driver version            */

#define CHARFACTOR 40.0        /* Character dimension multiplier         */
#define RSBLACK       0
#define RSWHITE       1

/*
 * Different values will be requested when opening the viewport
 *
 * A different value for strip length can be selected vie the SYSAUX
 * info (stored in the agldevs.dat file. E.g. a line like the following:
 *
 *  rs:raster.100      # defines raster output with 100 mm strip length
 *
 */

#include <aglsys.h>

#include <agl.h>
#include <aglerror.h>
#include <agldcom.h>
#include <agldcaps.h>


/*
 *  The following entry points have been defined:
 *
 *  Function    Entry point
 *
 *  Initialize  AGLINRST
 *  Cursor en.  AGLCURST
 *  Erase       AGLERRST
 *  Escape      AGLESRST
 *  Polyline    AGLPLRST
 *  Finish      AGLTERST
 *  Flush buff. AGLSERST
 *
 */

              
static double defwd;
static double defln;
static double maxwd;
static double maxln;
static double curwd;
static double curln;

static FILE *filpt;
static int untouched;

static double stripln;             /* Paper strip length (cm)              */
static double nlpirts;

static int    cur_lwidht;

static double factwd;              /* Conversion factor along paper width  */
static double factln;              /* Conversion factor along paper length */
static double ofstl;

static int rot;
static int XC,YC;




static void putcoo(ns,wd0,ln0,wd1,ln1)
int ns;                                         /* Segment number          */
double wd0,ln0;                                 /* Starting point          */
double wd1,ln1;                                 /* End point               */
{
ns=ns+'!';
fprintf(filpt,"%c %.2f %.2f %.2f %.2f %c\n",
               ns, wd0,ln0, wd1, ln1, cur_lwidht );
}


void AGLINRST(AGLDVCOM)
struct bufcom *AGLDVCOM;
{
char *pt;
int mode;
char filnam[32];
int aux;

ERRCODE=AGLNOERR;

switch((int)IBUFFR(0)) {		/* Select function           */
	char auxbuf[20];
	case 0:				/* Hardware initialization   */
		ERRCODE=AGLNOERR;

		strcpy(filnam,"vector");
		AG_NEWN(filnam);	/* make an unique name         */

		if(*filnam == '\0') {
			ERRCODE=DEVOPNSEV;
			return;
		}

		filpt=fopen(filnam,"w");

		if (filpt==NULL) {
			AG_DMSG("Open error:",filnam);
			ERRCODE=DEVOPNSEV;
			return;
		}

		CHANNEL=0;
		untouched=TRUE;

		pt=CHARBUF; 
		while(*pt++);			/* Get SYSAUX string        */

		if(*pt == '\0')
			stripln=DEF_STRIP;
		else
			sscanf(pt,"%lf",&stripln);

		nlpirts = 1.0/stripln;

		while(*pt++);			/* get USRAUX  info         */

		if(*pt=='\0') 
			mode=DEF_MODE;
		else
			mode = TOUPPER(*pt);

		if(mode == 'P') {		/* select portrait mode     */
			XC = 0;
			YC = 1;
			rot=TRUE;
			defwd = DEF_P_WIDHT;
			defln = DEF_P_LENGTH;
		} else {			/* select landscape mode    */
			XC = 1;
			YC = 0;
			rot=FALSE;
			defwd = DEF_L_WIDHT;
			defln = DEF_L_LENGTH;
		}
     
		strcpy(CHARBUF,filnam);		/* Copy filename to buffer   */
		AG_DMSG("Out to:",filnam);
      
		maxwd = MAX_WIDHT;
		maxln = stripln * 94;

		curwd = RBUFFR(XC) * 10.0;	/* Convert requested dims.   */
		curln = RBUFFR(YC) * 10.0;	/* into millimeters          */
              
		curwd = (curwd<=0.0) ? defwd : curwd;
		curwd = (curwd<maxwd) ? curwd : maxwd;
		curln = (curln<=0.0) ? defln : curln;
		curln = (curln<maxln) ? curln : maxln;

		auxbuf[0]=mode; auxbuf[1]='\0';
		AG_DMSG("Plot mode (Portrait,Landscape):",auxbuf);
		sprintf(auxbuf,"%.2f,%.2f",maxwd,maxln);         
		AG_DMSG("Plot max dims (mm):",auxbuf);
		sprintf(auxbuf,"%.2f,%.2f",curwd,curln);
		AG_DMSG("Plot cur dims (mm):",auxbuf);
                                    
		fprintf(filpt," %f %f %f\n",curwd,curln,stripln);

		if(rot) {             
			ofstl=curln;                             
			factln = -curln;	/* factor along length axis */
		} else {
			ofstl = 0.0;
			factln = curln;		/* factor along length axis */
		}

		factwd = curwd;			/* factor along width axis  */

		cur_lwidht = '0';
		break;      

	case 1:				/* Pass back device characteristics  */
		*(CHARBUF) = '\0';
		RBUFFR(XC) = curwd * 0.1;
		RBUFFR(YC) = curln * 0.1;

		IBUFFR(1) = SEPALPHA | EXECOMMND;
		IBUFFR(2) = 1;
		IBUFFR(XC+3) = curwd * 100.0;
		IBUFFR(YC+3) = curln * 100.0;
		IBUFFR(5) = VERSCODE;
		IBUFFR(6) = MAX_LWIDHT;
		IBUFFR(7) = RSWHITE;		/* Default Background */
		IBUFFR(8) = RSBLACK;		/* Default foreground */
		IBUFFR(9) = RSBLACK;
		IBUFFR(10) = RSBLACK;
		IBUFFR(11) = RSBLACK;
		IBUFFR(12) = RSBLACK;
		IBUFFR(13) = RSBLACK;
		IBUFFR(14) = RSBLACK;
		IBUFFR(15) = RSBLACK;
		IBUFFR(16) = RSWHITE;

		RBUFFR(2) = CHARFACTOR;
		RBUFFR(3) = 0.0;
		RBUFFR(4) = 0.0;
		RBUFFR(5) = 0.0;
		RBUFFR(6+XC) = defwd*0.1;
		RBUFFR(6+YC) = defln*0.1;
		RBUFFR(8+XC) = maxwd*0.1;
		RBUFFR(8+YC) = maxln*0.1;
		break;         

	case 2:					/* set color                 */
		ERRCODE=UNSFEATINF;
		break;				/* Unsupported               */

	case 3:					/* set line style            */
		ERRCODE=AGLNOERR;		/* Not used since vers. 3.3  */
		break;

	case 4:					/* set line width            */
		ERRCODE=AGLNOERR;
		aux=IBUFFR(1);
		if(aux<=0) aux = 0;
		if(aux>MAX_LWIDHT) aux = MAX_LWIDHT;
		cur_lwidht = aux+'0';
		break;
}
}
 
 
void AGLPLRST(AGLDVCOM)
struct bufcom *AGLDVCOM;
{
double wcross0,wcross1;
double wdsav,lnsav;
double wd0,wd1,ln0,ln1;
int lnc0,lnc1,lncx;
float *vectx, *vecty;
int n;

n = NPOINTS;

untouched=FALSE;

if(rot) {
	vectx = VECTX;
	vecty = VECTY;
} else {
	vectx = VECTY;
	vecty = VECTX;
}

wd0 = (*vectx++)*factwd + 0.005;		/* Set first point           */
ln0 = (*vecty++)*factln + ofstl;

while(n-->1) {
	wd1 = (*vectx++)*factwd + 0.005;
	ln1 = (*vecty++)*factln + ofstl;

	wdsav = wd1;
	lnsav = ln1;

	if(ln0>ln1) {
		double lsave=ln1, wsave=wd1;
		ln1 = ln0;      
		wd1 = wd0;
		ln0 = lsave;    
		wd0 = wsave;
	}

	lnc0 = ln0 * nlpirts;
	lnc1 = ln1 * nlpirts;
                   
	if(lnc1==lnc0)
		putcoo(lnc0,wd0,ln0,wd1,ln1);
	else {
		double startstrip,endstrip;
		double steep = (wd1-wd0)/(ln1-ln0);
		lncx=lnc0+1;
		endstrip=lncx*stripln;
		wcross0 = steep * (endstrip - ln0) + wd0;
		putcoo(lnc0,wd0,ln0,wcross0,endstrip);	/* First segment     */
     
		while(lnc1>lncx) {		/* Intermediate segments */
			startstrip=endstrip; 
			endstrip += stripln;
			wcross1 = steep * stripln + wcross0;
			putcoo(lncx,wcross0,startstrip,wcross1,endstrip);
			wcross0 = wcross1;
			lncx++;
		}
		putcoo(lnc1,wcross0,endstrip,wd1,ln1);
	}
	wd0 = wdsav;
	ln0 = lnsav;
}
}


void AGLCURST(AGLDVCOM)
struct bufcom *AGLDVCOM;
{
ERRCODE=UNSFEATINF;
}

void AGLERRST(AGLDVCOM)
struct bufcom *AGLDVCOM;
{
ERRCODE=UNSFEATINF;
}

void AGLESRST(AGLDVCOM)
struct bufcom *AGLDVCOM;
{
ERRCODE=UNSFEATINF;
}

void AGLSERST(AGLDVCOM)
struct bufcom *AGLDVCOM;
{
ERRCODE=AGLNOERR;
}

void AGLTERST(AGLDVCOM)
struct bufcom *AGLDVCOM;
{
fclose(filpt); filpt=NULL; 
AG_DMSG("Out file","closed");
ERRCODE=AGLNOERR;
CHANNEL=(-1);
IBUFFR(0)=untouched;
}

