/*===========================================================================
  Copyright (C) 1995-2005 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 Massachusetts Ave, Cambridge, 
  MA 02139, USA.
 
  Correspondence 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_vdef.c      - Vers 3.6.002  - Sep 1993 -  L. Fini, OAA
 *                         - Vers 3.6.001  - Aug 1992 -  L. Fini, OAA
 *
 *
 *                           C INTERFACE MODULE
 */

/*

.VERSION
051021		last modif

*/


#include <stdlib.h>

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


/****************************************************************************/
/*                         aglparse (Internal AGL use)                      */

/* Analyzes the device identification string and returns device, input      */
/* metafile and output metafile fields into output strings                  */

static void aglparse(devidn,device,flag,inpfil,outfil)
char *devidn;            /* string to analyze                              */
char *device;            /* device field (length MUST be<=PHNAMLNG)        */
char *flag;              /* don't erase optional flag (single character)   */
char *inpfil;            /* input m.file field (length MUST be<=PHNAMLNG)  */
char *outfil;            /* output m.file field (length MUST be<=PHNAMLNG) */
{
int slash = '/';
char *field,*pntr;
extern char *AG_SCAN();

*device = '\0'; 
*flag   = '\0';
*inpfil = '\0';
*outfil = '\0';

field=AG_SCAN(devidn,':',PHNAMLNG,device);		/* get device name   */

pntr = strrchr(device,slash); 		/* Search slash and flag (if any)    */
if(pntr != NULL) { 
	if(strlen(pntr)==2) {		/* Just "/" followed by single 'n'   */
		int chr= *(pntr+1); 	/* is taken as flag                  */

		if((chr=TOLOWER(chr))=='n')
			*pntr++ = '\0';
			*flag = chr; 
	}
}

if(*field=='\0') 
	return;

field=AG_SCAN(field,'>',PHNAMLNG,inpfil);	/* get input m.file name  */

if(*field=='\0') 
		return;

field=AG_SCAN(field,'\0',PHNAMLNG,outfil);	/* get output m.file name */
}


/*****************************************************************************/
/*                          makevwp (Internal AGL Use)                       */

/* Allocate space for viewport structure and clear viewport status           */

static void makevwp()
{

int idvw;
AGL_status.errstat=AGLNOERR;

AGL_status.vwpoint = (struct VWPDYN *)malloc((size_t)(sizeof(struct VWPDYN)));

if(AGL_status.vwpoint==NULL) { 
	AGL_status.errstat=MEMORYERR; 
	return; 
}

for(idvw = 0;idvw<MAXVWPTS;idvw++)         /* Search a free slot           */
	if(AGL_status.vwpts[idvw] == NULL) 
		break;

if(idvw==MAXVWPTS) { 
	AGL_status.errstat=VWPOVFSEV; 
	return; 
}

AGL_status.curvwp=idvw;
AGL_status.vwpts[idvw] = AGL_status.vwpoint;

DY(curchan)=(-1);
DY(color)=0;
DY(lstyle)=0;
DY(lwidth)=0;
DY(textlw)=0;
DY(wrmode)='S';
DY(curstyl)=0;
DY(modeflag)=NORMAL;
DY(autoasp)=OFF;
DY(window)=FALSE;
DY(flogx)=FALSE; DY(flogy)=FALSE;
DY(changle)=0.0;
DY(angfct)=0.017453293;
DY(scale) = 1.0;
DY(chrhsize) = 1.0;
DY(chrvsize) = 1.0;
DY(symbsize) = 1.0;
DY(filact)=NOMETAFILE;
DY(metamode)=SOFTMETAFILE;
DY(metafile)=NULL;
DY(curfont)=0;
DY(UsrRTransf)=NULL;
DY(UsrTransf)=NULL;
DY(UsrInit)=NULL;
}


/*****************************************************************************/
/*++                          AG_VDEF (C callable)                           */

/* AG_VDEF    Define viewport                                                */


/* Define and activate a new viewport. If a viewport is currently active it  */
/* is saved prior of activating the new one. After definition the graphic    */
/* mode is NORMALIZED.                                                       */

/* The first time a viewport is activated on a given device, the device is   */
/* allocated and initialized. Subsequent activation of viewports referencing */
/* the same device will not reinitialize it. The device is released when the */
/* last viewport referencing it is killed.                                   */

int AG_VDEF (device,xa,xb,ya,yb,xlim,ylim)

                              /* Returns integer viewport identifier (or < 0 */
                              /* if an error occurs)                         */

 char *device;                /* Graphic device identification. It is a      */
                              /* string with the following syntax:           */

                              /*    device[.aux][/n]:[inpmet][>outmet[/a]]   */

                              /* where:                                      */

                              /* device - Device name  See below for naming  */
                              /*          rules.                             */

                              /* aux    - Auxiliary user information. This   */
                              /*          string is passed as such to the    */
                              /*          device driver to select special    */
                              /*          device dependent features. E.g.:   */
                              /*          it may be used by some drivers to  */
                              /*          select either portrait or land-    */
                              /*          scape orientation, and the like.   */
                              /*          Specifications for auxiliary info  */
                              /*          are given in the device specific   */
                              /*          documentation.                     */

                              /* /n     - optional "no erase on init" flag.  */
                              /* :      - required separator.                */
                              /* inpmet - optional input metafile name. If   */
                              /*          specified the named metafile is    */
                              /*          executed just after viewport acti- */
                              /*          vation.                            */
                              /* >        Output metafile designator (requi- */
                              /*          red if output metafile name is     */
                              /*          specified).                        */
                              /* outmet - Optional output metafile name. If  */
                              /*          specified the named metafile is    */
                              /*          opened for output just after view- */
                              /*          port activation and prior of input */
                              /*          metafile execution.                */
                              /* /a     - Optional request for append mode   */
                              /*          opening of output metafile.        */

 double  xa,xb,ya,yb;         /* Viewport bounds (Normalized: 0.0-1.0).      */
                              /* xa<xb, ya<yb. (xb-xa)>0.001, (yb-ya)>0.001  */

 double  xlim,ylim;           /* Viewport dims (in cm). If 0.0 the device    */
                              /* default values are assigned. The request    */
                              /* will be accepted only at device initiali-   */
                              /* zation (i.e. the first time a viewport  is  */
                              /* opened onto the device). Some devices may   */
                              /* ignore the request (it is an optional driver*/
                              /* capability).                                */

/*  DEVICE NAME SPECIFICATION                                                */

/*  Device names may be either the special name tt: or a logical or physical */
/*  name. Device name translation is performed according to the following    */
/*  steps.                                                                   */

/*  1. If the name is "tt:", no further translation is performed and it is   */
/*     assumed that the output must be sent to the current interactive ter-  */
/*     minal. A definition for the type of terminal must be found within the */
/*     user defined file agldevs.dat, or in the system wide file agldevs.dat */
/*     It may be specified either by an entry into the file agldevs.dat such */
/*     as:                                                                   */
/*         tt:<devtype>  (eg: tt:tkg.t4010, tt:vt125, etc.)                  */

/*     If the entry is not found the environment variable (logical name)     */
/*     AGL3DEV is translated to get the device type (eg: tkg.t4010, vt125,   */
/*     etc.). If neither the entry is found into agldevs.dat nor the AGL3DEV */
/*     variable is defined a severe error condition is raised.               */

/*  2. Any other string is considered to be an environment variable (or logi-*/
/*     cal name) and translated.                                             */

/*  3. When no further translation is possible the resulting string (the     */
/*     original string, if it was a physical name) is used as device name.   */

/*  4. An entry for the given device name must be found either in the user   */
/*     specific agldevs.dat file or in the sistem wide file with the same    */
/*     name, with specification of the type of device. If the entry is not   */
/*     found the device name is used as physical device for output and the   */
/*     environment variable (logical name) AGL3DEV is translated to get the  */
/*     device type. If neither the entry is found into agldevs.dat nor the   */
/*     AGL3DEV variable is defined a severe error condition is raised.       */

/*     By default the device is erased when the 1st viewport is opened onto  */
/*     unless disabled with "/n".                                            */ 

/*     The following examples shows various device specifications:           */

/*     tt:                 Send output to current interactive device, find   */
/*                         device type into file agldevs.dat or into the     */
/*                         environment variable AGL3DEV.                     */
/*     tt/n:               As above. Do not erase on opening.                */

/*     ps0.R90:>meta.tmp   Translate environment variable (logical) ps0, use */
/*                         the resulting string (or "ps0" if no translation  */
/*                         exists) as device name. Search for device type    */
/*                         first into agldev.dat on the current directory    */
/*                         then in the same file on the AGL standard direc-  */
/*                         tory; if not found try to translate the environ-  */
/*                         ment variable (logical) AGL3DEV. If successful    */
/*                         open the device also sending to it the device     */
/*                         specific string R90.                              */
/*                         Then open the output metafile meta.tmp for graphic*/
/*                         operations recording.                             */
                                                                         /*--*/
{
static char *modnam = "VDEF";
double xal,yal,xbl,ybl;
char intdev[PHNAMLNG],inpfil[PHNAMLNG],outfil[PHNAMLNG];
char flag;
void AGL_fvwp();
void makevwp();

AG_DMSG(modnam,(char *)0);

AGL_init();
if ( AGL_status.errstat != AGLNOERR ) 
	AGL_siger(modnam);

if(AGL_status.curvwp!=VWPEMPTY) 
	AGL_vflsh();       /* Empty current viewport buffer    */

aglparse(device,intdev,&flag,inpfil,outfil);    /* Analyze string syntax   */

if(*intdev == '\0') { 
	AGL_puterr(NODEVICE,modnam); 
	return(-1); 
}

if(flag=='n') 
	AGL_status.ersonst=FALSE; 
else 
	AGL_status.ersonst=TRUE;

xal=xa; xbl=xb; yal=ya; ybl=yb;
                                             /* Test viewport bounds         */
AGL_status.errstat=AGLNOERR;

if((xal<0.0)||(xal>1.0)) { 
	AGL_status.errstat = ILLBOUWNG; 
	xal = 0.0; 
}
if((xbl<0.0)||(xbl>1.0)) { 
	AGL_status.errstat = ILLBOUWNG; 
	xbl = 1.0; 
}
if((yal<0.0)||(yal>1.0)) { 
	AGL_status.errstat = ILLBOUWNG; 
	yal = 0.0; 
}
if((ybl<0.0)||(ybl>1.0)) { 
	AGL_status.errstat = ILLBOUWNG; 
	ybl = 1.0; 
}

if( xbl <= xal+0.001 ) { 
	AGL_status.errstat = ILLBOUWNG; 
	xal = 0.0; 
	xbl = 1.0; 
}
if( ybl <= yal+0.001 ) { 
	AGL_status.errstat = ILLBOUWNG; 
	yal = 0.0; 
	ybl = 1.0; 
}

if(AGL_status.errstat != AGLNOERR) 
	AGL_siger(modnam);    /* test error conditions      */

makevwp();                           /* Create viewport structure       */

if(AGL_status.errstat!=AGLNOERR) { 
	AGL_siger(modnam); 
	return(-1); 
}

AGL_gdev(intdev,xlim,ylim);		/* Init device                  */

if(AGL_status.errstat>=ERRTRSH) {	/* Special error test           */
	AGL_fvwp(AGL_status.curvwp);	/* Deallocate viewport          */
	AGL_siger(modnam);		/* Signal error and return      */
	return(-1);
}
else 
	if(AGL_status.errstat!=AGLNOERR) 
		AGL_siger(modnam);
                            
XVWLOW = xal; XVWUP = xbl;		/*  set viewport parameters         */
YVWLOW = yal; YVWUP = ybl;

XCLOW = xal; XCLUP = xbl;		/*  set clipping area parameters    */
YCLOW = yal; YCLUP = ybl;

XSVLOW = xal; XSVUP = xbl;		/*  set saved clip.area parameters */
YSVLOW = yal; YSVUP = ybl;

AGL_status.devid = DY(devidx);

DY(color) = DEFFOREGR(AGL_status.devid);		/* Set default color            */
DY(lstyle) = 0;				/* Set solid line style         */
AGL_sstyl(DOTLEN(AGL_status.devid));
AGL_sclr();				/* Set color on device          */
AGL_swdt(0);				/* Set width on device          */
if(DY(UsrInit) != NULL)
	(*DY(UsrInit))();
AGL_sstat();				/* Set graphic status           */

#ifndef NO_METAFILE_SUPPORT

if(*inpfil != '\0') {
	AGL_push(modnam);		/* Push routine name into stack */
	AGL_mfex(inpfil);		/* Execute the metafile         */
	AGL_pop();			/* Pop routine name from stack  */
}

if(*outfil != '\0') {			/* Open output metafile         */
	AGL_mopn(outfil);
	if(AGL_status.errstat != AGLNOERR) 
		AGL_siger(modnam);
}
#endif

sprintf(inpfil,"%d",AGL_status.curvwp);
AG_DMSG("Viewport id:",inpfil);

return(AGL_status.curvwp);		/* Return viewport identifier  */
}

