/********************************************************************************/
/*										*/
/*  HPGL2SCR.C                                                   12 SEP 91	*/
/*										*/
/*  Converts HPGL files to AutoCAD script files.  HPGL file must have		*/
/*  extension ".plt", and script file will have extension ".scr".  To		*/
/*  find out more information, consult the "HP ColorPro Graphics Plotter	*/
/*  Programming Manual" available from HP, your AutoCad manual, and "Using	*/
/*  AutoCAD, 3rd Edition" by QUE Corporation.					*/
/*										*/
/*  This program copyright (c) 1991 by William D. Palmer, 1313 Vickers Ave.	*/
/*  Durham, NC  27707.  The program is released into the public domain,		*/
/*  and any commercial use without the prior written consent of the		*/
/*  copyright holder is prohibited.  No warranty as to the suitability of	*/
/*  this software for any particular purpose is expressed or implied.		*/
/*										*/
/*------------------------------------------------------------------------------*/
/*										*/
/* Ported for IRIX by:								*/
/*	Roger Brown, P.E.							*/
/*	Applications Consulting							*/
/*	Silicon Graphics, Inc.							*/
/*	24 FEB 1994								*/
/*	For use in AutoCAD Bonus Software Package				*/
/*	08 JUN 1994								*/
/*	Modified for use as a file filter					*/
/*										*/
/*	Build with:								*/
/*	cc -xansi -prototypes -O2 -I/usr/include hpgl2scr.c -o hpgl2scr -lfastm	*/
/*										*/
/********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <limits.h>

#define  DEBUGx

#define BUFFSIZE	16384	/* <<< Set to default disk read buffer size */

#define DOWN		0x0001
#define UP		0x0000

#define	PLT		".plt"
#define	SCR		".scr"

#ifndef PATH_MAX
#define PATH_MAX	255
#endif /* PATH_MAX */

int	p1x	= 250,
	p1y	= 279,
	p2x	= 10250,
	p2y	= 7479,
	u1x	= 250,
	u1y	= 279,
	u2x	= 10250,
	u2y	= 7479;

double	m1x, m1y,
	m2x, m2y;


/************************************************************************/
/*									*/
/*									*/
/************************************************************************/
static void init_eq(void);
static void init_eq(void)
{
	m1x = (p2x - p1x) / (u2x - u1x);
	m2x = p1x - u1x * m1x;
	m1y = (p2y - p1y) / (u2y - u1y);
	m2y = p1y - u1y * m1y;
}


/************************************************************************/
/*									*/
/*									*/
/************************************************************************/
static void get_coords(double, double, double *, double *);
static void get_coords(double ax, double ay, double *x, double *y)
{
	*x = (m1x * ax + m2x) / 1000.0;
	*y = (m1y * ay + m2y) / 1000.0;
}


/************************************************************************/
/*									*/
/*									*/
/************************************************************************/
void main(int argc, char *argv[]);
void main(int argc, char *argv[])
{
	int	pen, characters,
		index, jndex, kndex,
		x_range, y_range;
	FILE	*infile, *outfile;
	char	*ptr, *endptr,
		buffer[BUFFSIZE],
		infile_line[PATH_MAX],
		infile_name[PATH_MAX],
		outfile_name[PATH_MAX];
	double	x, y,
		ax, ay,
		height, width,
		params[20];

#ifdef _MSDOS
	/* Link floating point library; bug in Turbo C 2.0 */
	x = exp(1);
#endif /* _MSDOS */

	/*-----------------------*/
	/* Open requisite files. */
	/*-----------------------*/
	if (argc == 1)
	{
		printf("File To Filter   : ");
		scanf("%s", &infile_name[0]);
	}
	else
	{
		strcpy (infile_name, argv[1]);
	}

	if (strrchr(infile_name, '.') == NULL)
	{
		strcpy(outfile_name, infile_name);
		strcat(infile_name,  PLT);
		strcat(outfile_name, SCR);
	}
	else
	{
		index = 0;
		while (infile_name[index] != '.')
		{
			outfile_name[index] = infile_name[index++];
		}
		strcat(outfile_name, SCR);
	}
	infile = fopen(infile_name,   "r");
	outfile = fopen(outfile_name, "w");

#ifdef DEBUG
	printf("%s, %s\n", infile_name, outfile_name);
	printf("%p, %p\n", infile, outfile);
	getch();
#endif /* DEBUG */

	fprintf(outfile, "_BLIPMODE _OFF\n");
	fprintf(outfile, "_CMDECHO 0\n");
	
	/*------------------------------*/
	/* Initialize scaling equation. */
	/*------------------------------*/
	init_eq();
	strcpy(infile_line, "");
	jndex	= 0;
	pen	= UP;
	x_range	= 10000;
	y_range	= 7200;
	
	fprintf(stdout, "Processing plot file.");
	/*------------------------------------*/
	/* Process the input file until done. */
	/*------------------------------------*/
	while (!feof(infile))
	{
		index = 0;
		characters = fread(buffer, 1, BUFFSIZE, infile);
		fprintf(stdout, ".");
		fflush(stdout);

#ifdef DEBUG
		printf("characters = %d\n", characters);
		getch();
#endif /* DEBUG */

		while (index < characters)
		{
			if ((buffer[index] != 0x0d) && (buffer[index] != 0x0a))
			{
				infile_line[jndex++] = buffer[index];
			}

			if (buffer[index++] == ';')
			{
#ifdef DEBUG
				printf("\n");
#endif /* DEBUG */
				infile_line[jndex] = 0;

				/*--------------------------------------*/
				/* Here's where the HPGL commands get	*/
				/* processed into an AUTOCAD script.	*/
				/*--------------------------------------*/
#ifdef DEBUG
				printf("%s\n", infile_line);
#endif /* DEBUG */
				/*----------------------------------------------*/
				/* Process LB instruction.			*/
				/* If it's an LB, other command strings could	*/
				/* appear in the message line.			*/
				/*----------------------------------------------*/
				if ((ptr = strstr(infile_line, "LB")) != NULL)
				{
#ifdef DEBUG
					printf("Processing LB instruction\n");
#endif /* DEBUG */
					fprintf(outfile ,"_TEXT %lf,%lf   ", x, y);
					kndex = 2;
					while (infile_line[kndex] != 0x03)
					{
						fprintf(outfile, "%c", infile_line[kndex++]);
					}
					fprintf(outfile, "\n");
				} /* if LB */
				else
				{
					/*-------------------------*/
					/* Process IP instruction. */
					/*-------------------------*/
					if ((ptr = strstr(infile_line, "IP")) != NULL)
					{
#ifdef DEBUG
						printf("Processing IP instruction\n");
#endif /* DEBUG */
						kndex = 0;
						endptr = ptr += 2;
						while (strchr(";ABCDILPRSU", (int)*endptr) == NULL)
						{
							params[kndex] = strtod(ptr, &endptr);
							ptr = endptr + 1;
#ifdef DEBUG
							printf("%lf ", params[kndex]);
							printf("%i\n", kndex);
#endif /* DEBUG */
							kndex++;
						} /* while */
						switch (kndex)
						{
							case 0:
							p1x	= 250;
							p1y	= 279;
							p2x	= 10250;
							p2y	= 7479;
							x_range = 10000;
							y_range = 7200;
							init_eq();
							break;

							case 1:
							break;

							case 2:
							p1x	= (int)params[0]; 
							p1y	= (int)params[1];
							p2x	= p1x + x_range; 
							p2y	= p1y + y_range;
							init_eq();
							break;

							case 3:
							break;

							case 4:
							default:
							p1x	= (int)params[0];
							p1y	= (int)params[1];
							p2x	= (int)params[2];
							p2y	= (int)params[3];
							x_range = p2x - p1x;
							y_range = p2y - p1y;
							init_eq();
							break;
						} /* switch */
#ifdef DEBUG
						getch();
#endif /* DEBUG */
					} /* if IP */

					/*-------------------------*/
					/* Process SC instruction. */
					/*-------------------------*/
					if ((ptr = strstr(infile_line, "SC")) != NULL)
					{
#ifdef DEBUG
						printf("Processing SC instruction\n");
#endif /* DEBUG */
						kndex = 0;
						endptr = ptr += 2;
						while (strchr(";ABCDILPRSU", (int)*endptr) == NULL)
						{
							params[kndex] = strtod(ptr, &endptr);
							ptr = endptr + 1;
#ifdef DEBUG
							printf("%lf ", params[kndex]);
							printf("%i\n", kndex);
#endif /* DEBUG */
							kndex++;
						} /* while */
						switch (kndex)
						{
							case 0:
							u1x = p1x;
							u1y = p1y;
							u2x = p2x;
							u2y = p2y;
							init_eq();
							break;

							case 1:
							case 2:
							case 3:
							break;

							case 4:
							default:
							u1x = (int)params[0];
							u2x = (int)params[1];
							u1y = (int)params[2];
							u2y = (int)params[3];
							if ((u1x == u2x) || (u1y == u2y))
							{
								u1x = p1x;
								u1y = p1y;
								u2x = p2x;
								u2y = p2y;
							}
							init_eq();
							break;
						} /* switch */
					} /* if SC */

					/*-------------------------*/
					/* Process SR instruction. */
					/*-------------------------*/
					if ((ptr = strstr(infile_line, "SR")) != NULL)
					{
#ifdef DEBUG
						printf("Processing SR instruction\n");
#endif /* DEBUG */
						kndex = 0;
						endptr = ptr += 2;
						while (strchr(";ABCDILPRSU", (int) *endptr) == NULL)
						{
							params[kndex] = strtod(ptr, &endptr);
							ptr = endptr + 1;
#ifdef DEBUG
							printf("%lf ", params[kndex]);
							printf("%i\n", kndex);
#endif /* DEBUG */
							kndex++;
						} /* while */
						switch (kndex)
						{
							case 1:
							case 2:
							width  = x_range * 0.0075 / 1000.0;
							height = y_range * 0.0150 / 1000.0;
							break;

							case 3:
							default:
							width  = params[0] / 100000.0 * x_range;
							height = params[1] / 100000.0 * y_range;
							break;
						} /* switch */
						if (pen == DOWN)
						{
							fprintf(outfile, "\n");
						}
						fprintf(outfile, "STYLE  TXT %lf %lf    ", height, (width/height));
						if (pen == UP)
						{
							fprintf(outfile, "\n");
						}
#ifdef DEBUG
						printf("STYLE  TXT %lf %lf    #\n", height, (width/height));
						getch();
#endif /* DEBUG */
					} /* if SR */

					/*-------------------------*/
					/* Process PD instruction. */
					/*-------------------------*/
					if ((ptr = strstr(infile_line, "PD")) != NULL)
					{
#ifdef DEBUG
						printf("Processing PD instruction\n");
#endif /* DEBUG */
						if (pen == UP)
						{
							pen = DOWN;
							fprintf(outfile, "_LINE %lf,%lf ", x, y);
						} /* if (UP) */
						endptr = ptr += 2;
						while (strchr(";ABCDILPRSU", (int)*endptr) == NULL)
						{
							ax = strtod(ptr, &endptr);
#ifdef DEBUG
							printf("%lf,", ax);
#endif /* DEBUG */
							ptr = endptr + 1;
							ay = strtod(ptr, &endptr);
#ifdef DEBUG
							printf("%lf -> ", ay);
#endif /* DEBUG */
							ptr = endptr + 1;
							get_coords(ax, ay, &x, &y);
							fprintf(outfile, "%lf,%lf ", x, y);
#ifdef DEBUG
							printf("%lf,%lf\n", x, y);
#endif /* DEBUG */
						} /* while */
					} /* if PD */

					/*-------------------------*/
					/* Process PA instruction. */
					/*-------------------------*/
					if ((ptr = strstr(infile_line, "PA")) != NULL)
					{
#ifdef DEBUG
						printf("Processing PA instruction\n");
#endif /* DEBUG */
						endptr = ptr += 2;
						while (strchr(";ABCDILPRSU", (int) *endptr) == NULL)
						{
							ax = strtod(ptr, &endptr);
#ifdef DEBUG
							printf("%lf,", ax);
#endif /* DEBUG */
							ptr = endptr + 1;
							ay = strtod(ptr, &endptr);
#ifdef DEBUG
							printf("%lf -> ", ay);
#endif /* DEBUG */
							ptr = endptr + 1;
							get_coords(ax, ay, &x, &y);
							if (pen == DOWN)
							{
								fprintf(outfile, "%lf,%lf ", x, y);
							}
#ifdef DEBUG
							printf("%lf,%lf\n", x, y);
#endif /* DEBUG */
						} /* while */
					} /* if PA */

					/*-------------------------*/
					/* Process PU instruction. */
					/*-------------------------*/
					if ((ptr = strstr(infile_line, "PU")) != NULL)
					{
#ifdef DEBUG
						printf("Processing PU instruction\n");
#endif /* DEBUG */
						if (pen == DOWN)
						{
							fprintf(outfile, "\n");
						}
						pen = UP;
						endptr = ptr += 2;
						while (strchr(";ABCDILPRSU", (int) *endptr) == NULL)
						{
							ax = strtod(ptr, &endptr);
#ifdef DEBUG
							printf("%lf,", ax);
#endif /* DEBUG */
							ptr = endptr + 1;
							ay = strtod(ptr, &endptr);
#ifdef DEBUG
							printf("%lf -> ", ay);
#endif /* DEBUG */
							ptr = endptr + 1;
#ifdef DEBUG
							printf("%lf,%lf\n", x, y);
#endif /* DEBUG */
						} /* while */
					} /* if PU */
				} /* else LB */

				/*---------------------------*/
				/* re-initialize infile_line */
				/*---------------------------*/
				strcpy(infile_line, "");
				jndex = 0;
			} /* if buffer[index] == ';' */

		} /* while (index < characters) */

	} /* while (!feof(infile)) */

	fprintf(outfile, "_BLIPMODE _ON\n");
	fprintf(outfile, "_CMDECHO 1\n");
	fprintf(outfile, "_ZOOM _EXTENTS");
	fclose(infile);
	fclose(outfile);
	
	fprintf(stdout, "done.\n");
	fflush(stdout);

#ifdef DEBUG
	printf("infile closed\n");
	printf("outfile closed\n");
#endif /* DEBUG */
} /* main */
