/*
	WARNING: This file was generated by dkct.
	Changes you make here will be lost if dkct is run again!
	You should modify the original source and run dkct on it.
	Original source: test-xsp.ctr
*/

/**	@file test-xsp.c The test-xsp module.
*/


#line 4 "test-xsp.ctr"

#include "dk3all.h"
#include "dk3fig.h"
#include "dk3xsp.h"


/**	Run test to produce PS output.
*/
#define TEST_PS		0

/**	Run test for lengths.
*/
#define	TEST_LENGTHS	1

/**	Do test with NUMPOINTS points.
*/
#define	TEST_NUMPOINTS	1

/**	Run test around critical point t=5.
*/
#define	TEST_CRITICAL_POINT	1

/**	Find a t for a given distance.
*/
#define	TEST_T_FOR_DISTANCE	1

/**	Number of test points to calculate left and right length.
*/
#define	NUMPOINTS	1000

/**	When producing PS output create curves, not polylines.
*/
#define	TEST_PS_CURVES	0

/**	Number of lines or Bezier segments per X-spline segment.
*/
#define	NUM_SEGMENTS	16

/**	Flag: For compatibility implement spline bug.
*/
#define	FLAG_CB		0



#line 47 "test-xsp.ctr"



static dk3_fig_spline_point_t const pointData[] = {
  {  36.0, 108.0,  0.0 },	/* P0 */
  {  72.0, 180.0, -1.0 },	/* P1 */
  { 252.0, 180.0, -1.0 },	/* P2 */
  { 288.0, 108.0, -1.0 },	/* P3 */
  { 252.0,  36.0,  1.0 },	/* P4 */
  { 468.0,  36.0,  1.0 },	/* P5 */
  { 432.0, 108.0,  0.0 }	/* P6 */
};
static const size_t szPointData =
sizeof(pointData) / sizeof(dk3_fig_spline_point_t);


static double fslc[] = {
  -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0
};
static const size_t szFslc = sizeof(fslc)/sizeof(double);

static dkChar const gn[] = { "test" };

DK3_MAIN
{
  dk3_xspline_segment_t	 seg;
  dk3_app_t		*app;
  size_t		 i;
  size_t		 j;
  double		 t;
  double		 x;
  double		 y;
  double		 dxdt;
  double		 dydt;
  double		 lastx;
  double		 lasty;
  double		 lastdxdt;
  double		 lastdydt;
  double		 lgt;
  double		 d;
  double		 prevval;
  double		 direction;
  int			 ec = 0;
  

#line 91 "test-xsp.ctr"
  

#line 92 "test-xsp.ctr"
  dk3xsp_reset(&seg);
  dk3xsp_set_cb(&seg, FLAG_CB);
  app = dk3app_open_command(argc, (dkChar const * const *)argv, gn);
  if(app) {
    prevval = 0.0;

#if	TEST_PS
/* PS drawing tests. (start) */
    /*
    	Draw skeleton.
    */
    fputs("%PS\n", stdout);
    fputs("0 setlinewidth\n", stdout);
    fputs("newpath\n", stdout);
    for(i = 0; i < szPointData; i++) {
      if(0 == i) {
        fprintf(stdout, "%lg %lg moveto\n", pointData[i].x, pointData[i].y);
      } else {
        fprintf(stdout, "%lg %lg lineto\n", pointData[i].x, pointData[i].y);
      }
    }
    fputs("stroke\n", stdout);
#if	TEST_PS_CURVES
    /*
    	Draw series of Bezier splines.
    */
    fputs("1 setlinewidth\n", stdout);
    fputs("newpath\n", stdout);
    for(i = 0; i < (szPointData - 1); i++) {	

#line 121 "test-xsp.ctr"
      dk3xsp_set(
        &seg,
	((i > 0) ? (&(pointData[i - 1])) : NULL),
	&(pointData[i]),
	&(pointData[i+1]),
	((i < (szPointData - 2)) ? (&(pointData[i+2])) : NULL)
      );
      dk3xsp_calculate(&seg, 0.0, 1);
      lastx = dk3xsp_get_x(&seg);
      lasty = dk3xsp_get_y(&seg);
      lastdxdt = dk3xsp_get_dxdt(&seg) / NUM_SEGMENTS;
      lastdydt = dk3xsp_get_dydt(&seg) / NUM_SEGMENTS;
      if(0 == i) {
        fprintf(
	  stdout, "%lg %lg moveto\n",
	  dk3xsp_get_x(&seg), dk3xsp_get_y(&seg)
        );
      }
      for(j = 1; j <= NUM_SEGMENTS; j++) {	

#line 140 "test-xsp.ctr"
        if(NUM_SEGMENTS == j) {
	  t = 1.0;
	} else {
	  t = (double)j / (double)NUM_SEGMENTS;
	}
	dk3xsp_calculate(&seg, t, 1);
	x = dk3xsp_get_x(&seg);
	y = dk3xsp_get_y(&seg);
	dxdt = dk3xsp_get_dxdt(&seg) / NUM_SEGMENTS;
	dydt = dk3xsp_get_dydt(&seg) / NUM_SEGMENTS;
	

#line 151 "test-xsp.ctr"
	

#line 152 "test-xsp.ctr"
	fprintf(
	  stdout,
	  "%lg %lg %lg %lg %lg %lg curveto\n",
	  (lastx + lastdxdt / 3.0),
	  (lasty + lastdydt / 3.0),
	  (x - dxdt / 3.0),
	  (y - dydt / 3.0),
	  x,
	  y
	);
	lastdxdt = dxdt; lastdydt = dydt; lastx = x; lasty = y;
      }
    }
    fputs("stroke\n", stdout);
#else
    /*
    	Draw sequence of lines.
    */
    fputs("1 setlinewidth\n", stdout);
    fputs("newpath\n", stdout);
    for(i = 0; i < (szPointData - 1); i++) {	

#line 173 "test-xsp.ctr"
      dk3xsp_set(
        &seg,
	((i > 0) ? (&(pointData[i - 1])) : NULL),
	&(pointData[i]),
	&(pointData[i+1]),
	((i < (szPointData - 2)) ? (&(pointData[i+2])) : NULL)
      );
      if(0 == i) {
        dk3xsp_calculate(&seg, 0.0, 0);
	fprintf(
	  stdout, "%lg %lg moveto\n",
	  dk3xsp_get_x(&seg), dk3xsp_get_y(&seg)
	);
      }
      for(j = 1; j <= NUM_SEGMENTS; j++) {	

#line 188 "test-xsp.ctr"
        if(NUM_SEGMENTS == j) {
	  t = 1.0;
	} else {
	  t = (double)j / (double)NUM_SEGMENTS;
	}
	dk3xsp_calculate(&seg, t, 0);
	fprintf(
	  stdout, "%lg %lg lineto\n",
	  dk3xsp_get_x(&seg), dk3xsp_get_y(&seg)
	);
      }
    }
    fputs("stroke\n", stdout);
#endif

/* PS drawing tests. (end) */

#else
#if	TEST_LENGTHS
/* Length calculation tests. (start) */

    lgt = dk3xsp_open_spline_length(
      pointData,
      szPointData,
      (120.0 / 25400.0),
      fslc,
      0,
      &ec
    );
    for(i = 0; i < szFslc; i++) {
      printf("fslc[%u] = %lg\n", (unsigned)i, fslc[i]);
    }

#if TEST_NUMPOINTS
    for(i = 0; i <= NUMPOINTS; i++) {
      d = ((double)(szPointData - 1)) * (double)i / (double)NUMPOINTS;
      lastx = dk3xsp_open_spline_partial_length(
        pointData,
	szPointData,
	(1200.0 / 25400.0),
	d,
	fslc,
	1,
	0,
	&ec
      );
      lasty = dk3xsp_open_spline_partial_length(
        pointData,
	szPointData,
	(1200.0 / 25400.0),
	d,
	fslc,
	0,
	0,
	&ec
      );
      printf(
      "Pass %3u  t=%-6.4lg  left=%7lg  right=%7lg  summary=%7lg\n     delta=%7lg\n",
      (unsigned)i, d, lastx, lasty, (lastx + lasty), fabs(lastx - prevval));
      prevval = lastx;
      dk3xsp_calculate_position(
        &seg,
	pointData,
	szPointData,
	d,
	FLAG_CB,
	1,
	&ec
      );
      printf("    x=%7lg  y=%7lg  dxdt=%7lg  dydt=%7lg  dsdt=%7lg\n",
        dk3xsp_get_x(&seg),
	dk3xsp_get_y(&seg),
	dk3xsp_get_dxdt(&seg),
	dk3xsp_get_dydt(&seg),
	sqrt(
	  dk3xsp_get_dxdt(&seg) * dk3xsp_get_dxdt(&seg)
	  + dk3xsp_get_dydt(&seg) * dk3xsp_get_dydt(&seg)
	)
      );
      if(i > 0) {
        printf("    s=%7lg\n",
	  sqrt(
	    (x - dk3xsp_get_x(&seg)) * (x - dk3xsp_get_x(&seg))
	    + (y - dk3xsp_get_y(&seg)) * (y - dk3xsp_get_y(&seg))
	  )
	);
      }
      direction = dk3xsp_direction(
        pointData, szPointData, d, FLAG_CB, &ec
      );
      printf("    direction = %lg\n", (180.0 * direction) / M_PI);
      x = dk3xsp_get_x(&seg);
      y = dk3xsp_get_y(&seg);
    }
#endif
#if TEST_CRITICAL_POINT
    dk3xsp_reset(&seg);
    dk3xsp_set_cb(&seg, FLAG_CB);
    

#line 287 "test-xsp.ctr"
    dk3xsp_calculate_position(
      &seg,
      pointData,
      szPointData,
      4.999,
      FLAG_CB,
      1,
      &ec
    );
    

#line 297 "test-xsp.ctr"
    lastx = dk3xsp_open_spline_partial_length(
        pointData,
	szPointData,
	(1200.0 / 25400.0),
	4.999,
	fslc,
	1,
	0,
	&ec
    );
    lasty = dk3xsp_open_spline_partial_length(
        pointData,
	szPointData,
	(1200.0 / 25400.0),
	4.999,
	fslc,
	0,
	0,
	&ec
    );
    printf(
      "4.999:  left=%7lg  right=%7lg  summary=%7lg\n",
      lastx, lasty, (lastx + lasty)
    );
    prevval = lastx;
    

#line 323 "test-xsp.ctr"
    lastx = dk3xsp_open_spline_partial_length(
        pointData,
	szPointData,
	(1200.0 / 25400.0),
	5.0,
	fslc,
	1,
	0,
	&ec
    );
    lasty = dk3xsp_open_spline_partial_length(
        pointData,
	szPointData,
	(1200.0 / 25400.0),
	5.0,
	fslc,
	0,
	0,
	&ec
    );
    printf(
      "5.0  :  left=%7lg  right=%7lg  summary=%7lg  delta=%7lg\n",
      lastx, lasty, (lastx + lasty), (lastx - prevval)
    );
    prevval = lastx;
    

#line 349 "test-xsp.ctr"
    lastx = dk3xsp_open_spline_partial_length(
        pointData,
	szPointData,
	(1200.0 / 25400.0),
	5.001,
	fslc,
	1,
	0,
	&ec
    );
    lasty = dk3xsp_open_spline_partial_length(
        pointData,
	szPointData,
	(1200.0 / 25400.0),
	5.001,
	fslc,
	0,
	0,
	&ec
    );
    printf(
      "5.001:  left=%7lg  right=%7lg  summary=%7lg  delta=%7lg\n",
      lastx, lasty, (lastx + lasty), (lastx - prevval)
    );
    prevval = lastx;
#endif
    printf("Length = %lg\t\tec = %d\n", lgt, ec);

#if TEST_T_FOR_DISTANCE
    lastx = dk3xsp_get_t_for_distance(pointData, szPointData, 100.0,
    (1200.0/25400.0), fslc, 0, 0, NULL);
    if(lastx >= 0.0) {
      printf("t = %lg\n", lastx);
    }
    lastx = dk3xsp_get_t_for_distance(pointData, szPointData, 100.0,
    (1200.0/25400.0), fslc, 1, 0, NULL);
    if(lastx >= 0.0) {
      printf("t = %lg\n", lastx);
    }
#endif


/* Length calculation tests. (end) */
#else
/* --- Other tests here --- */
#endif
#endif



    dk3app_close(app);
  }
  

#line 402 "test-xsp.ctr"
  

#line 403 "test-xsp.ctr"
  exit(0); return 0;
}

