/*
 * Copyright (c) 2004 JetBrains s.r.o. All  Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * -Redistributions of source code must retain the above copyright
 *  notice, this list of conditions and the following disclaimer.
 *
 * -Redistribution in binary form must reproduct the above copyright
 *  notice, this list of conditions and the following disclaimer in
 *  the documentation and/or other materials provided with the distribution.
 *
 * Neither the name of JetBrains or IntelliJ IDEA
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
 * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
 * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT
 * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT
 * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS
 * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST
 * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
 * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
 * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN
 * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 *
 */
package com.intellij.openapi.vcs.update;

import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.util.ui.OptionsDialog;

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

public abstract class UpdateOrStatusOptionsDialog extends OptionsDialog {
  private final JComponent myMainPanel;
  private final Map<AbstractVcs, Configurable> myEnvToConfMap = new HashMap<AbstractVcs, Configurable>();
  protected final Project myProject;


  public UpdateOrStatusOptionsDialog(Project project, Map<Configurable, AbstractVcs> confs) {
    super(project);
    setTitle(getRealTitle());
    myProject = project;
    if (confs.size() == 1) {
      myMainPanel = new JPanel(new BorderLayout());
      final Configurable configurable = confs.keySet().iterator().next();
      addComponent(confs.get(configurable), configurable, BorderLayout.CENTER);
      myMainPanel.add(new JSeparator(), BorderLayout.SOUTH);
    }
    else {
      myMainPanel = new JTabbedPane();
      final ArrayList<AbstractVcs> vcses = new ArrayList<AbstractVcs>(confs.values());
      Collections.sort(vcses, new Comparator<AbstractVcs>() {
        public int compare(final AbstractVcs o1, final AbstractVcs o2) {
          return o1.getDisplayName().compareTo(o2.getDisplayName());
        }
      });
      Map<AbstractVcs, Configurable> vcsToConfigurable = revertMap(confs);
      for (AbstractVcs vcs : vcses) {
        addComponent(vcs, vcsToConfigurable.get(vcs), vcs.getDisplayName());
      }
    }
    init();
  }

  private Map<AbstractVcs, Configurable> revertMap(final Map<Configurable, AbstractVcs> confs) {
    final HashMap<AbstractVcs, Configurable> result = new HashMap<AbstractVcs, Configurable>();
    for (Configurable configurable : confs.keySet()) {
      result.put(confs.get(configurable), configurable);
    }
    return result;
  }

  protected abstract String getRealTitle();

  private void addComponent(AbstractVcs vcs, Configurable configurable, String constraint) {
    myEnvToConfMap.put(vcs, configurable);
    myMainPanel.add(configurable.createComponent(), constraint);
    configurable.reset();
  }

  protected void doOKAction() {
    for (Configurable configurable : myEnvToConfMap.values()) {
      try {
        configurable.apply();
      }
      catch (ConfigurationException e) {
        Messages.showErrorDialog(myProject, VcsBundle.message("messge.text.cannot.save.settings", e.getLocalizedMessage()), getRealTitle());
        return;
      }
    }
    super.doOKAction();
  }

  protected boolean shouldSaveOptionsOnCancel() {
    return false;
  }

  protected JComponent createCenterPanel() {

    return myMainPanel;
  }
}

@@ -1920,24 +1920,70 @@
 .VcsBundle;%0A
+import com.intellij.openapi.help.HelpManager;%0A
 import com.i
@@ -2013,16 +2013,16 @@
 Dialog;%0A
-
 %0Aimport 
@@ -3398,16 +3398,23 @@
 private 
+static 
 Map%3CAbst
@@ -4513,16 +4513,16 @@
 el() %7B%0A%0A
-
     retu
@@ -4540,11 +4540,954 @@
 nel;%0A  %7D
+%0A%0A  protected Action%5B%5D createActions() %7B%0A    for(Configurable conf: myEnvToConfMap.values()) %7B%0A      if (conf.getHelpTopic() != null) %7B%0A        return new Action%5B%5D %7B getOKAction(), getCancelAction(), getHelpAction() %7D;%0A      %7D%0A    %7D%0A    return super.createActions();%0A  %7D%0A%0A  protected void doHelpAction() %7B%0A    String helpTopic = null;%0A    final Collection%3CConfigurable%3E v = myEnvToConfMap.values();%0A    final Configurable%5B%5D configurables = v.toArray(new Configurable%5Bv.size()%5D);%0A    if (myMainPanel instanceof JTabbedPane) %7B%0A      final int tabIndex = ((JTabbedPane)myMainPanel).getSelectedIndex();%0A      if (tabIndex %3E= 0 && tabIndex %3C configurables.length) %7B%0A        helpTopic = configurables %5BtabIndex%5D.getHelpTopic();%0A      %7D%0A    %7D%0A    else %7B%0A      helpTopic = configurables %5B0%5D.getHelpTopic();%0A    %7D%0A    if (helpTopic != null) %7B%0A      HelpManager.getInstance().invokeHelp(helpTopic);%0A    %7D%0A    else %7B%0A      super.doHelpAction();%0A    %7D%0A  %7D
 %0A%7D%0A

add help button in update/integrate dialogs (IDEADEV-23182)