/*
   * (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();
    }
  }
  /**
   * Computes the alpha value for painting the separators.
   *
   * @return Alpha value for painting the separators.
   */
  private float getSeparatorAlpha() {
    ComponentState actionAreaState =
        this.getActionTransitionTracker().getModelStateInfo().getCurrModelState();

    if (!actionAreaState.isFacetActive(ComponentStateFacet.SELECTION)
        && !actionAreaState.isDisabled()) {
      float actionRolloverCycle =
          this.getActionTransitionTracker().getFacetStrength(ComponentStateFacet.ROLLOVER);
      float popupRolloverCycle =
          this.getPopupTransitionTracker().getFacetStrength(ComponentStateFacet.ROLLOVER);
      return Math.min(1.0f, actionRolloverCycle + popupRolloverCycle);
    }
    return 1.0f;
  }
  /*
   * (non-Javadoc)
   *
   * @see
   * org.jvnet.flamingo.common.ui.BasicCommandButtonUI#paint(java.awt.Graphics
   * , javax.swing.JComponent)
   */
  @Override
  public void paint(Graphics g, JComponent c) {
    Graphics2D g2d = (Graphics2D) g.create();
    g2d.setFont(
        FlamingoUtilities.getFont(this.commandButton, "Ribbon.font", "Button.font", "Panel.font"));

    this.layoutInfo = this.layoutManager.getLayoutInfo(this.commandButton, g);
    commandButton.putClientProperty("icon.bounds", layoutInfo.iconRect);
    commandButton.putClientProperty("icon", commandButton.getIcon());

    if (this.isPaintingBackground()) {
      this.paintButtonBackground(g2d, new Rectangle(0, 0, c.getWidth(), c.getHeight()));
    }

    // decide which command button model should be used to
    // compute the foreground color of the command button's text
    boolean useActionAreaForFg = layoutInfo.isTextInActionArea;
    StateTransitionTracker transitionTrackerForFg =
        useActionAreaForFg ? this.getActionTransitionTracker() : this.getPopupTransitionTracker();
    ModelStateInfo modelStateInfoForFg = transitionTrackerForFg.getModelStateInfo();
    ComponentState currStateForFg = modelStateInfoForFg.getCurrModelState();
    Color fgColor = this.commandButton.getForeground();

    if (fgColor instanceof UIResource) {
      float buttonAlpha =
          SubstanceColorSchemeUtilities.getAlpha(this.commandButton, currStateForFg);
      fgColor =
          SubstanceTextUtilities.getForegroundColor(
              this.commandButton, this.commandButton.getText(), modelStateInfoForFg, buttonAlpha);
    }

    if (layoutInfo.textLayoutInfoList != null) {
      for (CommandButtonLayoutManager.TextLayoutInfo mainTextLayoutInfo :
          layoutInfo.textLayoutInfoList) {
        if (mainTextLayoutInfo.text != null) {
          SubstanceTextUtilities.paintText(
              g2d,
              c,
              mainTextLayoutInfo.textRect,
              mainTextLayoutInfo.text,
              -1,
              g2d.getFont(),
              fgColor,
              g2d.getClipBounds());
        }
      }
    }

    if (layoutInfo.extraTextLayoutInfoList != null) {
      Color disabledFgColor =
          SubstanceColorSchemeUtilities.getColorScheme(
                  this.commandButton, ComponentState.DISABLED_UNSELECTED)
              .getForegroundColor();
      float buttonAlpha =
          SubstanceColorSchemeUtilities.getAlpha(
              this.commandButton, ComponentState.DISABLED_UNSELECTED);
      if (buttonAlpha < 1.0f) {
        Color bgFillColor = SubstanceColorUtilities.getBackgroundFillColor(this.commandButton);
        disabledFgColor =
            SubstanceColorUtilities.getInterpolatedColor(disabledFgColor, bgFillColor, buttonAlpha);
      }
      if (currStateForFg.isDisabled()) {
        disabledFgColor =
            SubstanceColorUtilities.getInterpolatedColor(
                disabledFgColor, SubstanceColorUtilities.getBackgroundFillColor(c), 0.5);
      }
      for (CommandButtonLayoutManager.TextLayoutInfo extraTextLayoutInfo :
          layoutInfo.extraTextLayoutInfoList) {
        if (extraTextLayoutInfo.text != null) {
          SubstanceTextUtilities.paintText(
              g2d,
              c,
              extraTextLayoutInfo.textRect,
              extraTextLayoutInfo.text,
              -1,
              g2d.getFont(),
              disabledFgColor,
              g2d.getClipBounds());
        }
      }
    }

    if (layoutInfo.iconRect != null) {
      this.paintButtonIcon(g2d, layoutInfo.iconRect);
    }
    if (layoutInfo.popupActionRect.getWidth() > 0) {
      paintPopupActionIcon(g2d, layoutInfo.popupActionRect);
    }

    if (this.isPaintingSeparators() && (layoutInfo.separatorArea != null)) {
      if (layoutInfo.separatorOrientation == CommandButtonSeparatorOrientation.HORIZONTAL) {
        this.paintButtonHorizontalSeparator(g2d, layoutInfo.separatorArea);
      } else {
        this.paintButtonVerticalSeparator(g2d, layoutInfo.separatorArea);
      }
    }

    // g2d.setColor(Color.red);
    // g2d.draw(layoutInfo.iconRect);
    // g2d.setColor(Color.blue);
    // if (layoutInfo.textLayoutInfoList != null) {
    // for (CommandButtonLayoutManager.TextLayoutInfo mainTextLayoutInfo :
    // layoutInfo.textLayoutInfoList) {
    // if (mainTextLayoutInfo.text != null) {
    // g2d.draw(mainTextLayoutInfo.textRect);
    // }
    // }
    // }
    // g2d.setColor(Color.magenta);
    // if (layoutInfo.extraTextLayoutInfoList != null) {
    // for (CommandButtonLayoutManager.TextLayoutInfo extraTextLayoutInfo :
    // layoutInfo.extraTextLayoutInfoList) {
    // if (extraTextLayoutInfo.text != null) {
    // g2d.draw(extraTextLayoutInfo.textRect);
    // }
    // }
    // }
    // g2d.setColor(Color.green);
    // g2d.draw(layoutInfo.popupActionRect);

    g2d.dispose();
  }
  public Component getTableCellRendererComponentWithSubstance(
      JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

    TableUI tableUI = table.getUI();
    SubstanceTableUI ui = (SubstanceTableUI) tableUI;

    // Recompute the focus indication to prevent flicker - JTable
    // registers a listener on selection changes and repaints the
    // relevant cell before our listener (in TableUI) gets the
    // chance to start the fade sequence. The result is that the
    // first frame uses full opacity, and the next frame starts the
    // fade sequence. So, we use the UI delegate to compute the
    // focus indication.
    hasFocus = ui.isFocusedCell(row, column);

    TableCellId cellId = new TableCellId(row, column);

    StateTransitionTracker.ModelStateInfo modelStateInfo = ui.getModelStateInfo(cellId);
    ComponentState currState = ui.getCellState(cellId);
    // special case for drop location
    JTable.DropLocation dropLocation = table.getDropLocation();
    boolean isDropLocation =
        (dropLocation != null
            && !dropLocation.isInsertRow()
            && !dropLocation.isInsertColumn()
            && dropLocation.getRow() == row
            && dropLocation.getColumn() == column);

    if (!isDropLocation && (modelStateInfo != null)) {
      if (ui.hasRolloverAnimations() || ui.hasSelectionAnimations()) {
        Map<ComponentState, StateContributionInfo> activeStates =
            modelStateInfo.getStateContributionMap();
        SubstanceColorScheme colorScheme = getColorSchemeForState(table, ui, currState);
        if (currState.isDisabled() || (activeStates == null) || (activeStates.size() == 1)) {
          super.setForeground(new ColorUIResource(colorScheme.getForegroundColor()));
        } else {
          float aggrRed = 0;
          float aggrGreen = 0;
          float aggrBlue = 0;
          for (Map.Entry<ComponentState, StateTransitionTracker.StateContributionInfo> activeEntry :
              modelStateInfo.getStateContributionMap().entrySet()) {
            ComponentState activeState = activeEntry.getKey();
            SubstanceColorScheme scheme = getColorSchemeForState(table, ui, activeState);
            Color schemeFg = scheme.getForegroundColor();
            float contribution = activeEntry.getValue().getContribution();
            aggrRed += schemeFg.getRed() * contribution;
            aggrGreen += schemeFg.getGreen() * contribution;
            aggrBlue += schemeFg.getBlue() * contribution;
          }
          super.setForeground(
              new ColorUIResource(new Color((int) aggrRed, (int) aggrGreen, (int) aggrBlue)));
        }
      } else {
        SubstanceColorScheme scheme = getColorSchemeForState(table, ui, currState);
        super.setForeground(new ColorUIResource(scheme.getForegroundColor()));
      }
    } else {
      SubstanceColorScheme scheme = getColorSchemeForState(table, ui, currState);
      if (isDropLocation) {
        scheme =
            SubstanceColorSchemeUtilities.getColorScheme(
                table, ColorSchemeAssociationKind.TEXT_HIGHLIGHT, currState);
      }
      super.setForeground(new ColorUIResource(scheme.getForegroundColor()));
    }

    SubstanceStripingUtils.applyStripedBackground(table, row, this);

    this.setFont(table.getFont());

    TableCellId cellFocusId = new TableCellId(row, column);

    StateTransitionTracker focusStateTransitionTracker = ui.getStateTransitionTracker(cellFocusId);

    Insets regInsets = ui.getCellRendererInsets();
    if (hasFocus || (focusStateTransitionTracker != null)) {
      SubstanceTableCellBorder border = new SubstanceTableCellBorder(regInsets, ui, cellFocusId);

      // System.out.println("[" + row + ":" + column + "] hasFocus : "
      // + hasFocus + ", focusState : " + focusState);
      if (focusStateTransitionTracker != null) {
        border.setAlpha(focusStateTransitionTracker.getFocusStrength(hasFocus));
      }

      // special case for tables with no grids
      if (!table.getShowHorizontalLines() && !table.getShowVerticalLines()) {
        this.setBorder(
            new CompoundBorder(
                new EmptyBorder(table.getRowMargin() / 2, 0, table.getRowMargin() / 2, 0), border));
      } else {
        this.setBorder(border);
      }
    } else {
      this.setBorder(
          new EmptyBorder(regInsets.top, regInsets.left, regInsets.bottom, regInsets.right));
    }

    setValue(Math.min(100, getBarStatus(value)));
    setString(getDescription(value));
    this.setOpaque(false);
    this.setEnabled(table.isEnabled());
    return this;
  }