/*
 * Copyright 2000-2016 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.vcs.log.ui.frame;

import com.intellij.ui.ColorUtil;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import com.intellij.vcs.log.VcsRef;
import com.intellij.vcs.log.VcsRefType;
import com.intellij.vcs.log.ui.render.LabelIcon;
import com.intellij.vcs.log.ui.render.RectanglePainter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import static com.intellij.openapi.vcs.history.VcsHistoryUtil.getCommitDetailsFont;
import static com.intellij.vcs.log.ui.frame.CommitPanel.getCommitDetailsBackground;

public class ReferencesPanel extends JPanel {
  public static final int H_GAP = 4;
  protected static final int V_GAP = 0;
  public static final int PADDING = 3;

  private final int myRefsLimit;
  @NotNull private List<VcsRef> myReferences;
  @NotNull protected MultiMap<VcsRefType, VcsRef> myGroupedVisibleReferences;

  public ReferencesPanel() {
    this(new WrappedFlowLayout(JBUI.scale(H_GAP), JBUI.scale(V_GAP)), -1);
  }

  public ReferencesPanel(LayoutManager layout, int limit) {
    super(layout);
    myRefsLimit = limit;
    myReferences = Collections.emptyList();
    myGroupedVisibleReferences = MultiMap.create();
    setOpaque(false);
  }

  public void setReferences(@NotNull List<VcsRef> references) {
    myReferences = references;

    List<VcsRef> visibleReferences = (myRefsLimit > 0) ? myReferences.subList(0, Math.min(myReferences.size(), myRefsLimit)) : myReferences;
    myGroupedVisibleReferences = ContainerUtil.groupBy(visibleReferences, VcsRef::getType);

    update();
  }

  public void update() {
    removeAll();
    int height = getIconHeight();
    JBLabel firstLabel = null;

    for (Map.Entry<VcsRefType, Collection<VcsRef>> typeAndRefs : myGroupedVisibleReferences.entrySet()) {
      VcsRefType type = typeAndRefs.getKey();
      Collection<VcsRef> refs = typeAndRefs.getValue();
      int refIndex = 0;
      for (VcsRef reference : refs) {
        Icon icon = createIcon(type, refs, refIndex, height);
        String ending = (refIndex != refs.size() - 1) ? "," : "";
        String text = reference.getName() + ending;
        JBLabel label = createLabel(text, icon);
        if (firstLabel == null) {
          firstLabel = label;
          add(label);
        }
        else {
          addWrapped(label, firstLabel);
        }
        refIndex++;
      }
    }
    if (getHiddenReferencesSize() > 0) {
      JBLabel label = createRestLabel(getHiddenReferencesSize());
      addWrapped(label, ObjectUtils.assertNotNull(firstLabel));
    }
    setVisible(!myGroupedVisibleReferences.isEmpty());
    revalidate();
    repaint();
  }

  private int getHiddenReferencesSize() {
    return (myRefsLimit > 0) ? myReferences.size() - Math.min(myReferences.size(), myRefsLimit) : 0;
  }

  protected int getIconHeight() {
    return getFontMetrics(getLabelsFont()).getHeight() + JBUI.scale(PADDING);
  }

  @NotNull
  protected JBLabel createRestLabel(int restSize) {
    return createLabel("... " + restSize + " more", null);
  }

  @Nullable
  protected Icon createIcon(@NotNull VcsRefType type,
                            @NotNull Collection<VcsRef> refs,
                            int refIndex, int height) {
    if (refIndex == 0) {
      Color color = type.getBackgroundColor();
      return new LabelIcon(height, getBackground(),
                           refs.size() > 1 ? new Color[]{color, color} : new Color[]{color});
    }
    return null;
  }

  private void addWrapped(@NotNull JBLabel label, @NotNull JBLabel referent) {
    Wrapper wrapper = new Wrapper(label);
    wrapper.setVerticalSizeReferent(referent);
    add(wrapper);
  }

  @NotNull
  protected JBLabel createLabel(@NotNull String text, @Nullable Icon icon) {
    JBLabel label = new JBLabel(text, icon, SwingConstants.LEFT);
    label.setFont(getLabelsFont());
    label.setIconTextGap(0);
    label.setHorizontalAlignment(SwingConstants.LEFT);
    return label;
  }

  @NotNull
  protected Font getLabelsFont() {
    return getCommitDetailsFont();
  }

  @Override
  public Dimension getMaximumSize() {
    return new Dimension(super.getMaximumSize().width, super.getPreferredSize().height);
  }

  @Override
  public Color getBackground() {
    return getCommitDetailsBackground();
  }

  @NotNull
  public static Color getLabelColor(@NotNull Color color) {
    if (UIUtil.isUnderDarcula()) {
      color = ColorUtil.darker(color, 6);
    }
    else {
      color = ColorUtil.brighter(color, 6);
    }
    return ColorUtil.desaturate(color, 3);
  }

  private static class ReferencePanel extends JPanel {
    @NotNull private final RectanglePainter myLabelPainter;
    @NotNull private final VcsRef myReference;

    private ReferencePanel(@NotNull VcsRef reference) {
      myReference = reference;
      myLabelPainter = new RectanglePainter(false);
      setOpaque(false);
    }

    @Override
    public void paint(Graphics g) {
      myLabelPainter.paint((Graphics2D)g, myReference.getName(), 0, 0,
                           getLabelColor(myReference.getType().getBackgroundColor()));
    }

    @Override
    public Dimension getPreferredSize() {
      Dimension dimension = myLabelPainter.calculateSize(myReference.getName(), getFontMetrics(RectanglePainter.getFont()));
      return new Dimension(dimension.width, dimension.height + JBUI.scale(PADDING));
    }

    @Override
    public Color getBackground() {
      return getCommitDetailsBackground();
    }
  }
}

@@ -638,42 +638,8 @@
 e;%0A%0A
-import com.intellij.ui.ColorUtil;%0A
 impo
@@ -900,44 +900,8 @@
 UI;%0A
-import com.intellij.util.ui.UIUtil;%0A
 impo
@@ -1025,64 +1025,8 @@
 on;%0A
-import com.intellij.vcs.log.ui.render.RectanglePainter;%0A
 impo
@@ -5134,1194 +5134,7 @@
 %0A  %7D
-%0A%0A  @NotNull%0A  public static Color getLabelColor(@NotNull Color color) %7B%0A    if (UIUtil.isUnderDarcula()) %7B%0A      color = ColorUtil.darker(color, 6);%0A    %7D%0A    else %7B%0A      color = ColorUtil.brighter(color, 6);%0A    %7D%0A    return ColorUtil.desaturate(color, 3);%0A  %7D%0A%0A  private static class ReferencePanel extends JPanel %7B%0A    @NotNull private final RectanglePainter myLabelPainter;%0A    @NotNull private final VcsRef myReference;%0A%0A    private ReferencePanel(@NotNull VcsRef reference) %7B%0A      myReference = reference;%0A      myLabelPainter = new RectanglePainter(false);%0A      setOpaque(false);%0A    %7D%0A%0A    @Override%0A    public void paint(Graphics g) %7B%0A      myLabelPainter.paint((Graphics2D)g, myReference.getName(), 0, 0,%0A                           getLabelColor(myReference.getType().getBackgroundColor()));%0A    %7D%0A%0A    @Override%0A    public Dimension getPreferredSize() %7B%0A      Dimension dimension = myLabelPainter.calculateSize(myReference.getName(), getFontMetrics(RectanglePainter.getFont()));%0A      return new Dimension(dimension.width, dimension.height + JBUI.scale(PADDING));%0A    %7D%0A%0A    @Override%0A    public Color getBackground() %7B%0A      return getCommitDetailsBackground();%0A    %7D%0A  %7D
 %0A%7D%0A

remove unused subclass and method