#include <stdio.h>
#include <string.h>
#include <math.h>
#include "freelance.h"
#include "find.h"

/*	CMS Generation: 3                       27-OCT-89
*/

#define PI	3.141592
#define RADIANS (PI/180.0)
FILE *fin,*fout;

/* draw a line */
line_draw(x,y,w,h)
int x,y,w,h;
{
	line(x,y,w,h);
}

/* draw a box */
box_draw(x,y,w,h)
int x,y,w,h;
{
	box(x,y,w,h);

}

/* pull text out of regis text command */
text_draw(x,y,line)
int x,y;
char line[];
{
	char *start,*end,string[133];
	char find[2];
	int size;
	char junk[20];


	find[0]='"';
	find[1]='\0';

	strtok(line,"S");
	start=strtok(NULL,find); /* point to number */

	sscanf(start,"%d",&size);

	/* set text size to size */
	set_text_height( 10+(size*5) );

	/* output text string */

	start=strtok(NULL,find); /* point to text */
	
	text(x,y,start);

}

/* draw a circle into metafile */
circle_draw(x,y,w,h)
int x,y,w,h;
{
	
	circle(x+w/2,y+h/2,w/2,h/2,w/2);	/* circle(x,y,xr,yr,rad); */

}

/* extract spline array info from regis command */
spline_draw(x,y,line)
int x,y;
char line[];
{	int dx,dy,a,b;
	int xarr[80],yarr[80];
	int i,stat;
	char *start,*start2;
                      
	sscanf(line," P[%d,%d]",&dx,&dy);

	dx += x;	/* turn into absolute coord */
	dy += y;	/* this is first point of spline */
	

	i=0;
	stat=2;

	start2=index(line,"F(V(B)");
	start=strtok(line,")");
           
	while ((stat == 2)&& ((start=strtok(NULL,"]")) != NULL))
	{                         
		stat=sscanf(start,"[%d,%d",&a,&b);

		if (stat == 2)	/* correct number of things found */
		{
		dx += a;	/* keep track of absolute position */
		dy += b;

		 xarr[i] = dx;	/* put in spline array */
	   	 yarr[i] = dy;
		 i++;
		}
	}
	polyline(xarr,yarr,i);

	if ( start2 != NULL)	/* arrow head */
	{	   
	start=strtok(start2,")");

	stat=2;

	xarr[0]=dx;	/* absolute of tip */
	yarr[0]=dy;

	xarr[3]=dx;	/* absolute of tip */
	yarr[3]=dy;

	i=1;
	while ((stat == 2)&& ((start=strtok(NULL,"]")) != NULL))
	{                         
		stat=sscanf(start,"[%d,%d",&a,&b);

		if (stat == 2)
		{
			dx += a;
			dy += b;
			xarr[i] = dx;
			yarr[i] = dy;
			i++;      
		}
	}  

	i++;
/* fill the arrow head */
	set_fill_style(SOLID);
	polyline(xarr,yarr,i);
	set_fill_style(HOLLOW);
/* stop the fill */ 
	}  
}

and_gate(x,y,w,h)
int x,y,w,h;
{
	int delta;

/* if the longest side is the width then it is horizontal */
/* if the longest side is negative, then it is pointing left or down */

	if ( abs(w) > abs(h) )	/* horizontal */
	{
		if (w < 0)	/* pointing left */
		 delta = -30;
		else		/* pointing right */
		 delta = 30;

    		 line_draw(x+delta,y,-delta,0);	/* lines of and gate */
     		 line_draw(x,y,0,h);
		 line_draw(x,y+h,delta,0);
						/* arc */
		 circle_arc_3pt( x+delta,y+h, x+w,y+(h/2), x+delta,y);

	}
	else /* vertical and gate */
	{
	 if (h<0)	/* pointing up */
		delta= -30;
    	else		/* pointing down  */
		delta= 30;

		 line_draw(x,y+delta,0,-delta);	/* lines of and gate */
		 line_draw(x,y,w,0);
		 line_draw(x+w,y,0,delta);
						/* arc */
		 circle_arc_3pt( x+w,y+delta, x+(w/2),y+h, x,y+delta);

	}
}

or_gate(x,y,w,h)
int x,y,w,h;
{
	int delta;

/* if the longest side is the width then it is horizontal */
/* if the longest side is negative, then it is pointing left or up */

	if ( abs(w) > abs(h) )	/* horizontal */
	{
		if (w < 0)	/* pointing left */
		 delta = -10;
		else		/* pointing right */
		 delta = 10;		

	circle_arc_3pt( x,y+h, x+delta,y+(h/2), x,y );
	circle_arc_3pt( x,y+h, x+w-delta,y+h-delta, x+w,y+(h/2));
	circle_arc_3pt( x+w,y+(h/2), x+w-delta,y+(h/2)-delta, x,y);
	}
	else /* vertical and gate */
	{
	 if (h<0)	/* pointing up */
	 delta = -10;
    	else		/* pointing down */
	 delta = 10;

	circle_arc_3pt( x+w,y, x+(w/2),y+delta, x,y );
	circle_arc_3pt( x+w,y, x+w+delta,y+h-delta, x+(w/2),y+h);
	circle_arc_3pt( x+(w/2),y+h, x+(w/2)+delta,y+h-delta, x,y);

	}
}                                                               
                
/* extract gate info from regis command */
gate_draw(x,y,w,h,line)
int x,y,w,h;
char line[];
{       
	char *start;

/* if there are two curves in it, it is an OR gate */
	start = index (line,"]C(A");

	if (start == NULL)
	 return(-1);

	if ( index(start+1,"]C(A") != NULL)
	{
	
	 or_gate(x,y,w,h);
	}
	else
	{
	
	 and_gate(x,y,w,h);
	}
}


/* extract angle info from ReGIS arc command */
arc_draw(x,y,r,line)
int x,y,r;
char line[];
{
	double theta,angle,angle2,angle1;
	int x1,y1,x2,y2;
	char *start;

	r = abs(r);
	/* x1,y1  : delta to start point */
	start = index(line,"C(A");
	start = strtok(start,")");
	sscanf(start,"C(A%lf",&angle);
	start = strtok(NULL,"]");    
	sscanf(start,"[%d,%d",&x1,&y1);
	

	angle *= -RADIANS;

	                         
                                 
        if (x1 == 0)
	 theta = (y>0)?(90.0*RADIANS):(270.0*RADIANS);
	else
 	theta = atan((double)((double)y1/(double)x1));
	                         
	if (x1 <0) theta += (PI);

	if (theta <0.0) theta += (2.0*PI);

 	

	angle1 = (angle+theta);                   
	if ( angle1 > (2.0*PI)) angle1 -= 2.0*PI;

	x2 = (int)(x + r*cos(angle1));	/* absolute coords */
	y2 = (int)(y + r*sin(angle1));

	
	
	x1 += x;			/* absolute coords */
	y1 += y;
	

	angle2 = ((angle/2.0)+theta);
	if ( angle2 > (2.0*PI)) angle2 -= 2.0*PI;

	x += (int)( r*cos(angle2));	/* absolute coords */
	y += (int)( r*sin(angle2));
	

/*	circle_arc_center(x,y,x1,y1,x2,y2,r);	*/

	if (angle <0) 
	circle_arc_3pt( x1,y1, x,y, x2,y2);	
	else 	circle_arc_3pt( x2,y2, x,y, x1,y1);	
                                   
}                                                 
                                 
init_obj(style)
int style;
{
	set_line_color(1);
	
	if( style != -1)   
	 {      
	        set_linestyle(style); 
	 }      /* end of linestyle */
	else printf("line style unknown!!\n");
	
	set_line_width(1);             


}
             
interpret(line,x,y,w,h,style)
char line[];
int x,y,w,h;
int style;
{
	char *start;

	if (strlen(line) < 3) return(-1);

		
	switch(line[1])         
	{                               
		case 'T': /* text */
			text_draw(x,y,line);	/* extract text and do it */
			break;

		case 'P':                         
			 if (  index(line,"]C[") != NULL) 
				circle_draw(x,y,w,h,style);	/* circle */
			 else
			  if ( index(line,"C(S)") != NULL) 
				{				
				init_obj(style);
				spline_draw(x,y,line);	/* spline */
				}
			 else
			  if ( index(line,"]C(A") != NULL) 
				{
				init_obj(style);
				arc_draw(x+w/2,y+h/2,h/2,line);	/* arc */
				}
			break;

		case 'F':		/* filled object */
			switch(line[3])
			{	case 'P':		/* circle */
					set_fill_style(SOLID);
					circle_draw(x,y,w,h,style);
					set_fill_style(HOLLOW);
					break;
				case 'V':		/* box */
					init_obj(style);
					set_fill_style(SOLID);
					box_draw(x,y,w,h);
					set_fill_style(HOLLOW);
					break;

			} /* end filled-object case */
			break;
		case 'V':	
				if (line[3] == 'B')
					{
					init_obj(style);
					box_draw(x,y,w,h);	/* box */
					}
				else
		  		 if ( index(line,"]C(A") != NULL)
					{
					init_obj(style);
					gate_draw(x,y,w,h,line); /* gate */
					}
				  else 
					{
					init_obj(style);
					line_draw(x,y,w,h);	/* line */
					}
			break;

	} /* end of switch */

}                     

read_file(dx,dy,fp)
int dx,dy;
FILE 	*fp;
{
	extern int do_tex;

	int x,w,y,h,dummy;
	int l_style= -1;
	int t_size; 
	char style[200],dummy_line[200],command[200],sdum[7];
	char *start;


	dummy=fgets(dummy_line,80,fp);	/* zoom file */

	while( dummy != NULL)
	{

		if (strchr(dummy_line,'[') != 0)                  
		{
			dummy=fgets(dummy_line,80,fp);
			sscanf(dummy_line,"%d%d%d%d",&x,&y,&w,&h);

			read_file(dx+x,dy+y,fp);
		
			dummy=fgets(dummy_line,80,fp);
			dummy=fgets(dummy_line,80,fp);
			dummy=fgets(dummy_line,80,fp);
	
		}
		else 
			if (strchr(dummy_line,']') != 0) 
				return(1);
			else
			{                                          
				sscanf(dummy_line,"%d%d%d%d",&x,&y,&w,&h);

				fgets(command,200,fp);
	
  			  	fgets(style,100,fp);
				dummy=fgets(dummy_line,200,fp);
				dummy=fgets(dummy_line,200,fp);
				dummy=fgets(dummy_line,200,fp);
	
				sscanf(style,"%s %d",sdum,&l_style) ;

				if (interpret(command,x+dx,y+dy,w,h,l_style) <0)
				printf("ERROR with interpret ReGIS \n");
                                        
			} /* end of not [ or ] */

	}   /* end of while */

	
}


main(argc,argv)
int argc;
char *argv[];
{
	FILE *fopen();
	char c,line[256];
	short unsigned class,element,listlen;
	short unsigned header;
	int tlen,i;

/*** let's see, what do we need to do? ***/                  
/* open mdraw file */
/* open metafile */

/* write standard header */

/* for each drawing command in mdraw file */
	/* write drawing command */

/* write standard ending */

/* close mdraw file */
/* close metafile */
/*** that's it... so.... ***/

/***** lets do it !!!! ******/

/* open mdraw file */

	if (argc <= 1)
	{
	 printf("no input file specified\n");
	 printf("format: mdr2cgm <infile.mdr> <outfile.cgm> \n");
	 return(1);
	}

	/* open input file */
	if ( (fin=fopen(argv[1],"r")) == NULL)
	{
	 printf("error opening output \n");
	 return(1);
	}

/* open metafile */

	if (argc <= 2)     
	{
	 printf("no metafile output specified\n");
	 printf("format: mdr2cgm %s <outfile.cgm> \n",argv[1]);
	 return(1);
	}
	/* open output metafile */
	if ( (fout=fopen(argv[2],"w")) == NULL)
	{
	 printf("error opening output \n");
	 return(1);
	}

/* write standard header */
	standard_header(argv[1]);

	begin_picture("PICTURE1");

/* for each line , draw command */
        
	fseek(fin,0L,0);
	fgets(line,100,fin);	/* toss first line */

	read_file(0,0,fin);

	end_picture();

/* write standard ending */
	standard_ending();

/* close mdraw file */
	fclose(fin);
/* close metafile */
	fclose(fout);


}
