/* makering.c */

#include <p2c/p2c.h>

typedef enum {
  initial, Spiraling, finishing, LastLevel
} States_type;

typedef enum {
  linear, arc
} Interp_type;

Static double CenterX, CenterY, ToolDia, BoreDia, BoreRadius, FeedRate,
	      WidthOfCut, FinishWOC, FinishFeed, Offset, CurRadius,
              X, Y, Z, I, DepthPerPass, BoreDepth, CurFeed, OldFeed,
	      J, NX, NY, NR, CurX, CurY, CurZ, CentDist, ToolRadius;
Static double ArcCent, ArcRadius, OldRadius;
Static long Quadrant, FinQuadrant;
Static double LineNo;
Static States_type State;
Static Interp_type Interp;
Static Char FileName[256];
Static boolean Done;
Static FILE *OutFile;

Static Void OutNum(RealNum, SigFrac)
double RealNum;
long SigFrac;
{
  double i;
  int j;
  char format[8];

  for (i = 1.0, j = 0; i <= 6 || i<= abs(RealNum); i *= 10.0, j++)
    {}
  if (SigFrac > 0) 
    j += SigFrac+1;  /* J <= # int digits + 1 for decimal pt + #frac digits */
  if (RealNum < 0.0 )
    j += 1;          /* add a position for the minus sign */
  sprintf(format,"%%%d.%df",j,SigFrac);
    fprintf(OutFile, format, (RealNum));
}


Static Void WriteLineNo()
{
  putc('N', OutFile);
  OutNum(LineNo, 0L);
  LineNo += 10.0;
  putc(' ', OutFile);
}


main(argc, argv)
int argc;
Char *argv[];
{
  OutFile = NULL;
  printf("Enter Starting X,Y (real):");
  scanf("%lg%lg%*[^\n]", &CenterX, &CenterY);
  getchar();
  printf("\nEnter Tool Diameter, Post Diameter (real):");
  scanf("%lg%lg%*[^\n]", &ToolDia, &BoreDia);
  getchar();
  printf("\nEnter Feed Rate (IPM) (real):");
  scanf("%lg%*[^\n]", &FeedRate);
  getchar();
  printf("\nEnter Finish Feed Rate, Width of Cut (real):");
  scanf("%lg%lg%*[^\n]", &FinishFeed, &FinishWOC);
  getchar();
  printf("\nEnter Z Depth per Pass, Post Height:");
  scanf("%lg%lg%*[^\n]", &DepthPerPass, &BoreDepth);
  getchar();
  printf("\nEnter File Name for CAM output:");
  scanf("%s",FileName);
  putchar('\n');
  OutFile = fopen(FileName,"w");
  if (OutFile != NULL)
    rewind(OutFile);
  else
    OutFile = tmpfile();
  if (OutFile == NULL)
    exit(EXIT_FAILURE);
  LineNo = 10.0;
  ToolRadius = ToolDia / 2.0;
  BoreRadius = BoreDia / 2.0;
  /* safety test on Width of cut */
  /*  if (BoreRadius + ToolRadius + FinishWOC <= WidthOfCut)
    {
      printf("Width of Cut too large to spiral in to requested post.\n");
      exit(EXIT_FAILURE);
      }  */
  /* loop to cut spiral path at each depth increment */
  for (CurZ = -DepthPerPass;
          CurZ >= -BoreDepth-DepthPerPass+0.001; CurZ -= DepthPerPass)
    {
    if (CurZ < -BoreDepth)
      {
      CurZ = -BoreDepth;
      /*      State = LastLevel;  */
      }
    CurFeed = FeedRate;
    OldFeed = 0.0 ;             /* force feed rate to be set */
    WidthOfCut = 0.0;           /* hack to cut circle */
    WriteLineNo();
    fprintf(OutFile, "G01 ");   /* Linear Interpolation */
    Interp = linear;
    putc('F', OutFile);   /*set feedrate */
    OutNum(CurFeed, 3L);
    OldFeed = CurFeed;
    CurX = CenterX + BoreRadius + ToolRadius + FinishWOC;
    CurY = CenterY;
    putc(' ', OutFile);
    putc('X', OutFile);    /* Move to point on roughing ring */
    OutNum(CurX, 4L);
    fprintf(OutFile, " Y");
    OutNum(CurY, 4L);
    putc('\n', OutFile);

    WriteLineNo();
    fprintf(OutFile, "F");
    OutNum(FeedRate/6.0, 3L);
    fprintf(OutFile, " Z");  /* LOWER tool */
    OldFeed = 0.0;  /* force feedrate to be reset on next move */
    OutNum(CurZ,4L);
    putc('\n', OutFile);
    CurRadius = BoreRadius + ToolRadius + FinishWOC;
    OldRadius = CurRadius;
    Quadrant = 1;
    State = initial;
    Done = false;
    /*  loop to spiral out in quadrants */
    do {
      if (State == LastLevel) {
        CentDist = CurRadius;
	ArcRadius = CurRadius; }
      else {
        CentDist = CurRadius + WidthOfCut;
      /* compute where to put center of arc */
      ArcCent=(OldRadius*OldRadius - CurRadius*CurRadius)/(-2.0*CurRadius);
      ArcRadius = CurRadius - ArcCent;
      OldRadius = CurRadius; }
      switch (Quadrant) {

      case 1:
        NX = CenterX;
        NY = CenterY - CurRadius;
        NR = ArcRadius;
        break;

      case 2:
        NX = CenterX - CurRadius;
        NY = CenterY;
        NR = ArcRadius;
        break;

      case 3:
        NX = CenterX;
        NY = CenterY + CurRadius;
        NR = ArcRadius;
        break;

      case 4:
        NX = CenterX + CurRadius;
        NY = CenterY;
        NR = ArcRadius;
        break;
    }               /* switch */
      WriteLineNo();
      if (CurFeed != OldFeed) {
	fprintf(OutFile, "F");
	OutNum(CurFeed, 3L);
	fprintf(OutFile, " ");
	OldFeed = CurFeed;
      }
      if (Interp == linear)
	{
	  Interp = arc;
	  fprintf(OutFile, "G02 ");
	}
      putc('X', OutFile);
      OutNum(NX, 4L);
      fprintf(OutFile, " Y");
      OutNum(NY, 4L);
      fprintf(OutFile, " R");
      OutNum(NR, 4L);
      putc('\n', OutFile);
      if (State == Spiraling) {
        if (Quadrant < 4)
	  CurRadius += WidthOfCut / 4.0;
        else {
	  printf("Cur Z = %12.4f BoreDepth = %12.4f\n",CurZ,BoreDepth);
	  if (State == Spiraling && CurZ <= -BoreDepth)
	  {
	    State = LastLevel;
	    FinQuadrant = 1;
	    printf("State is LastLevel\n");   /* bore to finish diameter */
	  CurRadius = BoreRadius + ToolRadius;
	  CurFeed = FinishFeed;   /*set finish feedrate */
          }
	  else Done = TRUE;
	}
      }
      if (State == LastLevel)
	{
	  FinQuadrant++;
	  if (FinQuadrant > 6)
	    { Done = TRUE;
	    }
	}
      if (State == initial) {
        if (CurRadius > WidthOfCut)
	  State = Spiraling;
        CurRadius += WidthOfCut / 4.0;
      }
      Quadrant++;
      if (Quadrant > 4)
        Quadrant = 1;
    } while (!Done);
    }       /* for CurZ ... */
   WriteLineNo();
   fprintf(OutFile, "G01 F50 Z0.1\n");   /* raise spindle above work */
  WriteLineNo();
  fprintf(OutFile, "M02\n");   /*End of Program */
  if (OutFile != NULL)
    fclose(OutFile);
  OutFile = NULL;
  if (OutFile != NULL)
    fclose(OutFile);
  exit(EXIT_SUCCESS);
}

/* End. */










