/*
   * (non-Javadoc)
   *
   * @see br.org.archimedes.factories.SelectionPointVectorFactory#drawVisualHelper(br.org.archimedes.model.writers.Writer,
   *      java.util.Set, br.org.archimedes.model.Point,
   *      br.org.archimedes.model.Vector)
   */
  @Override
  protected void drawVisualHelper(Set<Element> selection, Point reference, Vector vector) {

    OpenGLWrapper opengl = br.org.archimedes.Utils.getOpenGLWrapper();
    for (Element element : selection) {
      Element copied = element.clone();
      try {
        Point start = reference;
        Point end = start.addVector(vector);

        List<Point> points = new LinkedList<Point>();
        points.add(start);
        points.add(end);
        opengl.drawFromModel(points);

        copied.mirror(start, end);
        copied.draw(opengl);
      } catch (NullArgumentException e) {
        // Should not happen
        e.printStackTrace();
      } catch (Exception e) {
        // Might happen, just ignore
      }
    }
  }
  private Element generateSemiline(ComparablePoint clickPoint, Point initialPoint)
      throws NullArgumentException, InvalidArgumentException {

    Vector director = new Vector(clickPoint.getPoint(), initialPoint);
    Point endPoint =
        new Point(initialPoint.getX() + director.getX(), initialPoint.getY() + director.getY());

    return new Semiline(initialPoint, endPoint);
  }
  /*
   * (non-Javadoc)
   *
   * @see com.tarantulus.archimedes.factories.TwoPointFactory#drawVisualHelper(com.tarantulus.archimedes.model.writers.Writer,
   *      com.tarantulus.archimedes.model.Point,
   *      com.tarantulus.archimedes.model.Point)
   */
  @Override
  protected void drawVisualHelper(Point start, Point end) {

    try {
      InfiniteLine xline = new InfiniteLine(start.getX(), start.getY(), end.getX(), end.getY());
      xline.draw(br.org.archimedes.Utils.getOpenGLWrapper());
    } catch (InvalidArgumentException e) {
      // Draw nothing
    }
  }
  public SortedSet<ComparablePoint> getSortedPointSet(
      InfiniteLine line, Point referencePoint, Collection<Point> intersectionPoints) {

    SortedSet<ComparablePoint> sortedPointSet = new TreeSet<ComparablePoint>();

    Point otherPoint = line.getInitialPoint();
    if (referencePoint.equals(line.getInitialPoint())) {
      otherPoint = line.getEndingPoint();
    }

    Vector direction = new Vector(referencePoint, otherPoint);
    for (Point point : intersectionPoints) {
      Vector pointVector = new Vector(referencePoint, point);
      double key = direction.dotProduct(pointVector);
      ComparablePoint element;
      try {
        element = new ComparablePoint(point, new DoubleKey(key));
        sortedPointSet.add(element);
      } catch (NullArgumentException e) {
        // Should never reach
        e.printStackTrace();
      }
    }

    return sortedPointSet;
  }
  /**
   * Makes the mirror command
   *
   * @param copy true if the mirror is to copy the elements, false otherwise.
   * @return A nice message to the user.
   */
  private String makeCommand(boolean copy) {

    try {
      Point start = reference;
      Point end = reference.addVector(vector);
      command = new MirrorCommand(elements, start, end, copy);
    } catch (Exception e) {
      // Should not happen
      e.printStackTrace();
    }
    deactivate();
    return copy ? Messages.FinishedCopy : Messages.FinishedMove;
  }