/**
   * Test when user add new icon, after that repeats click on icon and chaotic click on map to move
   * editing icon At the end is succ finish => icon should be at the last click position
   */
  private void tstClickOnMapEditingAndFinish() {
    // simple add and finish adding of new item
    map.clearOverlays();
    mapAddOverlayEvents.clear();
    mapRemoveOverlayEvents.clear();
    MapControllerT mc = new MapControllerT(map, service);
    mc.startAdding();
    LatLng ll1 = getRandomLatLng();
    mc.onMapClick(new MapClickEvent(map, null, ll1, null));
    mc.finishWorking(false);

    // now presenter is calling web service to save and after succ. save is called onAddItem
    MapItem mapItem = RandomGenerator.genMapItem(false);
    LatLng mapItemLatLng = LatLng.newInstance(mapItem.getY(), mapItem.getX());
    mc.addMapItem(mapItem);
    MapItemOverlay<MapItem> mi = (MapItemOverlay<MapItem>) mapAddOverlayEvents.get(1).getOverlay();
    DataComparator.assertEquals(mapItemLatLng, mi.getLatLng());

    // simulate click on icon
    mc.startEditing(mi);

    LatLng ll = null;
    for (int i = 0; i < 10; i++) // just chaotic click, icon should moves
    {
      ll = getRandomLatLng();
      mc.onMapClick(new MapClickEvent(map, null, ll, null));
      DataComparator.assertEquals(ll, mi.getLatLng());
      DataComparator.assertEquals(mapItemLatLng, mc.mStartEditLatLng);
    }

    mc.finishWorking(false); // finished => not canceled
    assertEquals(mc.mState, State.Default);
    assertNull(mc.mCurrentMarker);
    assertNull(mc.mStartEditLatLng);
    // after finish nothing should happen
    assertEquals(1, mc.mCurrentVisibleMapItems.size());
    assertEquals(2, mapAddOverlayEvents.size());
    assertEquals(1, mapRemoveOverlayEvents.size());
    // only editing icon should be at the last click position
    DataComparator.assertEquals(ll, mi.getLatLng());
  }
  /** Test click on maps during adding state to move adding icon */
  private void tstClickOnMapAddingMoving() {
    map.clearOverlays();
    mapAddOverlayEvents.clear();
    mapRemoveOverlayEvents.clear();

    MapControllerT mc = new MapControllerT(map, service);
    mc.startAdding();

    LatLng ll1 = getRandomLatLng();
    mc.onMapClick(new MapClickEvent(map, null, ll1, null));
    assertEquals(1, mapAddOverlayEvents.size());
    Marker marker = (Marker) mapAddOverlayEvents.get(0).getOverlay();
    DataComparator.assertEquals(ll1, marker.getLatLng());
    DataComparator.assertEquals(ll1, mc.mCurrentMarker.getLatLng());
    assertNull(mc.mStartEditLatLng);

    LatLng ll2 = getRandomLatLng();
    mc.onMapClick(new MapClickEvent(map, null, ll2, null));
    assertEquals(1, mapAddOverlayEvents.size());
    DataComparator.assertEquals(ll2, mc.mCurrentMarker.getLatLng());
    DataComparator.assertEquals(ll2, marker.getLatLng());

    for (int i = 0; i < 10; i++) {
      LatLng ll = getRandomLatLng();
      mc.onMapClick(new MapClickEvent(map, null, ll, null));
      assertEquals(1, mapAddOverlayEvents.size());
      DataComparator.assertEquals(ll, mc.mCurrentMarker.getLatLng());
      DataComparator.assertEquals(ll, marker.getLatLng());
    }

    mc.finishWorking(true);
    assertEquals(1, mapRemoveOverlayEvents.size());
    assertNull(mc.mCurrentMarker);
  }
  /** Just simple test and check states what happen if new icon is added to map */
  private void tstClickOnMapAdding() {
    map.clearOverlays();
    mapAddOverlayEvents.clear();
    mapRemoveOverlayEvents.clear();

    // test for click in default state => should happen nothing
    MapControllerT mc = new MapControllerT(map, service);
    assertEquals(0, mapAddOverlayEvents.size());
    LatLng ll1 = getRandomLatLng();
    mc.onMapClick(new MapClickEvent(map, null, ll1, null));
    assertEquals(0, mapAddOverlayEvents.size());

    assertNull(mc.mCurrentMarker);
    assertNull(mc.mStartEditLatLng);
    assertEquals(mc.mState, State.Default);
    mc.startAdding();
    assertEquals(mc.mState, State.Adding);
    assertNull(mc.mCurrentMarker);
    assertNull(mc.mStartEditLatLng);
    assertEquals(mc.currentCursor, Cursor.CROSSHAIR.toString());

    // simulate click
    mc.onMapClick(new MapClickEvent(map, null, ll1, null));
    assertEquals(1, mapAddOverlayEvents.size());
    Marker mm = (Marker) mapAddOverlayEvents.get(0).getOverlay();
    DataComparator.assertEquals(ll1, mm.getLatLng());
    assertEquals(mc.mCurrentMarker, mm);

    // cancel adding
    assertEquals(0, mapRemoveOverlayEvents.size());
    mc.finishWorking(true);
    assertEquals(1, mapRemoveOverlayEvents.size());
    assertEquals(mc.mState, State.Default);
    assertNull(mc.mCurrentMarker);
    assertNull(mc.mStartEditLatLng);
    assertNull(mc.currentCursor);

    LatLng ll2 = getRandomLatLng();
    mc.onMapClick(new MapClickEvent(map, null, ll1, null));
    assertEquals(1, mapAddOverlayEvents.size());
  }
  private void tstLoadData() {
    // simple add and finish adding of new item
    map.clearOverlays();
    mapAddOverlayEvents.clear();
    mapRemoveOverlayEvents.clear();

    MapControllerT mc = new MapControllerT(map, service);
    randomData = new ArrayList<MapItem>();
    int iterator = 0;
    for (; iterator < 20; iterator++) {
      MapItem mi = RandomGenerator.genMapItem(false);
      mi.setId(iterator); // init ids
      randomData.add(mi);
    }

    service.setOnGetListener(
        new MockDataServiceAsync.OnGetListener() {
          @Override
          public void get(
              String className, String filters, boolean deep, AsyncCallback<List<?>> callback) {}

          @Override
          public void get(
              String className,
              double x1,
              double x2,
              double y1,
              double y2,
              boolean deep,
              AsyncCallback<List<?>> callback) {
            callback.onSuccess(randomData);
          }

          @Override
          public void get(String className, AsyncCallback<List<?>> callback) {}
        });

    // simulate map drag move
    LatLngBounds llb =
        LatLngBounds.newInstance(LatLng.newInstance(0, 0), LatLng.newInstance(80, 80));
    mc.loadIcons(12, llb); // just ensure about good zoom limit
    assertTrue(mc.calledOnLoad); // should becalled
    mc.calledOnLoad = false;
    assertEquals(randomData.size(), mc.mCurrentVisibleMapItems.size()); // this icons should be here
    assertEquals(randomData.size(), mapAddOverlayEvents.size());

    // call again, no new icon should be added into map
    mc.loadIcons(12, llb); //
    assertTrue(mc.calledOnLoad); // should becalled
    mc.calledOnLoad = false;
    assertEquals(randomData.size(), mc.mCurrentVisibleMapItems.size()); // this icons should be here
    assertEquals(randomData.size(), mapAddOverlayEvents.size());

    // add 10 new icons into database simulates different db result depending on latlngbounds
    for (; iterator < 30; iterator++) {
      MapItem mi = RandomGenerator.genMapItem(false);
      mi.setId(iterator); // init ids
      randomData.add(mi);
    }

    // call again, only 10 news icon should be added into map
    mc.loadIcons(12, llb); //
    assertTrue(mc.calledOnLoad); // should becalled
    mc.calledOnLoad = false;
    assertEquals(randomData.size(), mc.mCurrentVisibleMapItems.size()); // this icons should be here
    assertEquals(randomData.size(), mapAddOverlayEvents.size());

    for (int i = 0; i < iterator; i++) {
      long l = i;
      // check added data, should be same
      assertTrue(mc.mCurrentVisibleMapItems.containsKey(l));
      MapItemOverlay<MapItem> mi =
          (MapItemOverlay<MapItem>) mapAddOverlayEvents.get(i).getOverlay();
      DataComparator.assertEquals(randomData.get(i), mi.getMapItem(), true);
      DataComparator.assertEquals(randomData.get(i), mi.getMapItem(), true);
    }
  }