/*
 * Copyright (c) 1992, The Geometry Center
 *                     University of Minnesota 
 *                     1300 South Second Street
 *                     Minneapolis, MN  55454
 *
 * email address: software@geom.umn.edu
 *
 * This software is copyrighted as noted above.  It may be freely copied,
 * modified, and redistributed, provided that the copyright notice is
 * preserved on all copies.
 *
 * There is no warranty or other guarantee of fitness for this software,
 * it is provided solely "as is".  Bug reports or fixes may be sent
 * to the authors, who may or may not act on them as they desire.
 *
 * You may not include this software in a program or other software product
 * without supplying the source, or without informing the end-user that the
 * source is available for no extra charge.
 *
 * If you modify this software, you should include a notice giving the
 * name of the person performing the modification, the date of modification,
 * and the reason for such modification.
 *
 *     The National Science and Technology Research Center for
 *      Computation and Visualization of Geometric Structures
 */

#include <stdio.h>
#include <stdlib.h>
#import <objc/objc.h>
#include "link_types.h"
#include "link_edit_types.h"
#include "link_edit_global.h"
#import "EditView.h"

void LinkDCTranslateLink(LinkStatus *gnrc,LinkList *lnk,float dx,float dy)

{
  LinkPointList *pnt;

  pnt = lnk->point.next;
  while(pnt != NULL) {
     pnt->dcx += dx; pnt->dcy += dy;
     LinkComputePointWorldCoords(gnrc,pnt);
     pnt = pnt->next;
    }

  pnt = lnk->point.next;
  while(pnt != NULL) {
     LinkReComputeEdgeCrossings(gnrc,lnk,pnt);
     pnt = pnt->next;
    }
}


/*** Functions used for new crossing menu items ***/

void resetVisited(LinkStatus *gnrc)
{
  LinkList *lnk = gnrc->link.next;
  while (lnk != NULL)
    {
      lnk->visited = 0;
      lnk = lnk->next;
    }
}


LinkCrossingList *getNextXing(LinkList *lnk, LinkPointList **pnt)
{
  LinkCrossingList *xing = NULL;
  LinkPointList *firstpnt = *pnt;
  while ((xing = (*pnt)->crossing.next) == NULL)
    {
      *pnt = (*pnt)->next;
      if (*pnt == NULL)
	{
	  if (lnk->closed)
	    *pnt = lnk->point.next;
	  else break;
	}
      if (*pnt == firstpnt) break;
    }
  return xing;
}

void alternateFromCrossing(LinkPointList *pnt,
			   LinkCrossingList *xing)
{
  LinkCrossingList *firstxing = xing;
  LinkList *lnk = pnt->linkptr;
  double nextz = -xing->z;
  if (lnk->visited) return;
  lnk->visited = 1;
  if (xing->next == NULL)
    {
      pnt = pnt->next;
      if (pnt == NULL && lnk->closed) pnt = lnk->point.next;
    }
  while ((xing = ((xing->next) ? xing->next :
		  getNextXing(lnk, &pnt)))
	 != firstxing && xing != NULL)
    {
      xing->z = nextz; xing->crossing->z = -nextz;
      nextz = -nextz;
      alternateFromCrossing(xing->partner, xing->crossing);
      if (xing->next == NULL)
	{
	  pnt = pnt->next;
	  if (pnt == NULL && lnk->closed) pnt = lnk->point.next;
	}
    }
}

void reflectLink(LinkStatus *gnrc)
{
  LinkList *lnk;
  LinkPointList *pnt;
  LinkCrossingList *cross;

  lnk = gnrc->link.next;
  while(lnk != NULL) {
    pnt = lnk->point.next;
    while(pnt != NULL) {
      cross = pnt->crossing.next;
      while(cross != NULL)
	{
	  cross->z = -cross->z;
	  cross = cross->next;
	}
      pnt = pnt->next;
    }
    lnk = lnk->next;
  }
}
