/** Adds <code>CoordinateZeroMarkerView</code>s to <code>RoomMap</code>. */
  public void addCoordinateZeroMarkerViewsToMap() {

    if (lowerLeftMarker == null || upperRightMarker == null) {
      lowerLeftMarker = new CoordinateZeroMarkerView(CoordinateZeroMarkerViewType.LOWER_LEFT, this);
      upperRightMarker =
          new CoordinateZeroMarkerView(CoordinateZeroMarkerViewType.UPPER_RIGHT, this);

      if (map.getLowerLeftMarkerOffsetXInPixels() != 0
          || map.getLowerLeftMarkerOffsetYInPixels() != 0) {
        lowerLeftMarker.setLocation(
            (int) (map.getLowerLeftMarkerOffsetXInPixels() * scalingRatioToFitContainer),
            ((int) (map.getLowerLeftMarkerOffsetYInPixels() * scalingRatioToFitContainer)
                - (int)
                    (CoordinateZeroMarkerView.ZERO_COORDINATE_MARKER_VIEW_HEIGHT
                        * scalingRatioToFitContainer)));
      }

      if (map.getUpperRightMarkerOffsetXInPixels() != 0
          || map.getUpperRightMarkerOffsetYInPixels() != 0) {
        upperRightMarker.setLocation(
            ((int) (map.getUpperRightMarkerOffsetXInPixels() * scalingRatioToFitContainer)
                - (int)
                    (CoordinateZeroMarkerView.ZERO_COORDINATE_MARKER_VIEW_WIDTH
                        * scalingRatioToFitContainer)),
            (int) (map.getUpperRightMarkerOffsetYInPixels() * scalingRatioToFitContainer));
      }

      add(lowerLeftMarker);
      add(upperRightMarker);
      lowerLeftMarker.repaint();
      upperRightMarker.repaint();
      revalidate();
      componentMover.registerComponent(lowerLeftMarker);
      componentMover.registerComponent(upperRightMarker);
    } else {
      // don't add another pair of zero coordinate map marker views, just set position to zero and
      // repaint the old
      // ones
      lowerLeftMarker.setLocation(0, 0);
      lowerLeftMarker.repaint();
      upperRightMarker.setLocation(0, 0);
      upperRightMarker.repaint();
      revalidate();
    }
  }
  /**
   * Creates a <code>ReceiverView</code> object from <code>Receiver</code> object and adds it to the
   * <code>MapPreviewPanel</code>.
   *
   * @param receiver <code>Receiver</code> object
   */
  public void addReceiverViewToMap(Receiver receiver) {

    ReceiverView receiverView = new ReceiverView(receiver, this);
    receiverViews.add(receiverView);
    this.add(receiverView);
    receiverView.setLocation((int) receiver.getXPos(), (int) receiver.getYPos());
    componentMover.registerComponent(receiverView);
    repaint();
  }
  /**
   * Initializes graphical user interface. Layout of this panel is set to <code>null</code> (no
   * <code>LayoutManager</code>) so that <code>ReceiverView</code> items can be positioned
   * absolutely.
   *
   * @see ReceiverView
   * @see LayoutManager
   */
  private void initializeGui() {

    logger = Utilities.initializeLogger(this.getClass().getName());
    setSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
    setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
    setBackground(new Color(GRAY_COLOUR, GRAY_COLOUR, GRAY_COLOUR));
    setLayout(null); // in order to position ReceiverViews absolutely
    refreshPreviewImage();
    // register all receiver views to the ComponentMover
    componentMover = new ComponentMover();
    // add zero coordinate marker views
    addCoordinateZeroMarkerViewsToMap();

    for (Receiver receiver : map.getReceivers()) {

      ReceiverView receiverView = new ReceiverView(receiver, this);
      receiverViews.add(receiverView);
      this.add(receiverView);
      // TODO: location should be calculated with offsets for scaling
      // the image and pixel/meter scaling

      double receiverPositionInMetersX = receiver.getXPos();
      double receiverPositionInMetersY = receiver.getYPos();
      double mapRatioWidth = map.getRatioWidth();
      double mapRatioHeight = map.getRatioHeight();
      int lowerLeftMarkerOffsetXInPixels = map.getLowerLeftMarkerOffsetXInPixels();
      int lowerLeftMarkerOffsetYInPixels = map.getLowerLeftMarkerOffsetYInPixels();

      int receiverPositionInPixelsX =
          calculateReceiverPositionInPixelsX(
              receiverPositionInMetersX, lowerLeftMarkerOffsetXInPixels, mapRatioWidth);
      int receiverPositionInPixelsY =
          calculateReceiverPositionInPixelsY(
              receiverPositionInMetersY, lowerLeftMarkerOffsetYInPixels, mapRatioHeight);

      receiverView.setLocation(receiverPositionInPixelsX, receiverPositionInPixelsY);
      componentMover.registerComponent(receiverView);
    }
  }
  /**
   * Removes the <code>ReceiverView</code> object from <code>RoomMap</code>.
   *
   * @param receiver <code>Receiver</code> object
   */
  public void removeReceiverViewFromMap(Receiver receiver) {

    for (ReceiverView receiverView : receiverViews) {
      if (receiverView.getReceiver().getID() == receiver.getID()) {

        // remove receiver from map and receiverViews list
        this.remove(receiverView);
        receiverViews.remove(receiverView);
        componentMover.deregisterComponent(receiverView);
        repaint();

        // set receivers coordinates to 0,0
        for (Receiver receiverItem : map.getReceivers()) {
          if (receiverItem.getID() == receiver.getID()) {
            receiverItem.setOnMap(false);
            receiverItem.setxPos(0.0);
            receiverItem.setyPos(0.0);
          }
        }
        return;
      }
    }
  }