/* The routines in this file are copyright (c) 1987 by Helene (Lee) Taran.
 * Permission is granted for use and free distribution as long as the
 * original author's name is included with the code.
 */

/*
 * Reformatted, and modified to compile without warnings and errors
 * under SAS/C -6.5x by gduncan@philips.oz.au (GMD). This included
 * proto generation, renaming of some literals to avoid name collisions,
 * and Amiga Version string (also displayed in Title bar).
 * No original version number, this version arbitrarily named 1.1. 
 * - otherwise no functional changes.
 * GMD - Sep 94
 */

#include "all.h"


/* Draw_Natural_Bspline : draws the bspline with natural ends that
 * is defined by the list of <control_points>. Assumes that there
 * are at least three control points.
 */

void
Draw_Natural_Bspline (w, control_points)
     WINDOW *w;
     DLISTPTR control_points;

{
  REAL_POINT t1, t2, t3, t4, first, last;
  DLISTPTR a = FIRST (control_points);
  DLISTPTR b = NEXT (a);
  DLISTPTR c = NEXT (b);

  first = *POINT (a);
  TickMark (&t1, 1, 3, POINT (a), POINT (b));
  TickMark (&t2, 2, 3, POINT (a), POINT (b));
  if (DrawAFrame)
    DrawConstructionLine (w, POINT (a), POINT (b));
  while (1)
    {
      if (b == LAST (control_points))
	{
	  DrawBezierArc (w, &first, &t1, &t2, POINT (b));
	  return;
	}
      TickMark (&t3, 1, 3, POINT (b), POINT (c));
      TickMark (&t4, 2, 3, POINT (b), POINT (c));
      TickMark (&last, 1, 2, &t2, &t3);
      if (DrawAFrame)
	{
	  DrawConstructionLine (w, POINT (b), POINT (c));
	  DrawConstructionLine (w, &t2, &t3);
	}
      DrawBezierArc (w, &last, &t2, &t1, &first);
      first = last;
      t1 = t3;
      t2 = t4;
      a = b;
      b = c;
      c = NEXT (c);
    }
}

/* Draw_TripleKnot_Bspline : draws the bspline with triple knots at the ends
 * defined by the list of <control_points>. Assumes that there
 * are at least four control points.
 */

void
Draw_TripleKnot_Bspline (w, control_points)
     WINDOW *w;
     DLISTPTR control_points;
{
  REAL_POINT t1, t2, t3, t4, first, last;
  DLISTPTR a = FIRST (control_points);
  DLISTPTR b = NEXT (a);
  DLISTPTR c = NEXT (b);
  DLISTPTR d = NEXT (c);

  if (DrawAFrame)
    DrawConstructionLine (w, POINT (a), POINT (b));

  first = *POINT (a);
  t1 = *POINT (b);
  if (LENGTH (control_points) == 4)
    t2 = *POINT (c);
  else
    TickMark (&t2, 1, 2, POINT (b), POINT (c));

  while (1)
    {

      if (d == LAST (control_points))
	{			/* draw the last arc */
	  if (DrawAFrame)
	    {
	      DrawConstructionLine (w, POINT (b), POINT (c));
	      DrawConstructionLine (w, POINT (c), POINT (d));
	    }
	  DrawBezierArc (w, &first, &t1, &t2, POINT (d));
	  return;
	}

      if (d == PREVIOUS (LAST (control_points)))
	{
	  TickMark (&t3, 1, 2, POINT (c), POINT (d));
	  t4 = *POINT (d);
	}
      else
	{
	  TickMark (&t3, 1, 3, POINT (c), POINT (d));
	  TickMark (&t4, 2, 3, POINT (c), POINT (d));
	}

      TickMark (&last, 1, 2, &t2, &t3);
      if (DrawAFrame)
	{
	  DrawConstructionLine (w, POINT (b), POINT (c));
	  DrawConstructionLine (w, &t2, &t3);
	}
      DrawBezierArc (w, &last, &t2, &t1, &first);
      first = last;
      t1 = t3;
      t2 = t4;
      a = b;
      b = c;
      c = d;
      d = NEXT (d);
    }
}



/* Draw_Closed_Bspline : draws the closed bspline that
 * is defined by the list of <control_points>. Assumes that there
 * are at least three control points. 
 */

void
Draw_Closed_Bspline (w, control_points)
     WINDOW *w;
     DLISTPTR control_points;
{
  REAL_POINT t1, t2, t3, t4, first, last;
  DLISTPTR a = FIRST (control_points);
  DLISTPTR b = NEXT (a);
  DLISTPTR c = NEXT (b);

  TickMark (&t1, 2, 3, POINT (LAST (control_points)), POINT (a));
  TickMark (&t2, 1, 3, POINT (a), POINT (b));
  TickMark (&first, 1, 2, &t1, &t2);
  if (DrawAFrame)
    DrawConstructionLine (w, POINT (a), POINT (b));
  do
    {
      if (b == LAST (control_points))
	c = FIRST (control_points);
      TickMark (&t3, 2, 3, POINT (a), POINT (b));
      TickMark (&t4, 1, 3, POINT (b), POINT (c));
      TickMark (&last, 1, 2, &t3, &t4);
      if (DrawAFrame)
	{
	  DrawConstructionLine (w, POINT (b), POINT (c));
	  DrawConstructionLine (w, &t3, &t4);
	}
      DrawBezierArc (w, &first, &t2, &t3, &last);
      first = last;
      t1 = t3;
      t2 = t4;
      a = b;
      b = c;
      c = NEXT (c);
    }
  while (a != FIRST (control_points));
}
/*--*/
