/**
   * Computes the closest points on two line segments.
   *
   * @param line the segment to find the closest point to
   * @return a pair of Coordinates which are the closest points on the line segments
   */
  public Coordinate[] closestPoints(LineSegment line) {
    // test for intersection
    Coordinate intPt = intersection(line);
    if (intPt != null) {
      return new Coordinate[] {intPt, intPt};
    }

    /**
     * if no intersection closest pair contains at least one endpoint. Test each endpoint in turn.
     */
    Coordinate[] closestPt = new Coordinate[2];
    double minDistance = Double.MAX_VALUE;
    double dist;

    Coordinate close00 = closestPoint(line.p0);
    minDistance = close00.distance(line.p0);
    closestPt[0] = close00;
    closestPt[1] = line.p0;

    Coordinate close01 = closestPoint(line.p1);
    dist = close01.distance(line.p1);
    if (dist < minDistance) {
      minDistance = dist;
      closestPt[0] = close01;
      closestPt[1] = line.p1;
    }

    Coordinate close10 = line.closestPoint(p0);
    dist = close10.distance(p0);
    if (dist < minDistance) {
      minDistance = dist;
      closestPt[0] = p0;
      closestPt[1] = close10;
    }

    Coordinate close11 = line.closestPoint(p1);
    dist = close11.distance(p1);
    if (dist < minDistance) {
      minDistance = dist;
      closestPt[0] = p1;
      closestPt[1] = close11;
    }

    return closestPt;
  }
  /*
   * (non-Javadoc)
   *
   * @see com.iver.cit.gvsig.gui.cad.snapping.ISnapper#getSnapPoint(Point2D
   * point, IGeometry geom,double tolerance, Point2D lastPointEntered)
   */
  public Point2D getSnapPoint(
      Point2D point, IGeometry geom, double tolerance, Point2D lastPointEntered) {
    Point2D resul = null;
    Coordinate c = new Coordinate(point.getX(), point.getY());

    if (lastPointEntered == null) {
      return null;
    }

    Coordinate cLastPoint = new Coordinate(lastPointEntered.getX(), lastPointEntered.getY());
    PathIterator theIterator =
        geom.getPathIterator(null, FConverter.FLATNESS); // polyLine.getPathIterator(null,
    // flatness);
    double[] theData = new double[6];
    double minDist = tolerance;
    Coordinate from = null;
    Coordinate first = null;

    while (!theIterator.isDone()) {
      // while not done
      int theType = theIterator.currentSegment(theData);

      switch (theType) {
        case PathIterator.SEG_MOVETO:
          from = new Coordinate(theData[0], theData[1]);
          first = from;

          break;

        case PathIterator.SEG_LINETO:

          // System.out.println("SEG_LINETO");
          Coordinate to = new Coordinate(theData[0], theData[1]);
          LineSegment line = new LineSegment(from, to);
          Coordinate closestPoint = line.closestPoint(cLastPoint);
          double dist = c.distance(closestPoint);

          if (!(line.getCoordinate(0).equals2D(closestPoint)
              || line.getCoordinate(1).equals2D(closestPoint))) {
            if ((dist < minDist)) {
              resul = new Point2D.Double(closestPoint.x, closestPoint.y);
              minDist = dist;
            }
          }

          from = to;

          break;

        case PathIterator.SEG_CLOSE:
          line = new LineSegment(from, first);
          closestPoint = line.closestPoint(cLastPoint);
          dist = c.distance(closestPoint);

          if (!(line.getCoordinate(0).equals2D(closestPoint)
              || line.getCoordinate(1).equals2D(closestPoint))) {
            if ((dist < minDist)) {
              resul = new Point2D.Double(closestPoint.x, closestPoint.y);
              minDist = dist;
            }
          }

          from = first;

          break;
      } // end switch

      theIterator.next();
    }

    return resul;
  }