/*===========================================================================
  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 : hpgldrv.c      - Vers 3.6.002  - Jul 1992 -  L. Fini, OAA

.VERSION

 090630		last modif
 */

/*****************************************************************************/

/* AGL 3.6 driver for HP-GL plotters                                         */

/* L.Fini - Oct 1991                                                         */

/* Note: This driver is based on a VAX/VMS FORTRAN version for AGL 2.xx      */
/*       contributed by Benacchio and Franceschini (Oss. di Padova)          */

/* This driver can control the output size and orientation, as directed in   */
/* the HP-GL manual. The settings are controlled by appending the mode spec  */
/* to the device identification string in the AG_VDEF call. E.g.: if the     */
/* device identification name is defined as hpg in your system the following */
/* selections can be made:                                                   */

/* AG_VDEF("hpg",...) (def) : use paper size A/A4 orientation Landscape      */
/* AG_VDEF("hpg.a",...)     : use paper size A/A4 orientation Landscape      */
/* AG_VDEF("hpg.b",...)     : use paper size A/A4 orientation Portrait       */
/* AG_VDEF("hpg.c",...)     : use paper size B/A3 orientation Landscape      */
/* AG_VDEF("hpg.d",...)     : use paper size B/A3 orientation Portrait       */

/* In the example it is shown how to use device specification to get the     */
/* allowed paper settings (the plotter must support the given size)          */

#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  AGLINHPG                                                     */
/*  Cursor en.  AGLCUHPG                                                     */
/*  Erase       AGLERHPG                                                     */
/*  Escape      AGLESHPG                                                     */
/*  Polyline    AGLPLHPG                                                     */
/*  Finish      AGLTEHPG                                                     */
/*  Flush buff. AGLSEHPG                                                     */



#define VERSCODE 36			/* Declare driver as version 3.6     */

#define HPFLAGS  SEPALPHA | EXECOMMND
#define HPPLANES        6               /*  Set to number of pens           */
#define HPMAXLSTYL      6
#define HPMAXLWIDTH     1

				/* No one can ensure color correspondance   */
				/* Unless pens are installed on the plot in */
				/* the following order:                     */
#define HPGBLACK	0
#define HPGRED		1
#define HPGGREEN	2
#define HPGBLUE		3
#define HPGYELLOW	4
#define HPGMAGENTA	5

				/* Support is provided for 6 per plotters  */
				/* CYAN is set equal to blue, white is a   */
				/* "draw nothing" color                    */
#define HPGCYAN		3
#define HPGWHITE	(-1)

#define CHARMULT   16

#define TRUE  1
#define FALSE 0

/*                      A4L.   A4P.   A3L.   A3P.                             */

static int xpix[4]   = {10800, 7600,  15200, 10800 };
static int ypix[4]   = {7600,  10800, 10800, 15200 };

static float xlen[4] = {27.0,  19.0,  38.0,  27.0 };
static float ylen[4] = {19.0,  27.0,  27.0,  38.0 };

static int pencode[6] = { 1, 2, 4, 3, 5, 6 };
static int curpen;

static double xactlng,yactlng;
static double xfact,yfact;

static char *init0 = "IN;PS4;DF;SC;SP;";
static char *init1 = "IN;PS4;DF;SC;RO90;IP;IW;SP;";
static char *init2 = "IN;PS0;DF;SC;SP;";
static char *init3 = "IN;PS0;DF;SC;RO90;IP;IW;SP;";

static FILE *filpt;                         /* Internal file handler         */
static char *filnam = "hpglplot";
static int id;

static int untouched;


void AGLINHPG (AGLDVCOM)
struct bufcom *AGLDVCOM;
{
extern void AG_DMSG();
char *init;



init = init0;				/* to initialize ... */

ERRCODE=AGLNOERR;

switch((int)IBUFFR(0)) {		/* Select function           */
	char auxbuf[15];		/* File name buffer          */
	char *pt;

	case 0:				/* Hardware initialization   */
		strcpy(auxbuf,filnam);
		AG_NEWN(auxbuf);

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

		filpt=fopen(auxbuf,"w");	/* Open output file          */

		if(filpt==NULL) { 
			AG_DMSG("Open error:",auxbuf);
			ERRCODE=DEVOPNSEV; 
			break; 
		}
      
		CHANNEL=fileno(filpt);

		AG_DMSG("Out to:",auxbuf);

		pt=CHARBUF;			/* Get USRAUX string       */
		while(*pt++);			/* Skip device name        */
		while(*pt++);			/* Skip SYSAUX info        */

		if(*pt=='\0')
			id=0;
		else
			id = TOUPPER(*pt) - 'A';

		switch(id) {
			case 0: init = init0; break;
			case 1: init = init1; break;
			case 2: init = init2; break;
			case 3: init = init3; break;
		}

		strcpy(CHARBUF,auxbuf);		/* Copy filename to buffer   */

		untouched=TRUE;			/* Compute scaling factors    */

		xactlng = RBUFFR(0); 
		xactlng = (xactlng<=xlen[id])?xactlng:xlen[id];
		xactlng = (xactlng<=0.0) ? xlen[id] : xactlng;
		yactlng = RBUFFR(1); 
		yactlng = (yactlng<=ylen[id])?yactlng:ylen[id];
		yactlng = (yactlng<=0.0) ? ylen[id] : yactlng;

		xfact = (xpix[id]-1)*(xactlng/xlen[id]);
		yfact = (ypix[id]-1)*(yactlng/ylen[id]);

		fputs(init,filpt);		/* Send init commands  */
		curpen=HPGBLACK;
		break;

	case 1:				/* Pass back device characteristics  */
		*(CHARBUF) = '\0';
		RBUFFR(0) = xactlng;
		RBUFFR(1) = yactlng;
		IBUFFR(1) = HPFLAGS;
		IBUFFR(2) = HPPLANES;
		IBUFFR(3) = xpix[id];
		IBUFFR(4) = ypix[id];
		IBUFFR(5) = VERSCODE;
		IBUFFR(6) = HPMAXLWIDTH;

		IBUFFR(7) = HPGWHITE;	/* Default Background */
		IBUFFR(8) = HPGBLACK;	/* Default foreground */
		IBUFFR(9) = HPGBLACK;
		IBUFFR(10) = HPGRED;
		IBUFFR(11) = HPGGREEN;
		IBUFFR(12) = HPGBLUE;
		IBUFFR(13) = HPGYELLOW;
		IBUFFR(14) = HPGMAGENTA;
		IBUFFR(15) = HPGCYAN;
		IBUFFR(16) = HPGWHITE;

		RBUFFR(2) = CHARMULT;
		RBUFFR(6) = xlen[id];
		RBUFFR(7) = ylen[id];
		RBUFFR(8) = xlen[id];
		RBUFFR(9) = ylen[id];
		break;

	case 2:				/* set color                 */
		curpen=IBUFFR(1);
		if(curpen>=0) 
			fprintf(filpt,"SP%d;\n",pencode[curpen]);
		ERRCODE=AGLNOERR;
		break;

	case 3:				/* set line style            */
		ERRCODE=AGLNOERR;
		break;

	case 4:				/* set line width            */
		ERRCODE=UNSFEATINF;	/* Unsupported               */
		break;

	case 6:			/* Coordinate roundoff       */
		break;		/* Unnecessary for high resol. devices */
}
}
 

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

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

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


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


void AGLTEHPG(AGLDVCOM)
struct bufcom *AGLDVCOM;
{
extern void AG_DMSG();
fprintf(filpt,"SP0;\n");
fclose(filpt);
AG_DMSG("Out file","closed");
CHANNEL=(-1);
IBUFFR(0)=untouched;
filpt=NULL;
}

void AGLPLHPG(AGLDVCOM)
struct bufcom *AGLDVCOM;
{
int i,n;
float *vectx, *vecty;

ERRCODE=AGLNOERR;

n=NPOINTS;

if(curpen<0) 
	return;

if(n<2)
	return;

untouched=FALSE;

vectx = VECTX;
vecty = VECTY;

fprintf(filpt,"PU%d,%d;\n",       		/* Move to first point     */
                 (int)((*vectx++)*xfact+0.5),
                 (int)((*vecty++)*yfact+0.5));

for(i=1;i<n;i++) {
	fprintf(filpt,"PD%d,%d;\n",
	              (int)((*vectx++)*xfact+0.5),
	              (int)((*vecty++)*yfact+0.5));
}
}

