/*
 * Copyright 2000-2014 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.codeInspection.actions;

import com.intellij.codeInspection.ex.InspectionToolWrapper;
import com.intellij.ide.util.gotoByName.ChooseByNameBase;
import com.intellij.lang.Language;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.fileTypes.UnknownFileType;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.MinusculeMatcher;
import com.intellij.ui.JBColor;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.ui.speedSearch.SpeedSearchUtil;
import com.intellij.util.text.Matcher;
import com.intellij.util.text.MatcherHolder;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;

/**
* @author Konstantin Bulenkov
*/
@SuppressWarnings({"GtkPreferredJComboBoxRenderer"})
public class InspectionListCellRenderer extends DefaultListCellRenderer implements MatcherHolder {
  private Matcher myMatcher;
  private final SimpleTextAttributes mySelected;
  private final SimpleTextAttributes myPlain;
  private final SimpleTextAttributes myHighlighted;

  public InspectionListCellRenderer() {
    mySelected = new SimpleTextAttributes(UIUtil.getListSelectionBackground(),
                                          UIUtil.getListSelectionForeground(),
                                          JBColor.RED,
                                          SimpleTextAttributes.STYLE_PLAIN);
    myPlain = new SimpleTextAttributes(UIUtil.getListBackground(),
                                       UIUtil.getListForeground(),
                                       JBColor.RED,
                                       SimpleTextAttributes.STYLE_PLAIN);
    myHighlighted = new SimpleTextAttributes(UIUtil.getListBackground(),
                                             UIUtil.getListForeground(),
                                             null,
                                             SimpleTextAttributes.STYLE_SEARCH_MATCH);
  }


  @Override
  public Component getListCellRendererComponent(JList list, Object value, int index, boolean sel, boolean focus) {
    final BorderLayout layout = new BorderLayout();
    layout.setHgap(5);
    final JPanel panel = new JPanel(layout);
    panel.setOpaque(true);

    final Color bg = sel ? UIUtil.getListSelectionBackground() : UIUtil.getListBackground();
    final Color fg = sel ? UIUtil.getListSelectionForeground() : UIUtil.getListForeground();
    panel.setBackground(bg);
    panel.setForeground(fg);

    if (value instanceof InspectionToolWrapper) {
      final InspectionToolWrapper toolWrapper = (InspectionToolWrapper)value;
      final String inspectionName = "  " + toolWrapper.getDisplayName();
      final String groupName = StringUtil.join(toolWrapper.getGroupPath(), " | ");
      final String matchingText = inspectionName + "|" + groupName;
      List<TextRange> fragments = ((MinusculeMatcher)myMatcher).matchingFragments(matchingText);
      List<TextRange> adjustedFragments = new ArrayList<TextRange>();
      if (fragments != null) {
        adjustedFragments.addAll(fragments);
      }
      final int splitPoint = adjustRanges(adjustedFragments, inspectionName.length() + 1);
      final SimpleColoredComponent c = new SimpleColoredComponent();
      final boolean matchHighlighting = Registry.is("ide.highlight.match.in.selected.only") && !sel;
      if (matchHighlighting) {
        c.append(inspectionName, myPlain);
      }
      else {
        final List<TextRange> ranges = adjustedFragments.subList(0, splitPoint);
        SpeedSearchUtil.appendColoredFragments(c, inspectionName, ranges, sel ? mySelected : myPlain, myHighlighted);
      }
      panel.add(c, BorderLayout.WEST);

      final SimpleColoredComponent group = new SimpleColoredComponent();
      if (matchHighlighting) {
        group.append(groupName, SimpleTextAttributes.GRAYED_ATTRIBUTES);
      }
      else {
        final SimpleTextAttributes attributes = sel ? mySelected : SimpleTextAttributes.GRAYED_ATTRIBUTES;
        final List<TextRange> ranges = adjustedFragments.subList(splitPoint, adjustedFragments.size());
        SpeedSearchUtil.appendColoredFragments(group, groupName, ranges, attributes, myHighlighted);
      }
      final JPanel right = new JPanel(new BorderLayout());
      right.setBackground(bg);
      right.setForeground(fg);
      right.add(group, BorderLayout.CENTER);
      final JLabel icon = new JLabel(getIcon(toolWrapper));
      icon.setBackground(bg);
      icon.setForeground(fg);
      right.add(icon, BorderLayout.EAST);
      panel.add(right, BorderLayout.EAST);
    }
    else {
      // E.g. "..." item
      return value == ChooseByNameBase.NON_PREFIX_SEPARATOR ? ChooseByNameBase.renderNonPrefixSeparatorComponent(UIUtil.getListBackground()) :
             super.getListCellRendererComponent(list, value, index, sel, focus);
    }

    return panel;
  }

  private static int adjustRanges(List<TextRange> ranges, int offset) {
    int result = 0;
    for (int i = 0; i < ranges.size(); i++) {
      final TextRange range = ranges.get(i);
      final int startOffset = range.getStartOffset();
      if (startOffset < offset) {
        result = i + 1;
      }
      else {
        ranges.set(i, new TextRange(startOffset - offset, range.getEndOffset() - offset));
      }
    }
    return result;
  }

  @NotNull
  private static Icon getIcon(@NotNull InspectionToolWrapper tool) {
    Icon icon = null;
    final Language language = Language.findLanguageByID(tool.getLanguage());
    if (language != null) {
      final LanguageFileType fileType = language.getAssociatedFileType();
      if (fileType != null) {
        icon = fileType.getIcon();
      }
    }
    if (icon == null) {
      icon = UnknownFileType.INSTANCE.getIcon();
    }
    assert icon != null;
    return icon;
  }

  @Override
  public void setPatternMatcher(Matcher matcher) {
    myMatcher = matcher;
  }
}
