/**
   * Adds a OverlayHandleContainer with four menu handles for the previously calculated touch
   * points.
   *
   * @return true if adding handle touch point markers was successful
   */
  private boolean addOverlayHandles() {

    log.debug("Entering addOverlayHandles()"); // $NON-NLS-1$

    // If all required touch points are valid
    if (this.getTouchPointNorthEast() != null
        && this.getTouchPointSouthEast() != null
        && this.getTouchPointSouthWest() != null
        && this.getTouchPointNorthWest() != null) {

      // Add new marker container with touch points
      this.tpOverlayHandleContainer =
          new OverlayHandleContainer(
              this.mtApplication,
              this,
              this.getWidthXY(TransformSpace.GLOBAL) * OVERLAY_HANDLE_WIDTH_TO_OVERLAY_PERCENT,
              this.getTouchPointNorthEast(),
              this.getTouchPointSouthEast(),
              this.getTouchPointSouthWest(),
              this.getTouchPointNorthWest());

      // Add default drag/rotate listeners to handle container
      // that sends events to this AbstractOverlayDefaultList
      ToolsEventHandling.removeDragProcessorsAndListeners(this.tpOverlayHandleContainer);

      this.tpOverlayHandleContainer.registerInputProcessor(new DragProcessor(this.mtApplication));
      this.tpOverlayHandleContainer.addGestureListener(
          DragProcessor.class,
          new DragActionCheckBorders(this, this.mtApplication, CHECK_BORDER_OFFSET));

      ToolsEventHandling.removeRotateProcessorsAndListeners(this.tpOverlayHandleContainer);

      this.tpOverlayHandleContainer.registerInputProcessor(new RotateProcessor(this.mtApplication));
      this.tpOverlayHandleContainer.addGestureListener(
          RotateProcessor.class,
          new RotateActionCheckBorders(this, this.mtApplication, CHECK_BORDER_OFFSET));

      // Add to this menu
      this.addChild(this.tpOverlayHandleContainer);

      log.debug(
          "Leaving addOverlayHandles(): " //$NON-NLS-1$
              + "Intersection points are: North east: "
              + this.getTouchPointNorthEast() // $NON-NLS-1$
              + ", south east: "
              + this.getTouchPointSouthEast() // $NON-NLS-1$
              + ", south west: " //$NON-NLS-1$
              + this.getTouchPointSouthWest()
              + ", north west: " //$NON-NLS-1$
              + this.getTouchPointNorthWest());

      return true;
    }
    log.error(
        "Leaving addOverlayHandles(): " //$NON-NLS-1$
            + "false, touch points not successfully set!"); //$NON-NLS-1$
    return false;
  }
  /** Adds a close button. */
  private void addCloseButton() {
    log.debug("Entering addCloseButton()"); // $NON-NLS-1$

    // Create close button
    MTSvgButton closeButton = new MTSvgButton(this.mtApplication, BUTTON_CLOSE_IMG_PATH);

    // Remove all default gesture listeners
    ToolsEventHandling.removeScaleProcessorsAndListeners(closeButton);
    ToolsEventHandling.removeDragProcessorsAndListeners(closeButton);
    ToolsEventHandling.removeRotateProcessorsAndListeners(closeButton);

    // Set width
    float parentWidth = this.getWidthXY(TransformSpace.GLOBAL);
    closeButton.setWidthXYGlobal(parentWidth * BUTTON_CLOSE_WIDTH_SCALE_TO_OVERLAY_PERCENT);

    this.addChild(closeButton);

    // Set picking behaviour
    closeButton.setBoundsPickingBehaviour(AbstractShape.BOUNDS_ONLY_CHECK);

    // Add tap gesture listener
    addTapGestureListener(closeButton);

    // Position at touch point north east
    closeButton.setPositionGlobal(this.getTouchPointNorthEast());

    // Reposition
    closeButton.translate(
        new Vector3D(
            -(closeButton.getWidthXYGlobal() * BUTTON_CLOSE_X_OFFSET_FROM_TPNE_PERCENT),
            closeButton.getHeightXYGlobal() * BUTTON_CLOSE_Y_OFFSET_FROM_TPNE_PERCENT,
            0));

    // Set bounding behaviour
    closeButton.setBoundsPickingBehaviour(AbstractShape.BOUNDS_ONLY_CHECK);

    // Add tap gesture listener
    addTapGestureListener(closeButton);

    log.debug("Leaving addCloseButton()"); // $NON-NLS-1$
  }
  /**
   * Adds an emtpy form text field to the AbstractOverlayForm. To be filled by an implementing
   * class.
   */
  private void addFormTextField() {

    log.debug("Entering addFormTextField()"); // $NON-NLS-1$

    // Get the first vertex of the bounding shape
    if (this.hasBounds()) {

      if (this.formDefaultFont != null) {

        Vector3D upperLeftVertex = (this.getBounds().getVectorsGlobal())[0].getCopy();

        // Get OverlayWidht
        float overlayWidth = this.getWidthXY(TransformSpace.GLOBAL);
        float overlayHeight = this.getHeightXY(TransformSpace.GLOBAL);

        // Create new list
        MTTextField formTextField =
            new MTTextField(
                this.mtApplication,
                upperLeftVertex.getX(),
                upperLeftVertex.getY(),
                overlayWidth * FORM_TEXTFIELD_WIDTH_TO_OVERLAY_PERCENT,
                (overlayWidth * FORM_TEXTFIELD_WIDTH_TO_OVERLAY_PERCENT)
                    * FORM_TEXTFIELD_HEIGHT_TO_TFW_PERCENT,
                this.formDefaultFont);

        // Set style info
        formTextField.setStyleInfo(FORM_TEXTFIELD_STYLE_INFO);

        // Set font color
        formTextField.setFontColor(FORM_TEXTFIELD_FONT_COLOR);

        // Remove all default gesture listeners
        ToolsEventHandling.removeScaleProcessorsAndListeners(formTextField);
        ToolsEventHandling.removeDragProcessorsAndListeners(formTextField);
        ToolsEventHandling.removeRotateProcessorsAndListeners(formTextField);

        // Set padding
        formTextField.setInnerPaddingLeft(
            (new Float(
                    formTextField.getWidthXY(TransformSpace.GLOBAL)
                        * FORM_TEXT_FIELD_INNER_PADDING_LEFT_PERCENT))
                .intValue());
        formTextField.setInnerPaddingTop(
            (new Float(
                    formTextField.getWidthXY(TransformSpace.GLOBAL)
                        * FORM_TEXT_FIELD_INNER_PADDING_TOP_PERCENT))
                .intValue());

        // Add to overlay
        this.addChild(formTextField);

        // Reposition to correct position
        formTextField.translate(
            new Vector3D(
                overlayWidth * FORM_TEXT_FIELD_X_OFFSET_PERCENT,
                overlayHeight * FORM_TEXT_FIELD_Y_OFFSET_PERCENT,
                0));

        // Set member
        this.formTextField = formTextField;

      } else {
        log.error(
            "Error! The form default font specified at initialization is invalid! (null)"); //$NON-NLS-1$
      }

    } else {
      log.error("Error! The AbstractOverlayDefaultList has no bounds!"); // $NON-NLS-1$
    }

    log.debug("Entering addFormTextField()"); // $NON-NLS-1$
  }