/* threadmill.c */
#include <p2c/p2c.h>

typedef enum {
  Conventional, Climb } Direction_type;

Static double CenterX, CenterY, ToolDia, BoreDia, BoreRadius, FeedRate,
	      Side, Offset, CurRadius,
              X, Y, Z, I, TPI, ThreadPitch, BoreDepth,
	      J, NX, NY, NR, CurX, CurY, CurZ, CentDist, ToolRadius;
Static double LineNo;
Static Direction_type Direction;
Static Char FileName[256];
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 Thread Mill Diameter, Major Diameter (real):");
  scanf("%lg%lg%*[^\n]", &ToolDia, &BoreDia);
  getchar();
  printf("\nEnter Feed Rate (IPM):");
  scanf("%lg%*[^\n]", &FeedRate);
  getchar();
  printf("\nEnter Threads / Inch, Thread Depth:");
  scanf("%lg%lg%*[^\n]", &TPI, &BoreDepth);
  getchar();
  printf("\nEnter 1 for Conventional, 2 for Climb milling:");
  scanf("%lg%*[^\n]",&I);
  getchar();
  if (I == 2.0)
    Direction = Climb;
  else
    Direction = Conventional;
  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;
  WriteLineNo();
  fprintf(OutFile,"G01 G17 G90 F30 ");
  ToolRadius = ToolDia / 2.0;
  BoreRadius = BoreDia / 2.0;
  Offset = BoreRadius - ToolRadius;
  CurX = CenterX;
  CurY = CenterY;
  if (Direction == Climb)
    CurZ = -BoreDepth;
  else
    CurZ = 0.0;
  ThreadPitch = 1.0 / TPI;
  putc('X',OutFile);
  OutNum(CurX,4L);
  fprintf(OutFile," Y");
  OutNum(CurY,4L);
  putc('\n',OutFile);
  WriteLineNo();
  fprintf(OutFile,"Z");
  OutNum(CurZ,4L);
  putc('\n',OutFile);
  WriteLineNo();
  putc('F',OutFile);
  OutNum(FeedRate,3L);
  fprintf(OutFile," X");
  OutNum(CenterX+Offset,4L);
  putc('\n',OutFile);
  if (Direction == Climb)
{
  Side = -1.0;
  /* loop to cut spiral path at each depth increment */
  for (CurZ = BoreDepth - (ThreadPitch / 2.0);
          CurZ >= -0.001 - (ThreadPitch / 2.0);
          CurZ -= (ThreadPitch / 2.0) )
    {
      /*    printf("BoreDepth = %9.4f, CurZ = %9.4f",BoreDepth,CurZ); */
    WriteLineNo();
    fprintf(OutFile, "G03 ");   /* Circular Interpolation */
    putc('X', OutFile);
    OutNum(CenterX+(Offset*Side), 4L);
    fprintf(OutFile, " I");
    OutNum(Offset*Side, 4L);
    fprintf(OutFile, " Z");
    OutNum(-CurZ, 4L);
    putc('\n', OutFile);

    Side = Side * -1.0;
	  
      }       /* for CurZ ... */
} /* if climb */
else
  {
  Side = -1.0;
  /* loop to cut spiral path at each depth increment */
  for (CurZ = (ThreadPitch / 2.0);
          CurZ <= (BoreDepth+ThreadPitch/2.0+0.001);
          CurZ += (ThreadPitch / 2.0) )
    {
      /*    printf("BoreDepth = %9.4f, CurZ = %9.4f",BoreDepth,CurZ); */
    WriteLineNo();
    fprintf(OutFile, "G02 ");   /* Circular Interpolation */
    putc('X', OutFile);
    OutNum(CenterX+(Offset*Side), 4L);
    fprintf(OutFile, " I");
    OutNum(Offset*Side, 4L);
    fprintf(OutFile, " Z");
    OutNum(-CurZ, 4L);
    putc('\n', OutFile);

    Side = Side * -1.0;
	  
      }       /* for CurZ ... */
}
  WriteLineNo();
  fprintf(OutFile,"G01 X");      /* return to center */
  OutNum(CenterX,4L);
  fprintf(OutFile," Y");
  OutNum(CenterY,4L);
   putc('\n',OutFile);
  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. */

