/*
 *                         wedge.c
 *
 *       shade wedge (WG) and edge wedge (EW) instructions stuff
 *
 *   Marek Krawus, PCC,  March '89
 */

#include "defn.h"

#define   CCW   0
#define   CW    1

#define   ER1   "ERROR: parameter in EW/WG instruction is out of range"
#define   ER2   "ERROR: too few parameters in EW/WG instruction\n"

wedge( kind )
char   kind;        /* S - shade wedge,    E - edge wedge  */
{
  float         radius;
  int           radius_indicator;
  float         start_angle;
  float         sweep_angle;
  float         chord_angle;
  int           psi;
  int           psi_up;
  int           psi_down;
  int           sweep_abs;
  int           i;
  float         betarad;
  float         chord_size;
  float         epsilon;

  int           fill;
  int           zwrot;
  float         xRad;
  float         yRad;
  float         pocz_angle;
  float         kon_angle;
  float         dopeln_angle; 
  float         spacing;

  end_draw();

  if (test_token())  {
      radius = getval();
      if ((radius < -32768.0)||(radius > 32767.9999))  {
	 fprintf(stderr, "%s -> radius\n", ER1);
	 return;
      }
      if (radius < 0.0) {
	 radius_indicator = 1;
	 radius = - radius;
      }   else radius_indicator = 0;
      radius *= XSCALE;
  }  else  return;

  if (test_token())   {
     start_angle = getval();

     if ((start_angle < -32768.0)||(start_angle > 32767.0))  {
	 fprintf(stderr, "%s -> start angle\n", ER1);
	 return;
     }
     if(start_angle < 0.0) {while (start_angle <= -360.0) start_angle += 360.0;}
     else { while (start_angle >= 360.0) start_angle -= 360.0; }

     if (start_angle != (float)rintx(start_angle)) {
	fprintf(stderr,"ERROR: start angle parameter in EW/WG instruction \
	is not in integer format\n");
	return;
     }
  }
  else   {
        fprintf(stderr, "%s", ER2);
        return;
  }


  if (test_token())   {
     sweep_angle = getval();

     if ((sweep_angle < -32768.0)||(sweep_angle > 32767.0))  {
	 fprintf(stderr, "%s -> sweep angle\n", ER1);
	 return;
     }

     if (sweep_angle != (float)rintx(sweep_angle)) {
	fprintf(stderr,"ERROR: sweep angle parameter in EW/WG instruction \
	is not in integer format\n");
	return;
     }
    
     if (sweep_angle < -360.0) sweep_angle = -360.0;
     if (sweep_angle > 360.0) sweep_angle = 360.0; 
  }
  else   {
        fprintf(stderr, "%s", ER2);
        return;
  }
  
  if (test_token())   {
     chord_angle = getval();

     if ((chord_angle < 1.0)||(chord_angle > 120.0))  {
	 fprintf(stderr, "%s -> chord angle\n", ER1);
	 return;
     }

     if (chord_angle != (float)rintx(chord_angle)) {
	fprintf(stderr,"ERROR: chord angle parameter in EW/WG instruction \
	is not in integer format\n");
	return;
     }

     psi = rintx( chord_angle );
     psi = abs( psi );
     if (psi < 5) goto zero;

     psi_up = psi_down = psi;
     sweep_abs = abs((int)sweep_angle);
     if (sweep_abs > psi)
	while ((sweep_abs % psi_up) != 0) psi_up++;
     while ((sweep_abs % psi_down) != 0) psi_down--; 

     if (sweep_abs > psi)
	psi = ((psi_up - psi) < (psi - psi_down))?(psi_up):(psi_down);
     else psi = psi_down;
     if (psi < 5) goto zero;

     i = sweep_abs / psi;
     betarad = deg_rad * ( psi / 2.0 );
     chord_size = 2 * radius * sin(betarad);
     if (chord_size < 0.00001) goto zero;
     epsilon = psi / 2.0 + 90.0;
     goto koniec;

zero:
     chord_angle = 0.0;

koniec:
     ;
   }  else chord_angle = 0.0;

  if (test_token())  
     fprintf(stderr,"WARNING: too many parameters in EW/WG instruction\n");

  if (kind == 'S') fill = 1; else fill = 0;

  if (sweep_angle < 0.0) zwrot = CW; else zwrot = CCW;

  xRad = radius;
  if (USER_UNITS) yRad = xRad * YSCALE / XSCALE; else yRad = xRad;

  if ((FILL_TYPE == 1)||(FILL_TYPE == 2)||(FILL_SPACING == 0.0))
     spacing = PEN_THICKNESS * RESOLUTION * XSCALE_ABS;     /* in mm */
  else spacing = FILL_SPACING * XSCALE;                 /* in mm */

  if ((FILL_TYPE == 1)||(FILL_TYPE == 2))   spacing /= 2;

  if (radius_indicator == 0)                  /* reference point == 0 deg */
     pocz_angle = start_angle;
  else
     pocz_angle = 180.0 + start_angle;         /* reference point == 180 deg */
     
  while (pocz_angle < 0.0) pocz_angle += 360.0;
  while (pocz_angle >= 360.0) pocz_angle -= 360.0;

  kon_angle = pocz_angle + sweep_angle;
  if (kon_angle > 360.0) kon_angle -= 360.0;
  if (kon_angle < 0.0) kon_angle += 360.0; 



  if (chord_angle == 0.0)
    fprintf(outfile, "%d %d %g %g %g %g %g %g %d %g %d WedgeSmooth\n",
		      fill,
		      zwrot,
		      absX,
		      absY,
		      xRad,
		      yRad,
		      pocz_angle,
		      kon_angle,
		      FILL_TYPE,
		      spacing,
		      FILL_ANGLE);
  else  {
    if (zwrot == CW) pocz_angle = kon_angle;
    dopeln_angle = 360 - (pocz_angle + i * psi);

    fprintf(outfile,"%d %g %g %g %g %g %g %d %g %d %g %g %d %d WedgeChord\n",
		      fill,
		      absX,
		      absY,
		      xRad,
		      yRad,
		      pocz_angle,
		      dopeln_angle,
		      FILL_TYPE,
		      spacing,
		      FILL_ANGLE,
		      chord_size,
		      epsilon,
		      psi,
		      i);
  }

}

