/* FUNCTION: mimStrps                                                  */
/* Output is specific to PostScript                                    */
/* Function takes a pointer to an array of type MIMPOINT and processes */
/* it into the desired output.  This is a specific implementation of   */
/* general function mimStr.  All line conditions are assumed to be set */
/* before mimStr is called.                                            */
/*                                                                     */
/* F.R.Broome                                             20 June 1994 */
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

int  MIMlinetypeSearch(char *c, int *n, float l[]);
void getPtsFromDist(float xa, float xb, float ya, float yb, float s,
                    float *x, float *y);


/* There should be a header file in the main program that contains the
   following global data type.                                                          
      typedef struct {
        float   x, y;
        } MIMPOINT;

*/
#ifndef MIM_POINTS

#define MIM_POINTS 1

typedef struct {
  float   x, y;
  } MIMPOINT;
 
#endif


int mimStrps(mimPts, numPts, solidLineFlag)
   MIMPOINT      *mimPts;  /* A malloc'd array type MIMPOINT            */
   long          numPts;   /* An single variable of points this line.   */
   int           solidLineFlag; /* 0 = dashed, 1 = solid.               */
{
extern FILE      *psfile;
extern float     offsetX, offsetY, deviceFactor;
extern float     ltsValues[64];
extern char      lts[32];
MIMPOINT         mimPoint;
int              ltsFlag, workFlag, numValues, lineTypeFlag, num = 0;
int              firstPointFlag = 1;
long             i, k, n = 0;
long             numValuess;
float            x, y, xd, yd, ltLength, ltypeLength;
float            segLength, fromX, fromY;

if(solidLineFlag)
  {
  fprintf(psfile, "newpath\n");
  for(i = 0; i < numPts; i++)          /* For this many points.*/
    {
    mimPoint = *(mimPts+i);      /* Get the nth point from the array. */
    x = (mimPoint.x + offsetX) * deviceFactor;
    y = (mimPoint.y + offsetY) * deviceFactor;
    fprintf( psfile, "%0.3f %0.3f ",x,y);
    if( firstPointFlag )
      {
      firstPointFlag = 0;
      fprintf(psfile, "moveto\n");
      }
    else
      {
      fprintf(psfile, "lineto\n");
      }
    n++;                     /* Increment array pointer. */
    }     /*End for-loop reading one parts worth of points. */
  fprintf(psfile, "stroke\n");
  }
else/* Not solid, so break according to lts rules. */
  {
  i = MIMlinetypeSearch( lts, &num, ltsValues );
  ltypeLength = ltsValues[0];  /*Initialize*/
  ltsFlag = 1;
  /*Very tricky processing one point pair at a time, but will try.*/
  for(i = 0; i < numPts; i++)
    {
    mimPoint = *(mimPts+i);      /* Get the nth point from the array. */
    x = mimPoint.x;  /* Use raw coordinates. */
    y = mimPoint.y;
    /* BEGIN LINE TYPE PROCESSING */
    if( firstPointFlag )
      {
      fromX = x;
      fromY = y;
      segLength = 0;
      numValues = 0;
      ltLength = fabs(ltsValues[0]);
      if( ltsValues[0] < 0.0 )
        lineTypeFlag = 1;  /*Set to draw (pen down). */
      else
        lineTypeFlag = 0;  /*Set to no-draw (pen up).*/
      x = ( x + offsetX ) * deviceFactor; /* Convert to display */
      y = ( y + offsetY ) * deviceFactor;
      fprintf( psfile, "%0.3f %0.3f ",x,y);
      firstPointFlag = 0;
      fprintf(psfile, "moveto\n");
      }
    else  /* not first point, so process segnemt. */
      {
      segLength = sqrt((x-fromX)*(x-fromX) + (y-fromY)*(y-fromY));
      if( segLength > ltLength )
        {
        workFlag = 1;
        while( workFlag )
          {
          /* Subtract dash length used from seg length. */
          segLength -= ltLength;

          /* Check remaining segLength now so can process short */
          /*     if necessary                                   */
          if( segLength < 0.0 )
            {
            segLength += ltLength;  /* Restore to positive length.*/
            /* Process the remainder of the segment to the end x,y */
            xd = (x + offsetX) * deviceFactor; /*Convert to display*/
            yd = (y + offsetY) * deviceFactor;
            fprintf( psfile, "%0.3f %0.3f ", xd, yd);
            if( lineTypeFlag )
              fprintf(psfile, "lineto\n");
            else
              fprintf(psfile, "moveto\n");
            fromX = x;   fromY = y;
            workFlag = 0;
            ltLength -= segLength; /*Note subtract used part.*/
            continue;
            }

          /* Compute x,y-coordinates of dash along seg line. */
          getPtsFromDist( fromX, x, fromY, y, ltLength, &xd, &yd );

          fromX = xd;   /* Set new dash start point. */
          fromY = yd;

          /* Output this dash. */
          xd = (xd + offsetX) * deviceFactor; /*Convert to display*/
          yd = (yd + offsetY) * deviceFactor;
          fprintf( psfile, "%0.3f %0.3f ", xd, yd);
          if( lineTypeFlag )
            fprintf(psfile, "lineto\n");
          else
            fprintf(psfile, "moveto\n");

          /* Get next ltLength (Circular indexing.) */
          numValues++;
          if( !(numValues % num) )
            numValues = 0;
          ltLength = fabs(ltsValues[numValues]);
          if( ltsValues[numValues] < 0.0 )
            lineTypeFlag = 1;  /*Set to draw (pen down). */
          else
            lineTypeFlag = 0;  /*Set to no-draw (pen up).*/

           } /* End while condition. */
         }
       else    /* segLength is < ltLength so, */
         {
         fromX = x;    /* Save new from x,y-point. */
         fromY = y;

         xd = (x + offsetX) * deviceFactor; /*Convert to display*/
         yd = (y + offsetY) * deviceFactor;

         fprintf( psfile, "%0.3f %0.3f ", xd, yd); /*Output pt. */
                       /* Output this dash. */
         if( lineTypeFlag )
           fprintf(psfile, "lineto\n");
         else
           fprintf(psfile, "moveto\n");

         ltLength -= segLength;   /* Shorten dash by segLength. */
         }
       }   /*End not-first point if. */
     }     /*End for-loop reading one line of points. */
   fprintf(psfile, "stroke\n");
   }
return(1);
}