/**
  * @param startPos
  * @param destPos
  * @param myResultingPath in this Wrapper the resulting path will be stored
  * @param byWalk
  * @return
  */
 public boolean getPathFromAtoB(
     GeoObj startPos, GeoObj destPos, Wrapper myResultingPath, boolean byWalk) {
   GeoGraph result = getPathFromAtoB(startPos, destPos, byWalk);
   if (result != null) {
     Log.d(LOG_TAG, "Found way on maps!");
     Log.d(LOG_TAG, "Path infos: " + result.toString());
     myResultingPath.setTo(result);
     return true;
   }
   Log.d(LOG_TAG, "No way on maps found :(");
   return false;
 }
  private void setToNextWayPoint(GeoGraph graph, GeoObj justCheckedNode) {

    EfficientList<GeoObj> followers = graph.getFollowingNodesOf(justCheckedNode);
    if (followers != null) {
      for (int i = 0; i < followers.myLength; i++) {
        GeoObj followingNode = followers.get(i);
        followingNode.setComp(newProxiSensor(graph));
        setHighlightNodeTransformations(followingNode.getGraphicsComponent());
        setHighlightEdgeTransformation(graph.getEdge(justCheckedNode, followingNode));
      }
    } else {
      Log.d(LOG_TAG, justCheckedNode + " has no following nodes");
    }
  }
 /**
  * This will search for a specified address and return the found results
  *
  * @param address
  * @param maxResults number of results
  * @return a {@link GeoGraph} with maxResults many {@link GeoObj}s as specified
  */
 public GeoGraph getLocationListForAddress(String address, int maxResults) {
   try {
     List<Address> addresses = myGeoCoder.getFromLocationName(address, maxResults);
     if (addresses.size() > 0) {
       GeoGraph result = new GeoGraph();
       for (int i = 0; i < addresses.size(); i++) {
         result.add(new GeoObj(addresses.get(i)));
       }
       return result;
     }
   } catch (IOException e) {
     e.printStackTrace();
   }
   return null;
 }
  @Override
  public boolean addNodeToGraph(final GeoGraph targetGraph, GeoObj newNode) {
    newNode.setComp(getNodeMesh());

    /*
     * its a geoObj so the diamond will automatically surrounded by a
     * mesh-group. change the color of this group:
     */
    setNormalTransformations(newNode.getGraphicsComponent());

    Log.d(
        LOG_TAG,
        "Adding obj "
            + newNode
            + " to graph with number of nodes="
            + targetGraph.getAllItems().myLength);

    return targetGraph.add(newNode);
  }
  @Override
  public boolean addFirstNodeToGraph(final GeoGraph targetGraph, GeoObj newNode) {
    newNode.setComp(getNodeMesh());
    newNode.setComp(newProxiSensor(targetGraph));

    setNormalTransformations(newNode.getGraphicsComponent());

    Log.d(LOG_TAG, "First node will be added now..");

    Log.d(
        LOG_TAG,
        "Adding obj "
            + newNode
            + " to graph with number of nodes="
            + targetGraph.getAllItems().myLength);

    Log.d(LOG_TAG, "Setting special props for first node.");
    setHighlightNodeTransformations(newNode.getGraphicsComponent());

    return targetGraph.add(newNode);
  }
  @Override
  public void addEdgeToGraph(GeoGraph targetGraph, GeoObj startPoint, GeoObj endPoint) {

    // add an edge:
    if (startPoint != null) {
      MeshComponent edgeMesh = getEdgeMesh(targetGraph, startPoint, endPoint);
      if (edgeMesh != null) {
        Log.d(LOG_TAG, "Adding edge from " + startPoint + " to " + endPoint);
        GeoObj edge = targetGraph.addEdge(startPoint, endPoint, edgeMesh);
        edge.getGraphicsComponent().setColor(newNotJetWalkedColor());
      }
    }
  }
  /**
   * Uses google maps to calculate the way from the start pos to the destination pos
   *
   * @param startPos
   * @param destPos
   * @param byWalk
   * @param nodeListener
   * @param edgeListener
   * @return
   */
  public GeoGraph getPathFromAtoB(
      GeoObj startPos,
      GeoObj destPos,
      boolean byWalk,
      NodeListener nodeListener,
      EdgeListener edgeListener) {

    if (startPos == null || destPos == null) {
      Log.d(LOG_TAG, "Gmap getPathFromAtoB error: startPoint or target were null");
      return null;
    }

    // try to open the url:
    try {
      String url = generateUrl(startPos, destPos, byWalk);

      // kml does not work anymore, see a solution in
      // http://stackoverflow.com/questions/11745314/why-retrieving-google-directions-for-android-using-kml-data-is-not-working-anymo/11745316#11745316
      //			Document kml = getDocumentFromUrl(url);

      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document kml = db.parse(url);

      if (kml.getElementsByTagName("GeometryCollection").getLength() > 0) {

        String path =
            kml.getElementsByTagName("GeometryCollection")
                .item(0)
                .getFirstChild()
                .getFirstChild()
                .getFirstChild()
                .getNodeValue();

        final String[] pairs = path.split(" ");
        GeoGraph result = new GeoGraph();
        result
            .getInfoObject()
            .setShortDescr("Resulting graph for " + destPos.getInfoObject().getShortDescr());
        result.setIsPath(true);
        result.setNonDirectional(false);

        if (nodeListener != null) {
          nodeListener.addFirstNodeToGraph(result, startPos);
        } else {
          defaultNEListener.addFirstNodeToGraph(result, startPos);
        }

        GeoObj lastPoint = startPos;
        for (int i = 1; i < pairs.length; i++) {
          String[] geoCords = pairs[i].split(",");

          GeoObj currentPoint =
              new GeoObj(
                  Double.parseDouble(geoCords[1]),
                  Double.parseDouble(geoCords[0]),
                  Double.parseDouble(geoCords[2]));

          if (!currentPoint.hasSameCoordsAs(lastPoint)) {
            if (nodeListener != null) {
              nodeListener.addNodeToGraph(result, currentPoint);
            } else {
              defaultNEListener.addNodeToGraph(result, currentPoint);
            }
            if (edgeListener != null) {
              edgeListener.addEdgeToGraph(result, lastPoint, currentPoint);
            } else {
              defaultNEListener.addEdgeToGraph(result, lastPoint, currentPoint);
            }
            Log.d(LOG_TAG, "     + adding Waypoint:" + pairs[i]);
            lastPoint = currentPoint;
          }
        }
        if (lastPoint != null && !lastPoint.hasSameCoordsAs(destPos)) {

          /*
           * add the egde to the past point:
           */
          if (edgeListener != null) {
            edgeListener.addEdgeToGraph(result, lastPoint, destPos);
          } else {
            defaultNEListener.addEdgeToGraph(result, lastPoint, destPos);
          }
        }

        if (nodeListener != null) {
          nodeListener.addNodeToGraph(result, destPos);
        } else {
          defaultNEListener.addNodeToGraph(result, destPos);
        }

        /*
         * an alternative for adding the edges would be to call
         * result.addEdgesToCreatePath(); but this would be a bit
         * slower..
         */

        return result;
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }