/*
 * Copyright 2000-2013 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.openapi.vcs.configurable;

import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.impl.DefaultVcsRootPolicy;
import com.intellij.openapi.vcs.impl.VcsDescriptor;
import com.intellij.openapi.vcs.roots.VcsRootErrorsFinder;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.*;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.labels.LinkListener;
import com.intellij.ui.table.TableView;
import com.intellij.util.UriUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.*;
import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.border.CompoundBorder;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import java.util.*;
import java.util.List;

import static com.intellij.openapi.vcs.VcsConfiguration.getInstance;
import static com.intellij.openapi.vcs.VcsConfiguration.ourMaximumFileForBaseRevisionSize;
import static com.intellij.util.ui.UIUtil.DEFAULT_HGAP;
import static com.intellij.util.ui.UIUtil.DEFAULT_VGAP;

/**
 * @author yole
 */
public class VcsDirectoryConfigurationPanel extends JPanel implements Configurable {
  private final Project myProject;
  private final String myProjectMessage;
  private final ProjectLevelVcsManager myVcsManager;
  private final TableView<VcsDirectoryMapping> myDirectoryMappingTable;
  private final ComboboxWithBrowseButton myVcsComboBox = new ComboboxWithBrowseButton();
  private final List<ModuleVcsListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();

  private final MyDirectoryRenderer myDirectoryRenderer;
  private final ColumnInfo<VcsDirectoryMapping, VcsDirectoryMapping> DIRECTORY;
  private final JCheckBox myBaseRevisionTexts;
  private ListTableModel<VcsDirectoryMapping> myModel;
  private final Map<String, VcsDescriptor> myAllVcss;
  private VcsContentAnnotationConfigurable myRecentlyChangedConfigurable;
  private final boolean myIsDisabled;
  private final VcsConfiguration myVcsConfiguration;
  private final @NotNull Map<String, VcsRootChecker> myCheckers;
  private JCheckBox myShowVcsRootErrorNotification;
  private JCheckBox myShowChangedRecursively;
  private final VcsLimitHistoryConfigurable myLimitHistory;
  private final VcsUpdateInfoScopeFilterConfigurable myScopeFilterConfig;
  private VcsCommitMessageMarginConfigurable myCommitMessageMarginConfigurable;

  private class MyDirectoryRenderer extends ColoredTableCellRenderer {
    private final Project myProject;

    public MyDirectoryRenderer(Project project) {
      myProject = project;
    }

    @Override
    protected void customizeCellRenderer(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) {
      if (value instanceof VcsDirectoryMapping) {
        VcsDirectoryMapping mapping = (VcsDirectoryMapping)value;
        if (mappingIsError(mapping)) {
          setForeground(Color.RED);
        }
        if (mapping.isDefaultMapping()) {
          append(VcsDirectoryMapping.PROJECT_CONSTANT);
          return;
        }
        String directory = mapping.getDirectory();
        VirtualFile baseDir = myProject.getBaseDir();
        if (baseDir != null) {
          final File directoryFile = new File(StringUtil.trimEnd(UriUtil.trimTrailingSlashes(directory), "\\") + "/");
          File ioBase = new File(baseDir.getPath());
          if (directoryFile.isAbsolute() && !FileUtil.isAncestor(ioBase, directoryFile, false)) {
            append(new File(directory).getPath());
            return;
          }
          String relativePath = FileUtil.getRelativePath(ioBase, directoryFile);
          if (".".equals(relativePath) || relativePath == null) {
            append(ioBase.getPath());
          }
          else {
            append(relativePath);
            append(" (" + ioBase + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES);
          }
        }
      }
    }

    private boolean mappingIsError(VcsDirectoryMapping mapping) {
      String vcs = mapping.getVcs();
      VcsRootChecker checker = myCheckers.get(vcs);
      return checker != null &&
             (mapping.isDefaultMapping() ? !checker.isRoot(myProject.getBasePath()) : !checker.isRoot(mapping.getDirectory()));
    }
  }

  private final ColumnInfo<VcsDirectoryMapping, String> VCS_SETTING =
    new ColumnInfo<VcsDirectoryMapping, String>(VcsBundle.message("column.name.configure.vcses.vcs")) {
      @Override
      public String valueOf(final VcsDirectoryMapping object) {
        return object.getVcs();
      }

      @Override
      public boolean isCellEditable(final VcsDirectoryMapping o) {
        return true;
      }

      @Override
      public void setValue(final VcsDirectoryMapping o, final String aValue) {
        Collection<AbstractVcs> activeVcses = getActiveVcses();
        o.setVcs(aValue);
        checkNotifyListeners(activeVcses);
      }

      @Override
      public TableCellRenderer getRenderer(final VcsDirectoryMapping p0) {
        return new ColoredTableCellRenderer() {
          @Override
          protected void customizeCellRenderer(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) {
            final String vcsName = p0.getVcs();
            String text;
            if (vcsName.length() == 0) {
              text = VcsBundle.message("none.vcs.presentation");
            }
            else {
              final VcsDescriptor vcs = myAllVcss.get(vcsName);
              if (vcs != null) {
                text = vcs.getDisplayName();
              }
              else {
                text = VcsBundle.message("unknown.vcs.presentation", vcsName);
              }
            }
            append(text, new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, table.getForeground()));
          }
        };
      }

      @Override
      public TableCellEditor getEditor(final VcsDirectoryMapping o) {
        return new AbstractTableCellEditor() {
          @Override
          public Object getCellEditorValue() {
            final VcsDescriptor selectedVcs = (VcsDescriptor)myVcsComboBox.getComboBox().getSelectedItem();
            return ((selectedVcs == null) || selectedVcs.isNone()) ? "" : selectedVcs.getName();
          }

          @Override
          public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            String vcsName = (String)value;
            myVcsComboBox.getComboBox().setSelectedItem(myAllVcss.get(vcsName));
            return myVcsComboBox;
          }
        };
      }

      @Nullable
      @Override
      public String getMaxStringValue() {
        String maxString = null;
        for (String name : myAllVcss.keySet()) {
          if (maxString == null || maxString.length() < name.length()) {
            maxString = name;
          }
        }
        return maxString;
      }

      @Override
      public int getAdditionalWidth() {
        return DEFAULT_HGAP;
      }
    };

  public VcsDirectoryConfigurationPanel(final Project project) {
    myProject = project;
    myVcsConfiguration = getInstance(myProject);
    myProjectMessage = XmlStringUtil.wrapInHtml(StringUtil.escapeXml(VcsDirectoryMapping.PROJECT_CONSTANT) + " - " +
                                                DefaultVcsRootPolicy.getInstance(myProject).getProjectConfigurationMessage(myProject)
                                                  .replace('\n', ' '));
    myIsDisabled = myProject.isDefault();
    myVcsManager = ProjectLevelVcsManager.getInstance(project);
    final VcsDescriptor[] vcsDescriptors = myVcsManager.getAllVcss();
    myAllVcss = new HashMap<String, VcsDescriptor>();
    for (VcsDescriptor vcsDescriptor : vcsDescriptors) {
      myAllVcss.put(vcsDescriptor.getName(), vcsDescriptor);
    }

    myDirectoryMappingTable = new TableView<VcsDirectoryMapping>();
    myBaseRevisionTexts = new JCheckBox("Store on shelf base revision texts for files under DVCS");
    myLimitHistory = new VcsLimitHistoryConfigurable(myProject);
    myScopeFilterConfig = new VcsUpdateInfoScopeFilterConfigurable(myProject, myVcsConfiguration);

    myCheckers = new HashMap<String, VcsRootChecker>();
    updateRootCheckers();

    setLayout(new BorderLayout());
    add(createMainComponent());

    myDirectoryRenderer = new MyDirectoryRenderer(myProject);
    DIRECTORY = new ColumnInfo<VcsDirectoryMapping, VcsDirectoryMapping>(VcsBundle.message("column.info.configure.vcses.directory")) {
      @Override
      public VcsDirectoryMapping valueOf(final VcsDirectoryMapping mapping) {
        return mapping;
      }

      @Override
      public TableCellRenderer getRenderer(VcsDirectoryMapping vcsDirectoryMapping) {
        return myDirectoryRenderer;
      }
    };
    initializeModel();

    final JComboBox comboBox = myVcsComboBox.getComboBox();
    comboBox.setModel(buildVcsWrappersModel(myProject));
    comboBox.addItemListener(new ItemListener() {
      @Override
      public void itemStateChanged(final ItemEvent e) {
        if (myDirectoryMappingTable.isEditing()) {
          myDirectoryMappingTable.stopEditing();
        }
      }
    });
    myVcsComboBox.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        final VcsDescriptor vcsWrapper = ((VcsDescriptor)comboBox.getSelectedItem());
        new VcsConfigurationsDialog(project, comboBox, vcsWrapper).show();
      }
    });

    myDirectoryMappingTable.setRowHeight(myVcsComboBox.getPreferredSize().height);
    if (myIsDisabled) {
      myDirectoryMappingTable.setEnabled(false);
    }
  }

  private void updateRootCheckers() {
    myCheckers.clear();
    VcsRootChecker[] checkers = Extensions.getExtensions(VcsRootChecker.EXTENSION_POINT_NAME);
    for (VcsRootChecker checker : checkers) {
      VcsKey key = checker.getSupportedVcs();
      AbstractVcs vcs = myVcsManager.findVcsByName(key.getName());
      if (vcs == null) {
        continue;
      }
      myCheckers.put(key.getName(), checker);
    }
  }

  private void initializeModel() {
    List<VcsDirectoryMapping> mappings = new ArrayList<VcsDirectoryMapping>();
    for (VcsDirectoryMapping mapping : ProjectLevelVcsManager.getInstance(myProject).getDirectoryMappings()) {
      mappings.add(new VcsDirectoryMapping(mapping.getDirectory(), mapping.getVcs(), mapping.getRootSettings()));
    }
    myModel = new ListTableModel<VcsDirectoryMapping>(new ColumnInfo[]{DIRECTORY, VCS_SETTING}, mappings, 0);
    myDirectoryMappingTable.setModelAndUpdateColumns(myModel);

    myRecentlyChangedConfigurable.reset();
    myLimitHistory.reset();
    myScopeFilterConfig.reset();
    myBaseRevisionTexts.setSelected(myVcsConfiguration.INCLUDE_TEXT_INTO_SHELF);
    myShowChangedRecursively.setSelected(myVcsConfiguration.SHOW_DIRTY_RECURSIVELY);
    myCommitMessageMarginConfigurable.reset();
  }

  public static DefaultComboBoxModel buildVcsWrappersModel(final Project project) {
    final VcsDescriptor[] vcsDescriptors = ProjectLevelVcsManager.getInstance(project).getAllVcss();
    final VcsDescriptor[] result = new VcsDescriptor[vcsDescriptors.length + 1];
    result[0] = VcsDescriptor.createFictive();
    System.arraycopy(vcsDescriptors, 0, result, 1, vcsDescriptors.length);
    return new DefaultComboBoxModel(result);
  }

  private void addMapping() {
    VcsMappingConfigurationDialog dlg = new VcsMappingConfigurationDialog(myProject, VcsBundle.message("directory.mapping.add.title"));
    // due to wonderful UI designer bug
    dlg.initProjectMessage();
    dlg.show();
    if (dlg.isOK()) {
      VcsDirectoryMapping mapping = new VcsDirectoryMapping();
      dlg.saveToMapping(mapping);
      addMapping(mapping);
    }
  }

  private void addMapping(VcsDirectoryMapping mapping) {
    List<VcsDirectoryMapping> items = new ArrayList<VcsDirectoryMapping>(myModel.getItems());
    items.add(mapping);
    myModel.setItems(items);
    checkNotifyListeners(getActiveVcses());
  }

  private void editMapping() {
    Collection<AbstractVcs> activeVcses = getActiveVcses();
    VcsMappingConfigurationDialog dlg = new VcsMappingConfigurationDialog(myProject, VcsBundle.message("directory.mapping.remove.title"));
    final VcsDirectoryMapping mapping = myDirectoryMappingTable.getSelectedObject();
    dlg.setMapping(mapping);
    dlg.show();
    if (dlg.isOK()) {
      dlg.saveToMapping(mapping);
      myModel.fireTableDataChanged();
      checkNotifyListeners(activeVcses);
    }
  }

  private void removeMapping() {
    Collection<AbstractVcs> activeVcses = getActiveVcses();
    ArrayList<VcsDirectoryMapping> mappings = new ArrayList<VcsDirectoryMapping>(myModel.getItems());
    int index = myDirectoryMappingTable.getSelectionModel().getMinSelectionIndex();
    Collection<VcsDirectoryMapping> selection = myDirectoryMappingTable.getSelection();
    mappings.removeAll(selection);
    myModel.setItems(mappings);
    if (mappings.size() > 0) {
      if (index >= mappings.size()) {
        index = mappings.size() - 1;
      }
      myDirectoryMappingTable.getSelectionModel().setSelectionInterval(index, index);
    }
    checkNotifyListeners(activeVcses);
  }

  protected JComponent createMainComponent() {
    JPanel panel = new JPanel(new GridBagLayout());
    GridBag gb = new GridBag()
      .setDefaultInsets(new Insets(0, 0, DEFAULT_VGAP, DEFAULT_HGAP))
      .setDefaultWeightX(1)
      .setDefaultFill(GridBagConstraints.HORIZONTAL);

    panel.add(createMappingsTable(), gb.nextLine().next().fillCell().weighty(1.0));
    panel.add(createProjectMappingDescription(), gb.nextLine().next());
    panel.add(createErrorList(), gb.nextLine().next());
    panel.add(myLimitHistory.createComponent(), gb.nextLine().next());
    panel.add(createShowRecursivelyDirtyOption(), gb.nextLine().next());
    panel.add(createStoreBaseRevisionOption(), gb.nextLine().next());
    panel.add(createShowChangedOption(), gb.nextLine().next());
    panel.add(createShowVcsRootErrorNotificationOption(), gb.nextLine().next());
    panel.add(myScopeFilterConfig.createComponent(), gb.nextLine().next());
    panel.add(createUseCommitMessageRightMargin(), gb.nextLine().next().fillCellHorizontally());

    return panel;
  }

  private JComponent createMappingsTable() {
    JPanel panelForTable = ToolbarDecorator.createDecorator(myDirectoryMappingTable, null)
      .setAddAction(new AnActionButtonRunnable() {
        @Override
        public void run(AnActionButton button) {
          addMapping();
          updateRootCheckers();
        }
      }).setEditAction(new AnActionButtonRunnable() {
        @Override
        public void run(AnActionButton button) {
          editMapping();
          updateRootCheckers();
        }
      }).setRemoveAction(new AnActionButtonRunnable() {
        @Override
        public void run(AnActionButton button) {
          removeMapping();
          updateRootCheckers();
        }
      }).setAddActionUpdater(new AnActionButtonUpdater() {
        @Override
        public boolean isEnabled(AnActionEvent e) {
          return !myIsDisabled;
        }
      }).setEditActionUpdater(new AnActionButtonUpdater() {
        @Override
        public boolean isEnabled(AnActionEvent e) {
          final boolean hasSelection = myDirectoryMappingTable.getSelectedObject() != null;
          return (!myIsDisabled) && hasSelection;
        }
      }).setRemoveActionUpdater(new AnActionButtonUpdater() {
        @Override
        public boolean isEnabled(AnActionEvent e) {
          final boolean hasSelection = myDirectoryMappingTable.getSelectedObject() != null;
          return (!myIsDisabled) && hasSelection;
        }
      }).disableUpDownActions().createPanel();
    panelForTable.setPreferredSize(new Dimension(-1, 200));
    return panelForTable;
  }

  private JComponent createErrorList() {
    final int DEFAULT_HEIGHT = 200;
    final JComponent errorPanel = Box.createVerticalBox();
    final JBScrollPane pane = new JBScrollPane(errorPanel);

    Collection<VcsRootError> myErrors = VcsRootErrorsFinder.getInstance(myProject).find();
    for (final VcsRootError root : myErrors) {
      if (!VcsRootError.Type.UNREGISTERED_ROOT.equals(root.getType())) {
        continue;
      }
      final VcsKey vcsKey = root.getVcsKey();
      final VcsDescriptor vcsDescriptor = myAllVcss.get(vcsKey.getName());
      String displayVcsName = vcsDescriptor.getDisplayName();
      String title = "Unregistered " + displayVcsName + " root: " + FileUtil.toSystemDependentName(root.getMapping());
      final VcsRootErrorLabel vcsRootErrorLabel = new VcsRootErrorLabel(title);
      vcsRootErrorLabel.setAddRootLinkHandler(new Runnable() {
        @Override
        public void run() {
          addMapping(new VcsDirectoryMapping(root.getMapping(), vcsKey.getName()));
          errorPanel.remove(vcsRootErrorLabel);
          if (errorPanel.getComponentCount() == 0) {
            pane.setVisible(false);
          }
          pane.setMinimumSize(new Dimension(-1, calcMinHeight(errorPanel, DEFAULT_HEIGHT)));
          validate();
        }
      });
      errorPanel.add(vcsRootErrorLabel);
    }

    if (errorPanel.getComponentCount() == 0) {
      pane.setVisible(false);
    }
    pane.setMinimumSize(new Dimension(-1, calcMinHeight(errorPanel, DEFAULT_HEIGHT)));
    pane.setMaximumSize(new Dimension(-1, DEFAULT_HEIGHT));
    return pane;
  }

  private static int calcMinHeight(@NotNull JComponent errorPanel, int defaultHeight) {
    int height = errorPanel.getPreferredSize().height;
    return height > defaultHeight ? defaultHeight : height;
  }

  private JComponent createProjectMappingDescription() {
    final JBLabel label = new JBLabel(myProjectMessage);
    label.setComponentStyle(UIUtil.ComponentStyle.SMALL);
    label.setFontColor(UIUtil.FontColor.BRIGHTER);
    label.setBorder(BorderFactory.createEmptyBorder(2, 5, 2, 0));
    return label;
  }

  private JComponent createStoreBaseRevisionOption() {
    final JBLabel noteLabel = new JBLabel("File texts bigger than " + ourMaximumFileForBaseRevisionSize / 1000 + "K are not stored");
    noteLabel.setComponentStyle(UIUtil.ComponentStyle.SMALL);
    noteLabel.setFontColor(UIUtil.FontColor.BRIGHTER);
    noteLabel.setBorder(BorderFactory.createEmptyBorder(2, 25, 5, 0));

    final JPanel panel = new JPanel(new BorderLayout());
    panel.add(myBaseRevisionTexts, BorderLayout.NORTH);
    panel.add(noteLabel, BorderLayout.SOUTH);
    return panel;
  }

  private JComponent createShowChangedOption() {
    myRecentlyChangedConfigurable = new VcsContentAnnotationConfigurable(myProject);
    JComponent component = myRecentlyChangedConfigurable.createComponent();
    assert component != null;
    return component;
  }

  private JComponent createShowVcsRootErrorNotificationOption() {
    myShowVcsRootErrorNotification = new JCheckBox("Notify about VCS root errors",
                                                   myVcsConfiguration.SHOW_VCS_ERROR_NOTIFICATIONS);
    myShowVcsRootErrorNotification.setVisible(!myCheckers.isEmpty());
    return myShowVcsRootErrorNotification;
  }

  private JComponent createUseCommitMessageRightMargin() {
    myCommitMessageMarginConfigurable = new VcsCommitMessageMarginConfigurable(myProject, myVcsConfiguration);
    return myCommitMessageMarginConfigurable.createComponent();
  }

  private JComponent createShowRecursivelyDirtyOption() {
    myShowChangedRecursively = new JCheckBox("Show directories with changed descendants", myVcsConfiguration.SHOW_DIRTY_RECURSIVELY);
    return myShowChangedRecursively;
  }

  @Override
  public void reset() {
    initializeModel();
  }

  @Override
  public void apply() throws ConfigurationException {
    myVcsManager.setDirectoryMappings(myModel.getItems());
    myRecentlyChangedConfigurable.apply();
    myLimitHistory.apply();
    myScopeFilterConfig.apply();
    myVcsConfiguration.INCLUDE_TEXT_INTO_SHELF = myBaseRevisionTexts.isSelected();
    myVcsConfiguration.SHOW_VCS_ERROR_NOTIFICATIONS = myShowVcsRootErrorNotification.isSelected();
    myVcsConfiguration.SHOW_DIRTY_RECURSIVELY = myShowChangedRecursively.isSelected();
    myCommitMessageMarginConfigurable.apply();
    initializeModel();
  }

  @Override
  public boolean isModified() {
    if (myRecentlyChangedConfigurable.isModified()) return true;
    if (myLimitHistory.isModified()) return true;
    if (myScopeFilterConfig.isModified()) return true;
    if (myVcsConfiguration.INCLUDE_TEXT_INTO_SHELF != myBaseRevisionTexts.isSelected()) return true;
    if (myVcsConfiguration.SHOW_VCS_ERROR_NOTIFICATIONS != myShowVcsRootErrorNotification.isSelected()) {
      return true;
    }
    if (myVcsConfiguration.SHOW_DIRTY_RECURSIVELY != myShowChangedRecursively.isSelected()) {
      return true;
    }
    if (myCommitMessageMarginConfigurable.isModified()) {
      return true;
    }
    return !myModel.getItems().equals(myVcsManager.getDirectoryMappings());
  }

  public void addVcsListener(final ModuleVcsListener moduleVcsListener) {
    myListeners.add(moduleVcsListener);
  }

  public void removeVcsListener(final ModuleVcsListener moduleVcsListener) {
    myListeners.remove(moduleVcsListener);
  }

  private void checkNotifyListeners(Collection<AbstractVcs> oldVcses) {
    Collection<AbstractVcs> vcses = getActiveVcses();
    if (!vcses.equals(oldVcses)) {
      for (ModuleVcsListener listener : myListeners) {
        listener.activeVcsSetChanged(vcses);
      }
    }
  }

  public Collection<AbstractVcs> getActiveVcses() {
    Set<AbstractVcs> vcses = new HashSet<AbstractVcs>();
    for (VcsDirectoryMapping mapping : myModel.getItems()) {
      if (mapping.getVcs().length() > 0) {
        vcses.add(myVcsManager.findVcsByName(mapping.getVcs()));
      }
    }
    return vcses;
  }

  @Override
  @Nls
  public String getDisplayName() {
    return "Mappings";
  }

  @Override
  public String getHelpTopic() {
    return null;
  }

  @Override
  public JComponent createComponent() {
    return this;
  }

  @Override
  public void disposeUIResources() {
    myLimitHistory.disposeUIResources();
    myScopeFilterConfig.disposeUIResources();
  }

  private static class VcsRootErrorLabel extends JPanel {

    private final LinkLabel myAddLabel;

    VcsRootErrorLabel(String title) {
      super(new BorderLayout(DEFAULT_HGAP, DEFAULT_VGAP));

      CompoundBorder outsideBorder =
        BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(5, 0, 5, 0, UIUtil.getPanelBackground()),
                                           BorderFactory.createLineBorder(UIUtil.getPanelBackground().darker()));
      setBorder(BorderFactory.createCompoundBorder(outsideBorder, BorderFactory.createEmptyBorder(DEFAULT_VGAP, DEFAULT_HGAP,
                                                                                                  DEFAULT_VGAP, DEFAULT_HGAP)));
      setOpaque(true);
      setBackground(new Color(255, 186, 192));

      JBLabel label = new JBLabel(title);
      if( UIUtil.isUnderDarcula()) {
        label.setForeground(UIUtil.getPanelBackground());
      }

      myAddLabel = new LinkLabel("Add root", null);

      myAddLabel.setOpaque(false);

      JPanel actionsPanel = new JPanel(new BorderLayout(DEFAULT_HGAP, DEFAULT_VGAP));
      actionsPanel.setOpaque(false);
      actionsPanel.add(myAddLabel, BorderLayout.CENTER);

      add(label, BorderLayout.CENTER);
      add(actionsPanel, BorderLayout.EAST);
    }

    void setAddRootLinkHandler(final Runnable handler) {
      myAddLabel.setListener(new LinkListener() {
        @Override
        public void linkSelected(LinkLabel aSource, Object aLinkData) {
          handler.run();
        }
      }, null);
    }
  }
}
