/*===========================================================================
  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 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_mrdw.c      - Vers 3.6.004  - Sep 1993 -  L. Fini, OAA
 *                         - Vers 3.6.003  - Aug 1992 -  L. Fini, OAA
 *
 *
 *                           C INTERFACE MODULE

.VERSION

 090630		last modif
 */


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

#include <stdlib.h>


#ifndef NO_METAFILE_SUPPORT


static void auxgplm(poly)         /* Auxiliary entry point to invoke AG_GPLM */
struct polyline *poly;
{
extern void AG_GPLM ();

AG_GPLM(poly->XV,poly->YV,poly->nvects,poly->marker);
}

static void auxgpll(poly)         /* Auxiliary entry point to invoke AG_GPLL */
struct polyline *poly;
{
extern void AG_GPLL ();

AG_GPLL(poly->XV,poly->YV,poly->nvects);
}

static void auxgint(poly)         /* Auxiliary entry point to invoke AG_GINT */
struct polyline *poly;
{
extern void AG_GINT ();

AG_GINT(poly->XV,poly->YV,poly->nvects);
}

static int Allocated=0;
static char *Malloc_buf=NULL;

static char *my_malloc(lng)
int lng;
{
if(lng>Allocated) {
	if(Malloc_buf!=NULL)
		free(Malloc_buf);
	Malloc_buf=(char *)malloc((size_t)lng);
	if(Malloc_buf!=NULL)
		Allocated=lng;
}
return Malloc_buf;
}

static void my_free()
{
if(Malloc_buf != NULL)
	free(Malloc_buf);

Allocated=0;
}


/*****************************************************************************/
/*                        AGL_mfex (Internal AGL use)                        */

/*   Executes all codes in the Metafile                                      */


/* AGL standard metafiles are byte oriented files containing a standard      */
/* header (the null-termin., 22-char. string: "AGL Standard metafile")       */
/* followed by AGL instruction codes with related argument values.           */
/* Arguments are int, float or char values expressed as unformatted binary.  */

/* For visual inspection and/or graphic data transport AGL standard meta-    */
/* files can be interpreted and translated into an ASCII form by means of    */
/* the utility program MF2ASCII                                              */



void AGL_mfex ( exefile )
char *exefile;                   /* input metafile file name                */
{
enum RETCODES { RDNORMAL, CODERR, ARGERR, MEMERR };
FILE *fildsc;
enum METACODE code;
enum RETCODES retstat;

AGL_status.errstat=AGLNOERR;

fildsc = fopen(exefile,B_READ);          /* Open metafile                 */

if (fildsc==NULL) { AGL_status.errstat=MFOPENERR; return; }

AG_DMSG(exefile,"opened");

{
	char buffr[MFHDRLEN];
	*buffr='\0';
	(void) fread(buffr,sizeof(char),MFHDRLEN,fildsc);  /* Read header  */

	if(strncmp(buffr,AGL_mfhead,MFHDRLEN) != 0) {	/* Test header  */
		fclose(fildsc);
		AGL_status.errstat=MFFMTERR;
		return;
	}
}

AG_DMSG("Exec:",exefile);

retstat=RDNORMAL;

while(retstat==RDNORMAL) {
	int ic;
	ic=fread((void *)&code,
	          sizeof(enum METACODE),1,fildsc); 	/* get next code   */

	if(ic!=1) { 
		retstat = CODERR; 
		break; 
	}

	switch(code) {

	int lng;
	int pos;
	float xxx[4];
	float ApolyX[AUXPOLYBUFLNG];
	float ApolyY[AUXPOLYBUFLNG];
	struct polyline auxpoly;
	char *txtbuf;

	case MFGPLL: 			/* AG_GPLL                   */
	case MFGINT: 			/* AG_GINT                   */
	case MFGPLM: 			/* AG_GPLM                   */

		AGL_plmk(ApolyX,ApolyY,
		         AUXPOLYBUFLNG,0,DY(modeflag),&auxpoly);  

		switch(code) {
		case MFGPLL: 
			AGL_spfls(auxgpll,&auxpoly);
			auxpoly.join=TRUE;
			break;
		case MFGINT: 
			AGL_spfls(auxgint,&auxpoly);
			auxpoly.join=TRUE;
			break;
		case MFGPLM:
			AGL_spfls(auxgplm,&auxpoly);
			ic=fread((void *)&(auxpoly.marker),
			          sizeof(int),1,fildsc);
			auxpoly.join=FALSE;
			break;
		default:
			break;
		}

		ic=fread(&lng,sizeof(int),1,fildsc);
		while(lng--) {
			ic=fread((void *)xxx,sizeof(float),2,fildsc); 
			if(ic != 2) { 
				retstat=ARGERR; 
				break; 
			}
			AGL_pcoo(xxx[0],xxx[1],&auxpoly);
		}
		AGL_pflsh(&auxpoly);
		break;

	case MFGTXT: 				/* GTXT Command              */

		ic=fread((void *)xxx,sizeof(float),2,fildsc);
		ic=fread((void *)&pos,sizeof(int),1,fildsc);
		ic=fread((void *)&lng,sizeof(int),1,fildsc);
		txtbuf=my_malloc(lng+1);
		if(txtbuf==NULL) { retstat=MEMERR; break; }

		ic=fread((void *)txtbuf,sizeof(char),lng,fildsc);  

		*(txtbuf+lng)='\0';			/* Put terminator    */

		if(ic==lng) 
			AG_GTXT (xxx[0],xxx[1],txtbuf,pos);
		else
			retstat=ARGERR;
                          
		break;

	case MFCDEF:				/* AG_CDEF                   */
		ic=fread((void *)xxx,sizeof(float),4,fildsc);
		if(ic==4)
			AG_CDEF (xxx[0],xxx[1],xxx[2],xxx[3]);
		else
			retstat=ARGERR;
		break;

	case MFWDEF:				/* DEF_WINDOW Command        */
		ic=fread((void *)xxx,sizeof(float),4,fildsc);
		if(ic==4)
			AG_WDEF (xxx[0],xxx[1],xxx[2],xxx[3]);
		else
			retstat=ARGERR;
		break;

	case MFSSET:				/* SET Command               */
		ic = fread((void *)&lng,sizeof(int),1,fildsc);    
		txtbuf=my_malloc(lng+1);
		if(txtbuf==NULL) { retstat=MEMERR; break; }
		ic = fread (txtbuf,sizeof(char),lng,fildsc);
		txtbuf[lng]='\0';

		if(ic==lng) 
			AG_SSET ( txtbuf );
		else
			retstat=ARGERR;
		break;

	case MFVERS:				/* ERASE Command           */
		AG_VERS();
		break;

	case MFESC:				/* Escape command          */
		ic = fread((void *)&lng,sizeof(int),1,fildsc);    
		txtbuf=my_malloc(lng);
		if(txtbuf==NULL) { 
			retstat=MEMERR; 
			break; 
		}
		ic = fread(txtbuf,sizeof(char),lng,fildsc);

		if(ic==lng) 
			AG_ESC ( txtbuf, lng );
		else
			retstat=ARGERR;

		break;

	case MFEXTN:				/* EXTEND (for future use) */
						/* discard next record     */
		ic = fread((void *)&lng,sizeof(int),1,fildsc);    
		txtbuf=my_malloc(lng);
		if(txtbuf==NULL) { retstat=MEMERR; break; }
		ic = fread (txtbuf,sizeof(char),lng,fildsc);
		break;

	default:				/* Illegal metafile code   */
		retstat=CODERR;
		break;
	}
}

my_free();
  
switch(retstat) {			/* deal with return statuses       */
case CODERR:
	if(feof(fildsc))
		AGL_status.errstat=AGLNOERR;
	else
		AGL_status.errstat=MFREADERR;
	break;

case MEMERR:
	AGL_status.errstat=MEMORYERR;
	break;

case ARGERR:
	AGL_status.errstat=MFREADERR;
	break;
default:
	AGL_status.errstat=AGLNOERR;
	break;
}
fclose(fildsc); 
AG_DMSG(exefile,"closed");
}



/*****************************************************************************/
/*++                           AG_MRDW (C callable)                          */

/* AG_MRDW    Redraw a metafile                                              */


/* Redraws a previously generated metafile, i.e. all the commands stored in  */
/* it are executed. The metafile must have been previously closed.           */


void AG_MRDW (mfile)

char *mfile;                  /* Name of metafile to redraw                  */
                                                                         /*--*/
{
static char *modnam = "MRDW";
extern void AG_DMSG();

AG_DMSG(modnam,(char *)0);

if (AGL_status.curvwp == VWPEMPTY) 		/* Test if viewp. is active   */
	AGL_puterr(NOVWPERR,modnam);
else {
	AGL_push(modnam);
	AGL_mfex(mfile);
	AGL_pop();
	if(AGL_status.errstat != AGLNOERR)
		AGL_siger(modnam);
}
}


#else

void AG_MRDW (mfile) char *mfile; {}

#endif
