/*===========================================================================
  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 : mf2ascii.c     - Vers 3.6.002  - Sep 1993 -  L. Fini, OAA
 *                         - Vers 3.6.001  - Aug 1992 -  L. Fini, OAA
 *
 *
 *  AGL Metafile Conversion
 *
 * This utility program converts a standard AGL metafile into an ASCII AGL
 * metafile suitable for inspection and graphic data transport. It is the
 * reverse of the ASCII2MF program.
 *
 * AGL standard metafile are byte oriented files containing a standard
 * header (the 21-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.
 *
 * AGL ASCII files are character oriented files containing the standard
 * header: "# AGL ASCII metafile" followed by instruction codes (AGL routine
 * names) and related argument values. Int arguments are decimal values
 * (format: %d), float arguments are floating point numbers (format: %e),
 * char arguments are output as such.
 *
 * A full list of AGL instruction codes and related argument formats
 * is reported in the following table:
 *
 *  Routine
 *  Code       Arguments       Description
 *---------------------------------------------------------------------------
 *  CDEF x1 x2 y1 y2           Define clipping area.
 *
 *  WDEF x1 x2 y1 y2           Define window
 *
 *  ESC  n                     Escape command
 *  0x00 0x11 ... 0xNN         (n bytes)
 *
 *  EXTN n                     Future Extension
 *  0x00 0x11 ... 0xNN         (n bytes)
 *
 *  VERS                       Erase current viewport
 *
 *  GPLL 5                     Polyline for 5  (x,y) couples
 *  x y 
 *  x y
 *  x y
 *  x y
 *  x y
 *
 *  GPLM 7 5                   Polymarker with marker 7 for 5  (x,y) couples
 *  x y 
 *  x y
 *  x y
 *  x y
 *  x y
 *
 *  GINT 5                     Interpolated polyline for 5  (x,y) couples
 *  x y 
 *  x y
 *  x y
 *  x y
 *  x y
 *
 *  SSET 5                     Set status command="string" (5 chars)
 *  string
 *
 *  GTXT x y 1 3               Write "Str" (3 chars), center 1 in (x,y)
 *  Str
 *
 *  EOF                        End of File
 */

/*

.VERSION
051021		last modif

*/

#include <aglenvr.h>

#include <stdlib.h>
#include <string.h>


#define NOERROR 0
#define MEMERR  1
#define READERR 2
#define CODERR  3


static void help()
{
printf("\n\n");
printf("AGL - Standard to ASCII metafile ");
printf("conversion utility (v. 3.61)\n\n");
printf("Usage: mf2ascii [-i] [standard metafile] [ascii metafile]\n\n");
printf("       where: standard metafile - Input metafile name\n");
printf("              ascii metafile    - Output ascii file name\n\n");
printf("              -i                  Creates 'ip' compatible output file\n\n");
printf("If input and/or output file names are ");
printf("not provided, they are prompted.\n\n");
printf("Copyright 1992 by L. Fini. This program may be freely ");
printf("copied and used\n");
printf("provided this copyright notice will remain attached to it.\n");
}



main(argc,argv)
int argc;
char *argv[];
{
FILE *in=NULL,*out=NULL;
int retstat;
enum METACODE code;
register int ic;
int i;
int ipfmt = FALSE;
char buffr[MFHDRLEN];
char nambuf[PHNAMLNG];

for(i=1; i<argc; i++) {
	char *pt = argv[i];
	switch(*pt) {
	case '?':
		help();
		return 0;
	case '-':
		pt++;
		if(toupper(*pt)!='I') {
			help();
			return 0;
		}
		ipfmt=TRUE;
		break;
 	default: 
		if(in==NULL) {
			in=fopen(argv[i],B_READ);	/* Open input metafile      */
			if(in==NULL) {
				fprintf(stderr,"\nError opening file %s as input\n",argv[i]);
				return 0;
			}
		} else if(out==NULL) {
			out=fopen(argv[i],"w");
	
			if ( out == NULL ) {
				fprintf(stderr,"\nError opening file %s as output\n",argv[i]);
				return 0;
			}
		}
	}
}

if(in==NULL) {
	printf("\nInput file name (return to exit): ");
	scanf("%s",nambuf);
	if(*nambuf=='\0') return 0;
	in = fopen(nambuf,B_READ);		/* Open input metafile       */
	if(in==NULL) {
		fprintf(stderr,"\nError opening file %s as input\n",nambuf);
		return 0;
	}
}

ic = fread (buffr,sizeof(char),MFHDRLEN,in);    /* Read metafile header   */

if(strncmp(buffr,MFHEAD,MFHDRLEN) != 0) {
	fprintf(stderr,"\nInput file is not an AGL standard metafile\n");
	return 0;
}

if(out == NULL ) {
	printf("\nOutput file name (return to exit): ");
	scanf("%s",nambuf);
	if(*nambuf=='\0') return 0;
	out=fopen(nambuf,"w");
	if ( out == NULL ) {
		fprintf(stderr,"\nError opening file %s as output\n",nambuf);
		return 0;
	}
}

fprintf(out,"# AGL ASCII metafile\n");

retstat=NOERROR;

while(retstat==NOERROR) {
	ic = fread ((void *)&code,sizeof(enum METACODE),1,in);	/* get next code */
	if(ic!=1) { 
		retstat = READERR; 
		break; 
	}
	switch ( code ) {
	case MFGPLL: {
		int leng;
		ic=fread((void *)&leng,sizeof(int),1,in);  /* vector length  */
		fprintf(out,"GPLL %d\n",leng);             /* Put opcode     */
		while(leng--) {
			float xxx[2];
			ic=fread((void *)xxx,sizeof(float),2,in); 
			if(ic != 2) { 
				retstat=READERR; 
				break; 
			}
			fprintf(out,"%e %e\n",xxx[0],xxx[1]);
		}
		}
		break;
	case MFGINT: {
		int leng;
		ic=fread((void *)&leng,sizeof(int),1,in);  /* vector length  */
		fprintf(out,"GINT %d\n",leng);             /* Put opcode     */
		while(leng--) {
			float xxx[2];
			ic=fread((void *)xxx,sizeof(float),2,in); 
			if(ic != 2) { 
				retstat=READERR; 
				break; 
			}
			fprintf(out,"%e %e\n",xxx[0],xxx[1]);
		}
		}
		break;

	case MFGPLM: {
		int mark,leng;
		ic=fread((void *)&mark,sizeof(int),1,in);  /* get marker     */
		ic=fread((void *)&leng,sizeof(int),1,in);  /* get length     */
		fprintf(out,"GPLM %d %d\n",mark,leng);     /* put opcode     */
		while(leng--) {
			float xxx[2];
			ic=fread((void *)xxx,sizeof(float),2,in); 
			if(ic!=2) { 
				retstat = READERR; 
				break; 
			}
			fprintf(out,"%e %e\n",xxx[0],xxx[1]);
		}
		}
		break;


	case MFGTXT: {
		int leng,pos;
		float xxx[2];
		char *txtbuf;
		ic=fread((void *)xxx,sizeof(float),2,in);   /* Get coor.     */
		ic=fread((void *)&pos,sizeof(int),1,in);    /* Get position  */
		ic=fread((void *)&leng,sizeof(int),1,in);   /* get length    */
		txtbuf=(char *)malloc((size_t)(leng+1));
		if(txtbuf==NULL) { 
			retstat=MEMERR; 
			break; 
		}
		ic=fread((void *)txtbuf,sizeof(char),leng,in);	/* get string*/
		if(ic!=leng) { 
			retstat = READERR; 
			break; 
		}
		*(txtbuf+leng)='\0';                         /* Put termin.  */
		if(ipfmt) {
			fprintf(out,"GTXT %e %e %d %s\n",
			xxx[0],xxx[1],pos,txtbuf);
		} else {
			fprintf(out,"GTXT %e %e %d %d\n%s\n",
			xxx[0],xxx[1],pos,leng,txtbuf);
		}
		free(txtbuf);
		}
		break;

	case MFCDEF: {
		float xxx[4];
		ic=fread((void *)xxx,sizeof(float),4,in);
		if(ic!=4) { 
			retstat = READERR; 
			break; 
		}
		fprintf(out,"CDEF %e %e %e %e\n",
		xxx[0],xxx[1],xxx[2],xxx[3]);
		}
		break;

	case MFWDEF: {
		float xxx[4];
		ic=fread((void *)xxx,sizeof(float),4,in);
		if(ic!=4) { 
			retstat = READERR; 
			break; 
		}
		fprintf(out,"WDEF %e %e %e %e\n",
		xxx[0],xxx[1],xxx[2],xxx[3]);
		}
		break;

	case MFSSET: {
		int leng;
		char *txtbuf; 
	
		ic=fread((void *)&leng,sizeof(int),1,in);	/* get length*/
		txtbuf=(char *)malloc((size_t)(leng+1));
		if(txtbuf==NULL) { 
			retstat=MEMERR; 
			break; 
		}
		ic=fread((void *)txtbuf,sizeof(char),leng,in);	/* get string*/
		if(ic!=leng) { 
			retstat = READERR; 
			break; 
		}
		*(txtbuf+leng)='\0';                         /* Put termin.  */

		if(ipfmt) {
			fprintf(out,"SSET %s\n",txtbuf);
		} else {
			fprintf(out,"SSET %d\n%s\n",leng,txtbuf);
		}
		free(txtbuf);
		}
		break;

	case MFESC:
	case MFEXTN: {
		int leng;
		char *txtbuf,*pt; 

		ic=fread((void *)&leng,sizeof(int),1,in);	/* get length */
		txtbuf=(char *)malloc((size_t)leng);
		if(txtbuf==NULL) { 
			retstat=MEMERR; 
			break; 
		}
		ic=fread((void *)txtbuf,sizeof(char),leng,in);	/* get string */
		if(ic!=leng) { 
			retstat = READERR; 
			break; 
		}

		if(code==MFESC)
			fprintf(out,"ESC  %d\n",leng);
		else
			fprintf(out,"EXTN %d\n",leng);
    
		pt=txtbuf;
		while (leng--) {
			int an_int= *pt++;
			fprintf(out,"%2x ",an_int);
		}
		fprintf(out,"\n");
		free(txtbuf);
		}
		break;

	case MFVERS:
		fprintf(out,"VERS\n");
		break;

	default: 
		fprintf(stderr,"\nIllegal metafile code\n"); 
		retstat=CODERR;
	}
}

switch(retstat) {
	default:
	case NOERROR:
		break;

	case READERR:
		if(!feof(in)) fprintf(stderr,"\nRead error on input file\n");
		break;

	case MEMERR:
		fprintf(stderr,"\nNot enough memory\n");
		break;

	case CODERR:
		fprintf(stderr,"\nIllegal metafile code\n");
}

fclose(in);
fclose(out);
return 0;
}
