/*
   * (non-Javadoc)
   *
   * @see
   * org.jvnet.flamingo.common.ui.BasicCommandButtonUI#getPreferredSize(javax
   * .swing.JComponent)
   */
  @Override
  public Dimension getPreferredSize(JComponent c) {
    AbstractCommandButton button = (AbstractCommandButton) c;
    SubstanceButtonShaper shaper = SubstanceCoreUtilities.getButtonShaper(button);

    Dimension superPref = super.getPreferredSize(button);
    if (superPref == null) return null;

    if (shaper == null) return superPref;

    // fix for issue 35 on Flamingo - do not enforce
    // min size on buttons in the ribbon
    // Additional fix - buttons with popup action should
    // not have min size enforced as well
    // Additional fix - buttons in popup menus and breadcrumb bars should
    // not have min size enforced
    if ((button.getDisplayState() == CommandButtonDisplayState.MEDIUM)
        && (SwingUtilities.getAncestorOfClass(AbstractRibbonBand.class, button) == null)
        && (SwingUtilities.getAncestorOfClass(JBreadcrumbBar.class, button) == null)
        && (SwingUtilities.getAncestorOfClass(JCommandPopupMenu.class, button) == null)) {
      JButton dummy = new JButton(button.getText(), button.getIcon());
      Dimension result = shaper.getPreferredSize(dummy, superPref);
      if (FlamingoUtilities.hasPopupAction(button)) {
        result.width = superPref.width;
      }
      return result;
    }
    return superPref;
  }
  /*
   * (non-Javadoc)
   *
   * @see
   * org.jvnet.flamingo.common.ui.BasicCommandButtonUI#paintButtonBackground
   * (java.awt.Graphics, java.awt.Rectangle)
   */
  @Override
  protected void paintButtonBackground(Graphics graphics, Rectangle toFill) {
    if (SubstanceCoreUtilities.isButtonNeverPainted(this.commandButton)) return;

    ButtonModel actionModel = this.commandButton.getActionModel();
    PopupButtonModel popupModel = ((JCommandButton) this.commandButton).getPopupModel();
    Rectangle actionArea = this.getLayoutInfo().actionClickArea;
    Rectangle popupArea = this.getLayoutInfo().popupClickArea;

    BufferedImage fullAlphaBackground =
        CommandButtonBackgroundDelegate.getCombinedCommandButtonBackground(
            this.commandButton, actionModel, actionArea, popupModel, popupArea);

    // Two special cases here:
    // 1. Button has flat appearance and doesn't show the popup
    // 2. Button is disabled.
    // For both cases, we need to set custom translucency.
    boolean isFlat =
        this.commandButton.isFlat()
            && !((JCommandButton) this.commandButton).getPopupModel().isPopupShowing();
    boolean isSpecial = isFlat || !this.commandButton.isEnabled();
    float extraAlpha = 1.0f;
    if (isSpecial) {
      if (isFlat) {
        float extraActionAlpha = 0.0f;
        for (Map.Entry<ComponentState, StateTransitionTracker.StateContributionInfo> activeEntry :
            getActionTransitionTracker().getModelStateInfo().getStateContributionMap().entrySet()) {
          ComponentState activeState = activeEntry.getKey();
          if (activeState.isDisabled()) continue;
          if (activeState == ComponentState.ENABLED) continue;
          extraActionAlpha += activeEntry.getValue().getContribution();
        }
        float extraPopupAlpha = 0.0f;
        for (Map.Entry<ComponentState, StateTransitionTracker.StateContributionInfo> activeEntry :
            getPopupTransitionTracker().getModelStateInfo().getStateContributionMap().entrySet()) {
          ComponentState activeState = activeEntry.getKey();
          if (activeState.isDisabled()) continue;
          if (activeState == ComponentState.ENABLED) continue;
          extraPopupAlpha += activeEntry.getValue().getContribution();
        }
        extraAlpha = Math.max(extraActionAlpha, extraPopupAlpha);
      } else {
        ComponentState actionAreaState = ComponentState.getState(actionModel, this.commandButton);
        if (actionAreaState.isDisabled()) {
          extraAlpha = SubstanceColorSchemeUtilities.getAlpha(this.commandButton, actionAreaState);
        }
      }
    }
    // System.out.println(extraAlpha);
    extraAlpha = Math.min(1.0f, extraAlpha);
    if (extraAlpha > 0.0f) {
      Graphics2D g2d = (Graphics2D) graphics.create();
      g2d.setComposite(
          LafWidgetUtilities.getAlphaComposite(this.commandButton, extraAlpha, graphics));
      g2d.drawImage(fullAlphaBackground, 0, 0, null);
      g2d.dispose();
    }
  }
  /*
   * (non-Javadoc)
   *
   * @see
   * org.jvnet.flamingo.common.ui.BasicCommandButtonUI#paintButtonIcon(java
   * .awt.Graphics, java.awt.Rectangle)
   */
  @Override
  protected void paintButtonIcon(Graphics g, Rectangle iconRect) {
    JCommandButton jcb = (JCommandButton) this.commandButton;
    Icon regular = jcb.getIcon();
    if (toUseDisabledIcon()
        && (jcb.getDisabledIcon() != null)
        && ((regular != null) && !regular.getClass().isAnnotationPresent(TransitionAware.class)))
      regular = jcb.getDisabledIcon();

    if ((iconRect == null)
        || (regular == null)
        || (iconRect.width == 0)
        || (iconRect.height == 0)) {
      return;
    }

    boolean useThemed = SubstanceCoreUtilities.useThemedDefaultIcon(this.commandButton);
    if (regular != null) {
      Graphics2D g2d = (Graphics2D) g.create();

      GhostPaintingUtils.paintGhostIcon(g2d, jcb, regular, iconRect);
      g2d.setComposite(LafWidgetUtilities.getAlphaComposite(jcb, g));

      if (!useThemed) {
        regular.paintIcon(jcb, g2d, iconRect.x, iconRect.y);
      } else {
        StateTransitionTracker tracker =
            this.substanceVisualStateTracker.getActionStateTransitionTracker();
        ButtonModel model = commandButton.getActionModel();
        if (jcb.getCommandButtonKind() == CommandButtonKind.POPUP_ONLY) {
          tracker = this.substanceVisualStateTracker.getPopupStateTransitionTracker();
          model = jcb.getPopupModel();
        }
        CommandButtonBackgroundDelegate.paintThemedCommandButtonIcon(
            g2d, iconRect, jcb, regular, model, tracker);
      }
      g2d.dispose();
    }
  }
 /*
  * (non-Javadoc)
  *
  * @see javax.swing.plaf.ComponentUI#createUI(javax.swing.JComponent)
  */
 public static ComponentUI createUI(JComponent comp) {
   SubstanceCoreUtilities.testComponentCreationThreadingViolation(comp);
   return new SubstanceCommandButtonUI((JCommandButton) comp);
 }