/*
   * (non-Javadoc)
   *
   * @see org.jvnet.flamingo.common.ui.BasicCommandButtonUI#updateBorder()
   */
  @Override
  protected void updateBorder() {
    Border currBorder = this.commandButton.getBorder();
    if ((currBorder == null) || (currBorder instanceof UIResource)) {
      Insets extra =
          SubstanceSizeUtils.getDefaultBorderInsets(
              SubstanceSizeUtils.getComponentFontSize(this.commandButton));
      double hgapScaleFactor = this.commandButton.getHGapScaleFactor();
      double vgapScaleFactor = this.commandButton.getVGapScaleFactor();

      int top = 1 + (int) (vgapScaleFactor * extra.top);
      int left = 2 + (int) (hgapScaleFactor * (1 + extra.left));
      int bottom = 0 + (int) (vgapScaleFactor * extra.bottom);
      int right = 2 + (int) (hgapScaleFactor * (1 + extra.right));
      this.commandButton.setBorder(
          new BorderUIResource.EmptyBorderUIResource(top, left, bottom, right));
    }
  }
 /*
  * (non-Javadoc)
  *
  * @see
  * org.jvnet.flamingo.common.ui.BasicCommandButtonUI#createPopupActionIcon()
  */
 @Override
 protected ResizableIcon createPopupActionIcon() {
   final int fontSize = SubstanceSizeUtils.getComponentFontSize(this.commandButton);
   int arrowIconHeight = (int) SubstanceSizeUtils.getArrowIconHeight(fontSize);
   int arrowIconWidth = (int) SubstanceSizeUtils.getArrowIconWidth(fontSize);
   ResizableIcon icon =
       new TransitionAwareResizableIcon(
           this.commandButton,
           new TransitionAwareResizableIcon.StateTransitionTrackerDelegate() {
             @Override
             public StateTransitionTracker getStateTransitionTracker() {
               return getPopupTransitionTracker();
             }
           },
           new TransitionAwareResizableIcon.Delegate() {
             @Override
             public Icon getColorSchemeIcon(SubstanceColorScheme scheme, int width, int height) {
               CommandButtonPopupOrientationKind orientation =
                   ((JCommandButton) commandButton).getPopupOrientationKind();
               int direction =
                   (orientation == CommandButtonPopupOrientationKind.DOWNWARD)
                       ? SwingConstants.SOUTH
                       : (commandButton.getComponentOrientation().isLeftToRight()
                           ? SwingConstants.EAST
                           : SwingConstants.WEST);
               // System.out.println(direction + ":" + width + ":"
               // + height);
               Icon result =
                   SubstanceImageCreator.getArrowIcon(
                       width,
                       height,
                       SubstanceSizeUtils.getArrowStrokeWidth(fontSize) - 0.5f,
                       direction,
                       scheme);
               // System.out.println(" --> " + result.getIconWidth()
               // + "*" + result.getIconHeight());
               return result;
             }
           },
           new Dimension(arrowIconWidth, arrowIconHeight));
   return icon;
 }
 /*
  * (non-Javadoc)
  *
  * @see org.jvnet.flamingo.ribbon.ui.BasicRibbonUI#getTabButtonGap()
  */
 @Override
 protected int getTabButtonGap() {
   return SubstanceSizeUtils.getAdjustedSize(
       SubstanceSizeUtils.getComponentFontSize(this.ribbon), super.getTabButtonGap(), 3, 1, false);
 }
  /*
   * (non-Javadoc)
   *
   * @see org.jvnet.flamingo.ribbon.ui.BasicRibbonUI#paintTaskArea(java.awt.
   * Graphics , int, int, int, int)
   */
  @Override
  protected void paintTaskArea(Graphics g, int x, int y, int width, int height) {
    if (this.ribbon.getTaskCount() == 0) return;

    Graphics2D g2d = (Graphics2D) g.create();

    RibbonTask selectedTask = this.ribbon.getSelectedTask();
    JRibbonTaskToggleButton selectedTaskButton = this.taskToggleButtons.get(selectedTask);
    Rectangle selectedTaskButtonBounds = selectedTaskButton.getBounds();
    Point converted =
        SwingUtilities.convertPoint(
            selectedTaskButton.getParent(), selectedTaskButtonBounds.getLocation(), this.ribbon);
    float radius =
        SubstanceSizeUtils.getClassicButtonCornerRadius(
            SubstanceSizeUtils.getComponentFontSize(this.ribbon));

    float borderDelta = SubstanceSizeUtils.getBorderStrokeWidth() / 2.0f;

    SubstanceBorderPainter borderPainter = SubstanceCoreUtilities.getBorderPainter(this.ribbon);
    float borderThickness = SubstanceSizeUtils.getBorderStrokeWidth();

    AbstractRibbonBand band = (selectedTask.getBandCount() == 0) ? null : selectedTask.getBand(0);
    SubstanceColorScheme borderScheme =
        SubstanceColorSchemeUtilities.getColorScheme(
            band, ColorSchemeAssociationKind.BORDER, ComponentState.ENABLED);

    Rectangle taskToggleButtonsViewportBounds =
        taskToggleButtonsScrollablePanel.getView().getParent().getBounds();
    taskToggleButtonsViewportBounds.setLocation(
        SwingUtilities.convertPoint(
            taskToggleButtonsScrollablePanel,
            taskToggleButtonsViewportBounds.getLocation(),
            this.ribbon));
    int startSelectedX = Math.max(converted.x + 1, (int) taskToggleButtonsViewportBounds.getMinX());
    startSelectedX = Math.min(startSelectedX, (int) taskToggleButtonsViewportBounds.getMaxX());
    int endSelectedX =
        Math.min(
            converted.x + selectedTaskButtonBounds.width - 1,
            (int) taskToggleButtonsViewportBounds.getMaxX());
    endSelectedX = Math.max(endSelectedX, (int) taskToggleButtonsViewportBounds.getMinX());

    Shape outerContour =
        RibbonBorderShaper.getRibbonBorderOutline(
            this.ribbon,
            x + borderDelta,
            x + width - borderDelta,
            startSelectedX - borderThickness,
            endSelectedX + borderThickness,
            converted.y + borderDelta,
            y + borderDelta,
            y + height - borderDelta,
            radius);

    Shape innerContour =
        RibbonBorderShaper.getRibbonBorderOutline(
            this.ribbon,
            x + borderDelta + borderThickness,
            x + width - borderThickness - borderDelta,
            startSelectedX - borderThickness,
            endSelectedX + borderThickness,
            converted.y + borderDelta + borderThickness,
            y + borderDelta + borderThickness,
            y + height - borderThickness - borderDelta,
            radius);

    g2d.setColor(
        SubstanceColorSchemeUtilities.getColorScheme(band, ComponentState.ENABLED)
            .getBackgroundFillColor());
    g2d.clipRect(x, y, width, height + 2);
    g2d.fill(outerContour);

    // g2d.setColor(Color.red);
    // g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    // RenderingHints.VALUE_ANTIALIAS_ON);
    // g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
    // RenderingHints.VALUE_STROKE_PURE);
    // g2d.setStroke(new BasicStroke(0.5f));
    // g2d.draw(outerContour);
    // g2d.setColor(Color.blue);
    // g2d.draw(innerContour);
    borderPainter.paintBorder(
        g2d,
        this.ribbon,
        width,
        height + selectedTaskButtonBounds.height + 1,
        outerContour,
        innerContour,
        borderScheme);

    // check whether the currently selected task is a contextual task
    RibbonTask selected = selectedTask;
    RibbonContextualTaskGroup contextualGroup = selected.getContextualGroup();
    if (contextualGroup != null) {
      // paint a small gradient directly below the task area
      Insets ins = this.ribbon.getInsets();
      int topY = ins.top + getTaskbarHeight();
      int bottomY = topY + 5;
      Color hueColor = contextualGroup.getHueColor();
      Paint paint =
          new GradientPaint(
              0,
              topY,
              FlamingoUtilities.getAlphaColor(
                  hueColor, (int) (255 * RibbonContextualTaskGroup.HUE_ALPHA)),
              0,
              bottomY,
              FlamingoUtilities.getAlphaColor(hueColor, 0));
      g2d.setPaint(paint);
      g2d.clip(outerContour);
      g2d.fillRect(0, topY, width, bottomY - topY + 1);
    }

    // paint outlines of the contextual task groups
    // paintContextualTaskGroupsOutlines(g);

    g2d.dispose();
  }