/**
     * Returns the tree path of geo
     *
     * @return returns null if geo is not in tree
     */
    private TreePath getTreePath(GeoElement geo) {
      DefaultMutableTreeNode typeNode = typeNodesMap.get(geo.getObjectType());
      if (typeNode == null) return null;

      // find pos of geo
      int pos = AlgebraView.binarySearchGeo(typeNode, geo.getLabel());
      if (pos == -1) return null;

      return new TreePath(((DefaultMutableTreeNode) typeNode.getChildAt(pos)).getPath());
    }
    /** @param binarySearch true for binary, false for linear search */
    public void remove(GeoElement geo, boolean binarySearch) {
      // get type node
      DefaultMutableTreeNode typeNode = typeNodesMap.get(geo.getObjectType());
      if (typeNode == null) return;

      int pos =
          binarySearch
              ? AlgebraView.binarySearchGeo(typeNode, geo.getLabel())
              : AlgebraView.linearSearchGeo(typeNode, geo.getLabel());
      if (pos > -1) {
        DefaultMutableTreeNode child = (DefaultMutableTreeNode) typeNode.getChildAt(pos);
        treeModel.removeNodeFromParent(child);

        if (typeNode.getChildCount() == 0) {
          // last child
          typeNodesMap.remove(geo.getObjectType());
          treeModel.removeNodeFromParent(typeNode);
        }
      }
    }
    /** adds a new element to the list */
    public final void add(GeoElement geo) {
      if (!geo.isLabelSet() || !geo.hasProperties()) return;

      // get type node
      String typeString = geo.getObjectType();
      DefaultMutableTreeNode typeNode = typeNodesMap.get(typeString);

      // init type node
      boolean initing = typeNode == null;
      if (initing) {
        String transTypeString = geo.translatedTypeString();
        typeNode = new DefaultMutableTreeNode(transTypeString);
        typeNodesMap.put(typeString, typeNode);

        // find insert pos
        int pos = root.getChildCount();
        for (int i = 0; i < pos; i++) {
          DefaultMutableTreeNode child = (DefaultMutableTreeNode) root.getChildAt(i);
          if (transTypeString.compareTo(child.toString()) < 0) {
            pos = i;
            break;
          }
        }

        treeModel.insertNodeInto(typeNode, root, pos);
      }

      // check if already present in type node
      int pos = AlgebraView.binarySearchGeo(typeNode, geo.getLabel());
      if (pos >= 0) return;

      // add geo to type node
      DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(geo);
      pos = AlgebraView.getInsertPosition(typeNode, geo, AlgebraView.SortMode.DEPENDENCY);
      treeModel.insertNodeInto(newNode, typeNode, pos);

      // make sure something is selected
      if (getSelectionModel().isSelectionEmpty()) {
        selectFirstElement();
      }
    }
    public void mouseMoved(MouseEvent e) {
      Point loc = e.getPoint();
      GeoElement geo = AlgebraView.getGeoElementForLocation(this, loc.x, loc.y);
      EuclidianView ev = app.getEuclidianView();

      // tell EuclidianView to handle mouse over
      ev.mouseMovedOver(geo);
      if (geo != null) {
        app.setTooltipFlag();
        setToolTipText(geo.getLongDescriptionHTML(true, true));
        app.clearTooltipFlag();
      } else {
        setToolTipText(null);
      }
    }
    /** returns geo's TreePath */
    private TreePath getGeoPath(GeoElement geo) {
      String typeString = geo.getObjectType();
      DefaultMutableTreeNode typeNode = typeNodesMap.get(typeString);
      if (typeNode == null) return null;

      int pos = AlgebraView.binarySearchGeo(typeNode, geo.getLabel());
      if (pos == -1) return null;
      else {
        // add to selection
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) typeNode.getChildAt(pos);

        //	expand typenode
        TreePath tp = new TreePath(node.getPath());

        return tp;
      }
    }
    /** Handles clicks on the show/hide icon to toggle the show-object status. */
    public void mouseClicked(MouseEvent e) {
      if (Application.isControlDown(e) || e.isShiftDown()) return;

      // get GeoElement at mouse location
      TreePath tp = getPathForLocation(e.getX(), e.getY());
      GeoElement geo = AlgebraView.getGeoElementForPath(tp);

      if (geo != null) {
        // check if we clicked on the 16x16 show/hide icon
        Rectangle rect = getPathBounds(tp);
        boolean iconClicked =
            rect != null && e.getX() - rect.x < 13; // distance from left border			
        if (iconClicked) {
          // icon clicked: toggle show/hide
          geo.setEuclidianVisible(!geo.isSetEuclidianVisible());
          geo.update();
          kernel.notifyRepaint();

          // update properties dialog by selecting this geo again
          geoElementSelected(geo, false);
        }
      }
    }