/*
  * Test method for 'net.refractions.udig.tools.edit.support.PrimitiveShape.getPoint(int)'
  */
 @Test
 public void testGetPoint() {
   assertEquals(Point.valueOf(10, 10), shell.getPoint(0));
   assertEquals(Point.valueOf(11, 10), shell.getPoint(1));
   assertEquals(Point.valueOf(10, 10), shell.getPoint(2));
   assertEquals(Point.valueOf(2, 20), shell.getPoint(3));
   assertEquals(Point.valueOf(4000, 8000), shell.getPoint(4));
 }
 /*
  * Test method for 'net.refractions.udig.tools.edit.support.PrimitiveShape.hasVertex(Point)'
  */
 @Test
 public void testHasVertexPoint() {
   assertTrue(shell.hasVertex(Point.valueOf(10, 10)));
   assertTrue(shell.hasVertex(Point.valueOf(11, 10)));
   assertTrue(shell.hasVertex(Point.valueOf(2, 20)));
   assertTrue(shell.hasVertex(Point.valueOf(4000, 8000)));
   assertFalse(shell.hasVertex(Point.valueOf(40, 40)));
 }
  @Test
  public void testRemovePoint() throws Exception {
    bb.removeCoordsAtPoint(10, 10);

    assertEquals(Point.valueOf(11, 10), shell.getPoint(0));
    assertEquals(Point.valueOf(2, 20), shell.getPoint(1));
    assertEquals(Point.valueOf(4000, 8000), shell.getPoint(2));
  }
 /*
  * Test method for 'net.refractions.udig.tools.edit.support.PrimitiveShape.getCoord(int)'
  */
 @Test
 public void testGetCoord() {
   assertEquals(bb.toCoord(Point.valueOf(10, 10)), shell.getCoord(0));
   assertEquals(bb.toCoord(Point.valueOf(11, 10)), shell.getCoord(1));
   assertEquals(bb.toCoord(Point.valueOf(10, 10)), shell.getCoord(2));
   assertEquals(bb.toCoord(Point.valueOf(2, 20)), shell.getCoord(3));
   assertEquals(bb.toCoord(Point.valueOf(2, 20)), shell.getCoord(4));
   assertEquals(bb.toCoord(Point.valueOf(4000, 8000)), shell.getCoord(5));
   assertEquals(bb.toCoord(Point.valueOf(4000, 8000)), shell.getCoord(6));
 }
  @Test
  public void testRemoveCoordinate() throws Exception {

    bb.removeCoordinate(4, shell.getCoord(6), shell);
    assertEquals(bb.toCoord(Point.valueOf(10, 10)), shell.getCoord(0));
    assertEquals(bb.toCoord(Point.valueOf(11, 10)), shell.getCoord(1));
    assertEquals(bb.toCoord(Point.valueOf(10, 10)), shell.getCoord(2));
    assertEquals(bb.toCoord(Point.valueOf(2, 20)), shell.getCoord(3));
    assertEquals(bb.toCoord(Point.valueOf(2, 20)), shell.getCoord(4));
    assertEquals(bb.toCoord(Point.valueOf(4000, 8000)), shell.getCoord(5));
  }
 /**
  * @param numGeoms number of expected geometries
  * @param numShellPoints expected number of points in shells of each geometry
  * @param numHoles expected number of holes of each geometry
  * @param numHolesPoints expected number of points in all holes of each geometry
  */
 private void assertPixMapState(
     EditBlackboard map, int numGeoms, int numShellPoints, int numHoles, int numHolesPoints) {
   assertEquals("numGeoms", numGeoms, map.getGeoms().size()); // $NON-NLS-1$
   for (EditGeom geom : map.getGeoms()) {
     assertEquals("numShellPoints", numShellPoints, geom.getShell().getNumPoints()); // $NON-NLS-1$
     assertEquals("numHoles", numHoles, geom.getHoles().size()); // $NON-NLS-1$
     for (PrimitiveShape hole : geom.getHoles()) {
       assertEquals(
           "numHolesPoints ", numHolesPoints, hole.getNumPoints()); // $NON-NLS-1$
     }
   }
 }
  @Test
  public void testMoveGeom() throws Exception {
    TestEditBlackboard bb = new TestEditBlackboard();
    EditGeom geom = bb.getGeoms().get(0);
    PrimitiveShape shell = geom.getShell();
    bb.addPoint(10, 10, shell);
    bb.addPoint(11, 10, shell);
    bb.addPoint(12, 10, shell);
    bb.addPoint(13, 10, shell);
    bb.addPoint(14, 10, shell);

    bb.moveSelection(1, 0, geom.createSelection());

    assertEquals(Point.valueOf(11, 10), shell.getPoint(0));
    assertEquals(Point.valueOf(12, 10), shell.getPoint(1));
    assertEquals(Point.valueOf(13, 10), shell.getPoint(2));
    assertEquals(Point.valueOf(14, 10), shell.getPoint(3));
    assertEquals(Point.valueOf(15, 10), shell.getPoint(4));
  }
 /*
  * Test method for 'net.refractions.udig.tools.edit.support.PrimitiveShape.iterator()'
  */
 @Test
 public void testIterator() {
   Iterator<Point> iter = shell.iterator();
   assertTrue(iter.hasNext());
   assertEquals(Point.valueOf(10, 10), iter.next());
   assertEquals(Point.valueOf(11, 10), iter.next());
   assertEquals(Point.valueOf(10, 10), iter.next());
   assertEquals(Point.valueOf(2, 20), iter.next());
   assertEquals(Point.valueOf(4000, 8000), iter.next());
 }
 /*
  * Test method for 'net.refractions.udig.tools.edit.support.PrimitiveShape.coordArray()'
  */
 @Test
 public void testCoordArray() {
   Coordinate[] array = shell.coordArray();
   assertEquals(bb.toCoord(Point.valueOf(10, 10)), array[0]);
   assertEquals(bb.toCoord(Point.valueOf(11, 10)), array[1]);
   assertEquals(bb.toCoord(Point.valueOf(10, 10)), array[2]);
   assertEquals(bb.toCoord(Point.valueOf(2, 20)), array[3]);
   assertEquals(bb.toCoord(Point.valueOf(2, 20)), array[4]);
   assertEquals(bb.toCoord(Point.valueOf(4000, 8000)), array[5]);
   assertEquals(bb.toCoord(Point.valueOf(4000, 8000)), array[6]);
 }
  /*
   * Test method for 'net.refractions.udig.tools.edit.support.PrimitiveShape.coordIterator()'
   */
  @Test
  public void testCoordIterator() {

    Iterator<Coordinate> iter = shell.coordIterator();
    assertTrue(iter.hasNext());
    assertEquals(bb.toCoord(Point.valueOf(10, 10)), iter.next());
    assertEquals(bb.toCoord(Point.valueOf(11, 10)), iter.next());
    assertEquals(bb.toCoord(Point.valueOf(10, 10)), iter.next());
    assertEquals(bb.toCoord(Point.valueOf(2, 20)), iter.next());
    assertEquals(bb.toCoord(Point.valueOf(2, 20)), iter.next());
    assertEquals(bb.toCoord(Point.valueOf(4000, 8000)), iter.next());
    assertEquals(bb.toCoord(Point.valueOf(4000, 8000)), iter.next());
  }
  private boolean isDoneInternal() {
    if (nextPoint != null) return false;

    if (points != null && points.hasNext()) {
      nextPoint = points.next();
      return false;
    }

    // points is null or is done so get next shape
    while (shapes.hasNext()) {
      currentShape = shapes.next();

      points = currentShape.iterator();

      if (points.hasNext()) {
        nextPoint = points.next();
        break;
      }
    }

    return nextPoint == null;
  }
  @Test
  public void testLakeDrawingCase() throws Exception {
    URL url = TestsPlugin.getDefault().getBundle().getResource("data/lake.gml"); // $NON-NLS-1$
    InputStream in = url.openConnection().getInputStream();

    InputStreamReader filereader = new InputStreamReader(in);

    InputSource input = new InputSource(filereader);
    DefaultFeatureCollection collection = new DefaultFeatureCollection();
    GMLReceiver receiver = new GMLReceiver(collection);
    GMLFilterFeature filterFeature = new GMLFilterFeature(receiver);
    GMLFilterGeometry filterGeometry = new GMLFilterGeometry(filterFeature);
    GMLFilterDocument filterDocument = new GMLFilterDocument(filterGeometry);
    try {
      // parse xml
      XMLReader reader = XMLReaderFactory.createXMLReader();
      reader.setContentHandler(filterDocument);
      reader.parse(input);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }

    SimpleFeature feature = collection.features().next();
    ReferencedEnvelope bounds = new ReferencedEnvelope(feature.getBounds());
    bounds =
        new ReferencedEnvelope(
            bounds.getMinX() - (bounds.getWidth() / 8),
            bounds.getMaxX() + (bounds.getWidth() / 8),
            bounds.getMinY() - (bounds.getHeight() / 4),
            bounds.getMaxY() + (bounds.getHeight() / 4),
            DefaultGeographicCRS.WGS84);
    EditBlackboard map =
        new EditBlackboard(
            SCREEN.x,
            SCREEN.y,
            ScaleUtils.worldToScreenTransform(bounds, new Dimension(100, 100)),
            layerToWorld);

    map.setGeometries((Geometry) feature.getDefaultGeometry(), null);

    Polygon poly = (Polygon) ((MultiPolygon) feature.getDefaultGeometry()).getGeometryN(0);

    PrimitiveShape shell = map.getGeoms().get(0).getShell();
    assertEquals(poly.getExteriorRing().getCoordinates().length, shell.getNumCoords());
    for (int i = 0; i < shell.getNumCoords(); i++) {
      assertEquals(
          "i=" + i, poly.getExteriorRing().getCoordinateN(i), shell.getCoord(i)); // $NON-NLS-1$
    }
    assertEquals(shell.getCoord(0), shell.getCoord(shell.getNumCoords() - 1));
    assertEquals(shell.getPoint(0), shell.getPoint(shell.getNumPoints() - 1));

    List<PrimitiveShape> holes = map.getGeoms().get(0).getHoles();

    for (int j = 0; j < holes.size(); j++) {
      PrimitiveShape hole = holes.get(j);
      for (int i = 0; i < hole.getNumCoords(); i++) {
        assertEquals(
            "hole=" + j + "i=" + i,
            poly.getInteriorRingN(j).getCoordinateN(i),
            hole.getCoord(i)); // $NON-NLS-1$ //$NON-NLS-2$
      }
      assertEquals(hole.getCoord(0), hole.getCoord(hole.getNumCoords() - 1));
      assertEquals(hole.getPoint(0), hole.getPoint(hole.getNumPoints() - 1));
    }
  }
  /*
   * Test method for 'org.locationtech.udig.tools.edit.support.PixelCoordMap.addCoord(int, int, Coordinate)'
   */
  @Test
  public void testAddCoord() {
    EventListener l = new EventListener();

    GeometryFactory factory = new GeometryFactory();
    Geometry geom = factory.createPoint(new Coordinate(10, 5));
    EditBlackboard map = new EditBlackboard(SCREEN.x, SCREEN.y, transform, layerToWorld);
    map.getListeners().add(l);

    map.setGeometries(geom, null);
    assertPixMapState(map, 1, 1, 0, 0);

    EditGeom geomShape = map.getGeoms().get(0);
    map.addPoint(10, 5, geomShape.getShell());
    assertPixMapState(map, 1, 2, 0, 0);
    assertEquals(1, map.getCoords(10, 5).size());
    assertEquals(EventType.ADD_POINT, l.getEditBlackboardEvent().getType());
    EditBlackboardEvent editBlackboardEvent = l.getEditBlackboardEvent();
    assertEquals(null, editBlackboardEvent.getOldValue());
    assertEquals(Point.valueOf(10, 5), editBlackboardEvent.getNewValue());

    LinearRing ring = createShellRing(factory, 10);

    map = new EditBlackboard(SCREEN.x, SCREEN.y, transform, layerToWorld);
    map.getListeners().add(l);
    Map<Geometry, EditGeom> mapping = map.setGeometries(ring, null);
    assertPixMapState(map, 1, 5, 0, 0);

    // add at a particular index.
    map.insertCoord(25, 15, 3, mapping.get(ring).getShell());
    assertEquals(Point.valueOf(20, 10), mapping.get(ring).getShell().getPoint(0));
    assertEquals(Point.valueOf(30, 10), mapping.get(ring).getShell().getPoint(1));
    assertEquals(Point.valueOf(30, 15), mapping.get(ring).getShell().getPoint(2));
    assertEquals(Point.valueOf(25, 15), mapping.get(ring).getShell().getPoint(3));
    assertEquals(Point.valueOf(20, 15), mapping.get(ring).getShell().getPoint(4));
    assertEquals(EventType.ADD_POINT, l.event.getType());
    editBlackboardEvent = l.getEditBlackboardEvent();
    assertEquals(null, editBlackboardEvent.getOldValue());
    assertEquals(Point.valueOf(25, 15), editBlackboardEvent.getNewValue());
    assertEquals(mapping.get(ring).getShell(), editBlackboardEvent.getSource());

    // create a geom one point at a time   test ordering of geometries
    map = new EditBlackboard(SCREEN.x, SCREEN.y, transform, layerToWorld);
    map.getListeners().add(l);
    geomShape = map.getGeoms().get(0);
    map.addPoint(0, 0, geomShape.getShell());
    map.addPoint(0, 100, geomShape.getShell());
    map.addPoint(50, 100, geomShape.getShell());
    map.addPoint(100, 100, geomShape.getShell());
    map.addPoint(50, 150, geomShape.getShell());

    assertEquals(Point.valueOf(0, 0), geomShape.getShell().getPoint(0));
    assertEquals(Point.valueOf(0, 100), geomShape.getShell().getPoint(1));
    assertEquals(Point.valueOf(50, 100), geomShape.getShell().getPoint(2));
    assertEquals(Point.valueOf(100, 100), geomShape.getShell().getPoint(3));
    assertEquals(Point.valueOf(50, 150), geomShape.getShell().getPoint(4));

    // test the coordinates were created correcly
    assertEquals(new Coordinate(-9.5, -4.5), geomShape.getShell().getCoord(0));
    assertEquals(new Coordinate(-9.5, 95.5), geomShape.getShell().getCoord(1));
    assertEquals(new Coordinate(40.5, 95.5), geomShape.getShell().getCoord(2));
    assertEquals(new Coordinate(90.5, 95.5), geomShape.getShell().getCoord(3));
    assertEquals(new Coordinate(40.5, 145.5), geomShape.getShell().getCoord(4));

    // now making sure the the CoordMap is correctly updated too.
    assertEquals(1, map.getCoords(0, 0).size());
    assertEquals(new Coordinate(-9.5, -4.5), map.getCoords(0, 0).get(0));
    assertEquals(1, map.getCoords(0, 100).size());
    assertEquals(new Coordinate(-9.5, 95.5), map.getCoords(0, 100).get(0));
    assertEquals(1, map.getCoords(0, 100).size());
    assertEquals(new Coordinate(40.5, 95.5), map.getCoords(50, 100).get(0));
    assertEquals(1, map.getCoords(0, 100).size());
    assertEquals(new Coordinate(90.5, 95.5), map.getCoords(100, 100).get(0));
    assertEquals(1, map.getCoords(50, 150).size());
    assertEquals(new Coordinate(40.5, 145.5), map.getCoords(50, 150).get(0));

    // insert a vertex in a hole
    Polygon polygon = createPolygon(factory, 10);
    map = new EditBlackboard(SCREEN.x, SCREEN.y, transform, layerToWorld);
    map.getListeners().add(l);
    mapping = map.setGeometries(polygon, null);
    assertPixMapState(map, 1, 5, 1, 5);

    // add at a particular index.
    PrimitiveShape hole = mapping.get(polygon).getHoles().get(0);
    map.insertCoord(26, 13, 3, hole);
    assertEquals(Point.valueOf(25, 12), hole.getPoint(0));
    assertEquals(Point.valueOf(28, 12), hole.getPoint(1));
    assertEquals(Point.valueOf(28, 13), hole.getPoint(2));
    assertEquals(Point.valueOf(26, 13), hole.getPoint(3));
    assertEquals(Point.valueOf(25, 13), hole.getPoint(4));
    editBlackboardEvent = l.getEditBlackboardEvent();
    assertEquals(null, editBlackboardEvent.getOldValue());
    assertEquals(Point.valueOf(26, 13), editBlackboardEvent.getNewValue());
    assertEquals(hole, editBlackboardEvent.getSource());

    // add on an edge test ordering of geometries
    LinearRing ring2 = createShellRing(factory, 30);
    LinearRing ring3 = createShellRing(factory, 32);

    ring3.getCoordinateN(2).y = 20;

    mapping = map.setGeometries(ring2, null);
    mapping.putAll(map.addGeometry(ring3, null));

    map.addToNearestEdge(54, 12, mapping.get(ring2), true);
    assertEquals(1, map.getCoords(54, 12).size());
    assertEquals(new Coordinate(44.5, 7.5), mapping.get(ring2).getShell().getCoord(2));
    editBlackboardEvent = l.getEditBlackboardEvent();
    assertEquals(null, editBlackboardEvent.getOldValue());
    assertEquals(Point.valueOf(54, 12), editBlackboardEvent.getNewValue());
    assertEquals(mapping.get(ring2).getShell(), editBlackboardEvent.getSource());

    mapping = map.setGeometries(ring2, null);
    mapping.putAll(map.addGeometry(ring3, null));

    List<ClosestEdge> added = map.addToNearestEdge(51, 12, true);
    assertEquals(2, added.size());
    assertTrue(
        added.get(0).getGeom() == mapping.get(ring3)
            || added.get(1).getGeom() == mapping.get(ring3));
    assertTrue(
        added.get(0).getGeom() == mapping.get(ring2)
            || added.get(1).getGeom() == mapping.get(ring2));
    assertEquals(2, map.getCoords(51, 12).size());
    assertEquals(new Coordinate(41.5, 7.5), mapping.get(ring2).getShell().getCoord(2));
    assertEquals(new Coordinate(41.5, 7.5), mapping.get(ring3).getShell().getCoord(2));
    editBlackboardEvent = l.getEditBlackboardEvent();
    assertEquals(null, editBlackboardEvent.getOldValue());
    assertEquals(Point.valueOf(51, 12), editBlackboardEvent.getNewValue());
    assertTrue(((Collection) l.event.getSource()).contains(added.get(0).getPart()));
    assertTrue(((Collection) l.event.getSource()).contains(added.get(1).getPart()));

    // create hole one point at a time
    map = new EditBlackboard(SCREEN.x, SCREEN.y, transform, layerToWorld);
    map.getListeners().add(l);
    geomShape = map.getGeoms().get(0);
    hole = geomShape.newHole();
    try {
      map.addPoint(0, 0, null);
      fail();
    } catch (Exception e) {
      // good
    }

    map.addPoint(0, 0, hole);
    assertEquals(Point.valueOf(0, 0), l.getEditBlackboardEvent().getNewValue());
    map.addPoint(0, 100, hole);
    assertEquals(Point.valueOf(0, 100), l.getEditBlackboardEvent().getNewValue());
    map.addPoint(50, 100, hole);
    assertEquals(Point.valueOf(50, 100), l.getEditBlackboardEvent().getNewValue());
    map.addPoint(100, 100, hole);
    assertEquals(Point.valueOf(100, 100), l.getEditBlackboardEvent().getNewValue());
    map.addPoint(50, 150, hole);
    assertEquals(null, l.getEditBlackboardEvent().getOldValue());
    assertEquals(Point.valueOf(50, 150), l.getEditBlackboardEvent().getNewValue());
    assertEquals(hole, l.getEditBlackboardEvent().getSource());

    assertEquals(Point.valueOf(0, 0), geomShape.getHoles().get(0).getPoint(0));
    assertEquals(Point.valueOf(0, 100), geomShape.getHoles().get(0).getPoint(1));
    assertEquals(Point.valueOf(50, 100), geomShape.getHoles().get(0).getPoint(2));
    assertEquals(Point.valueOf(100, 100), geomShape.getHoles().get(0).getPoint(3));
    assertEquals(Point.valueOf(50, 150), geomShape.getHoles().get(0).getPoint(4));

    // test the coordinates were created correcly
    assertEquals(new Coordinate(-9.5, -4.5), geomShape.getHoles().get(0).getCoord(0));
    assertEquals(new Coordinate(-9.5, 95.5), geomShape.getHoles().get(0).getCoord(1));
    assertEquals(new Coordinate(40.5, 95.5), geomShape.getHoles().get(0).getCoord(2));
    assertEquals(new Coordinate(90.5, 95.5), geomShape.getHoles().get(0).getCoord(3));
    assertEquals(new Coordinate(40.5, 145.5), geomShape.getHoles().get(0).getCoord(4));

    // now making sure the the CoordMap is correctly updated too.
    assertEquals(1, map.getCoords(0, 0).size());
    assertEquals(new Coordinate(-9.5, -4.5), map.getCoords(0, 0).get(0));
    assertEquals(1, map.getCoords(0, 100).size());
    assertEquals(new Coordinate(-9.5, 95.5), map.getCoords(0, 100).get(0));
    assertEquals(1, map.getCoords(0, 100).size());
    assertEquals(new Coordinate(40.5, 95.5), map.getCoords(50, 100).get(0));
    assertEquals(1, map.getCoords(0, 100).size());
    assertEquals(new Coordinate(90.5, 95.5), map.getCoords(100, 100).get(0));
    assertEquals(1, map.getCoords(50, 150).size());
    assertEquals(new Coordinate(40.5, 145.5), map.getCoords(50, 150).get(0));

    // call add to edge so that it is added to a hole
    polygon = createPolygon(factory, 10);
    LinearRing ring1 = createShellRing(factory, 10);
    mapping = map.setGeometries(ring1, null);
    mapping.putAll(map.addGeometry(polygon, null));

    added = map.addToNearestEdge(26, 12, true);
    assertEquals(1, added.size());
    assertEquals(6, added.iterator().next().getGeom().getHoles().get(0).getNumCoords());

    map = new EditBlackboard(SCREEN.x, SCREEN.y, transform, this.layerToWorld);
    map.getListeners().add(l);
    added = map.addToNearestEdge(26, 12, true);
    assertEquals(Point.valueOf(26, 12), map.getGeoms().get(0).getShell().getPoint(0));
  }
 /*
  * Test method for 'net.refractions.udig.tools.edit.support.PrimitiveShape.getNumCoords()'
  */
 @Test
 public void testGetNumCoords() {
   assertEquals(7, shell.getNumCoords());
 }
 /*
  * Test method for 'net.refractions.udig.tools.edit.support.PrimitiveShape.getNumPoints()'
  */
 @Test
 public void testGetNumPoints() {
   assertEquals(5, shell.getNumPoints());
 }