gt:           Tag.listAsStrings(myProject, getGitRoot(), myTagNames, null);
context: /*
   * Copyright 2000-2009 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 org.community.intellij.plugins.communitycase.checkin;
  
  import com.intellij.ide.util.ElementsChooser;
  import com.intellij.openapi.diagnostic.Logger;
  import com.intellij.openapi.project.Project;
  import com.intellij.openapi.ui.DialogWrapper;
  import com.intellij.openapi.util.text.StringUtil;
  import com.intellij.openapi.vcs.VcsException;
  import com.intellij.openapi.vfs.VirtualFile;
  import com.intellij.ui.DocumentAdapter;
  import com.intellij.util.containers.HashMap;
  import org.community.intellij.plugins.communitycase.Branch;
  import org.community.intellij.plugins.communitycase.Remote;
  import org.community.intellij.plugins.communitycase.Tag;
  import org.community.intellij.plugins.communitycase.commands.Command;
  import org.community.intellij.plugins.communitycase.commands.LineHandler;
  import org.community.intellij.plugins.communitycase.config.ConfigUtil;
  import org.community.intellij.plugins.communitycase.i18n.Bundle;
  import org.community.intellij.plugins.communitycase.ui.UiUtil;
  import org.jetbrains.annotations.Nullable;
  
  import javax.swing.*;
  import javax.swing.event.DocumentEvent;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  import java.util.ArrayList;
  import java.util.List;
  
  /**
   * The push dialog
   */
  public class PushDialog extends DialogWrapper {
    /**
     * the logger
     */
    private static final Logger LOG = Logger.getInstance("#"+PushDialog.class.getName());
    /**
     * Push policy meaning selected references
     */
    private static final String PUSH_POLICY_SELECTED = Bundle.getString("push.policy.selected");
    /**
     * This push policy means that simple "git push" will be used, so push will happen according to the push configuration.
     */
    private static final String PUSH_POLICY_DEFAULT = Bundle.getString("push.policy.default");
    /**
     * Push policy meaning all references
     */
    private static final String PUSH_POLICY_ALL = Bundle.getString("push.policy.all");
    /**
     * Push policy meaning mirror
     */
    private static final String PUSH_POLICY_MIRROR = Bundle.getString("push.policy.mirror");
    /**
     * The root panel
     */
    private JPanel myPanel;
    /**
     * Git root selector
     */
    private JComboBox myGitRootComboBox;
    /**
     * Remote name combobox
     */
    private JComboBox myRemoteComboBox;
    /**
     * Push tags flag
     */
    private JCheckBox myPushTagsCheckBox;
    /**
     * Use thin pack flag
     */
    private JCheckBox myUseThinPackCheckBox;
    /**
     * The push policy drop down
     */
    private JComboBox myPushPolicy;
    /**
     * Force update checkbox
     */
    private JCheckBox myForceUpdateCheckBox;
    /**
     * Chooser for branches
     */
    private ElementsChooser<String> myBranchChooser;
    /**
     * The current branch label
     */
    private JLabel myCurrentBranch;
    /**
     * The checkbox that specifies whether tags are shown
     */
    private JCheckBox myShowTagsCheckBox;
    /**
     * The list of branches
     */
    private final ArrayList<String> myBranchNames = new ArrayList<String>();
    /**
     * The list of branches
     */
    private final ArrayList<String> myTagNames = new ArrayList<String>();
    /**
     * The map from list of branches to the result of mirror checks
     */
    private final HashMap<String, Boolean> myMirrorChecks = new HashMap<String, Boolean>();
    /**
     * The current project
     */
    private final Project myProject;
  
    /**
     * A constructor
     *
     * @param project     the project
     * @param roots       the list of the roots
     * @param defaultRoot the default root to select
     */
    public PushDialog(final Project project, final List<VirtualFile> roots, final VirtualFile defaultRoot) {
      super(project, true);
      setTitle(Bundle.getString("push.title"));
      setOKButtonText(Bundle.getString("push.button"));
      UiUtil.setupRootChooser(project, roots, defaultRoot, myGitRootComboBox, myCurrentBranch);
      myProject = project;
      setupRemotes();
      setupPolicy();
      setupValidation();
      myShowTagsCheckBox.addActionListener(new ActionListener() {
        public void actionPerformed(final ActionEvent e) {
          if (myPushPolicy.getSelectedItem().equals(PUSH_POLICY_SELECTED)) {
            updateBranchChooser();
          }
        }
      });
      init();
    }
  
    /**
     * @return a prepared handler for push operation
     */
    public LineHandler handler() {
      LineHandler h = new LineHandler(myProject, getGitRoot(), Command.PUSH);
      String policy = (String)myPushPolicy.getSelectedItem();
      if (PUSH_POLICY_ALL.equals(policy)) {
        h.addParameters("--all");
      }
      else if (PUSH_POLICY_MIRROR.equals(policy)) {
        h.addParameters("--mirror");
      }
      if (myPushTagsCheckBox.isEnabled() && myPushTagsCheckBox.isSelected()) {
        h.addParameters("--tags");
      }
      if (myUseThinPackCheckBox.isSelected()) {
        h.addParameters("--thin");
      }
      if (myForceUpdateCheckBox.isSelected()) {
        h.addParameters("--force");
      }
      h.addParameters("-v");
      h.addParameters(getRemoteTextField().getText());
      if (PUSH_POLICY_SELECTED.equals(policy)) {
        for (String b : myBranchChooser.getMarkedElements()) {
          if (myBranchNames.contains(b)) {
            h.addParameters(b);
          }
          else {
            h.addParameters("tag", b);
          }
        }
      }
      return h;
    }
  
    /**
     * Setup dialog validation
     */
    private void setupValidation() {
      myPushPolicy.addActionListener(new ActionListener() {
        public void actionPerformed(final ActionEvent e) {
          validateFields();
        }
      });
      getRemoteTextField().getDocument().addDocumentListener(new DocumentAdapter() {
        protected void textChanged(final DocumentEvent e) {
          validateFields();
        }
      });
      myBranchChooser.addElementsMarkListener(new ElementsChooser.ElementsMarkListener<String>() {
        public void elementMarkChanged(final String element, final boolean isMarked) {
          validateFields();
        }
      });
      validateFields();
    }
  
    /**
     * Validate fields in the dialog
     */
    private void validateFields() {
      boolean isValid = getRemoteTextField().getText().length() != 0;
      final Object policy = myPushPolicy.getSelectedItem();
      isValid &= !policy.equals(PUSH_POLICY_SELECTED) || myBranchChooser.getMarkedElements().size() != 0;
      setOKActionEnabled(isValid);
    }
  
    /**
     * Setup policy combobox
     */
    private void setupPolicy() {
      myPushPolicy.addItem(PUSH_POLICY_SELECTED);
      myPushPolicy.addItem(PUSH_POLICY_DEFAULT);
      myPushPolicy.addItem(PUSH_POLICY_ALL);
      myPushPolicy.addItem(PUSH_POLICY_MIRROR);
      myPushPolicy.setSelectedIndex(0);
      // configure policy listener
      final ActionListener policyListener = new ActionListener() {
        public void actionPerformed(final ActionEvent e) {
          String p = (String)myPushPolicy.getSelectedItem();
          if (PUSH_POLICY_SELECTED.equals(p)) {
            myBranchChooser.setEnabled(true);
            myShowTagsCheckBox.setEnabled(true);
            updateBranchChooser();
          }
          else {
            myBranchChooser.clear();
            myBranchChooser.setEnabled(false);
            myShowTagsCheckBox.setEnabled(false);
          }
          if (PUSH_POLICY_MIRROR.equals(p)) {
            myPushTagsCheckBox.setEnabled(false);
            myPushTagsCheckBox.setSelected(true);
            myForceUpdateCheckBox.setEnabled(false);
            myForceUpdateCheckBox.setSelected(true);
          }
          else {
            if (!myForceUpdateCheckBox.isEnabled()) {
              myForceUpdateCheckBox.setEnabled(true);
              myForceUpdateCheckBox.setSelected(false);
            }
            if (PUSH_POLICY_ALL.equals(p)) {
              myPushTagsCheckBox.setEnabled(false);
              myPushTagsCheckBox.setSelected(false);
            }
            else if (!myPushTagsCheckBox.isEnabled()) {
              myPushTagsCheckBox.setEnabled(true);
              myPushTagsCheckBox.setSelected(false);
            }
          }
        }
      };
      myPushPolicy.addActionListener(policyListener);
      policyListener.actionPerformed(null);
      // select remote listener
      final DocumentAdapter listener = new DocumentAdapter() {
        VirtualFile myPreviousRoot;
        Remote myPreviousRemote = null;
  
        protected void textChanged(final DocumentEvent e) {
          final VirtualFile newRoot = getGitRoot();
          final Remote newRemote = getRemote(getRemoteTextField().getText());
          if (newRoot == null) {
            return;
          }
          if (myPreviousRoot == null || myPreviousRemote == null || !myPreviousRoot.equals(newRoot) || !myPreviousRemote.equals(newRemote)) {
            if (isMirror()) {
              myPushPolicy.setEnabled(false);
              myPushPolicy.setSelectedItem(PUSH_POLICY_MIRROR);
            }
            else {
              if (!myPushPolicy.isEnabled()) {
                myPushPolicy.setSelectedItem(PUSH_POLICY_SELECTED);
                myPushPolicy.setEnabled(true);
              }
            }
            myPreviousRoot = newRoot;
            myPreviousRemote = newRemote;
          }
        }
      };
      getRemoteTextField().getDocument().addDocumentListener(listener);
      myGitRootComboBox.addActionListener(new ActionListener() {
        public void actionPerformed(final ActionEvent e) {
          listener.changedUpdate(null);
        }
      });
      listener.changedUpdate(null);
    }
  
    /**
     * Update content of the branch chooser
     */
    private void updateBranchChooser() {
      myBranchChooser.clear();
      final String current = myCurrentBranch.getText();
      for (String b : myBranchNames) {
        myBranchChooser.addElement(b, b.equals(current));
      }
      if (myShowTagsCheckBox.isSelected()) {
        for (String t : myTagNames) {
          myBranchChooser.addElement(t, false);
        }
      }
      validateFields();
    }
  
    /**
     * @return true if the current branch should be mirror branch
     */
    private boolean isMirror() {
      final String name = getRemoteTextField().getText();
      Boolean rc = myMirrorChecks.get(name);
      if (rc == null) {
        rc = false;
        Remote remote = getRemote(name);
        if (remote != null) {
          try {
            rc = ConfigUtil.getBoolValue(myProject, getGitRoot(), "remote." + name + ".mirror");
            if (rc == null) {
              rc = false;
            }
          }
          catch (VcsException e) {
            // treat error as a false value
          }
          myMirrorChecks.put(name, rc);
        }
      }
      return rc.booleanValue();
    }
  
    /**
     * Get currently selected remote object.
     *
     * @param name a name to select
     * @return the remote or null
     */
    @Nullable
    private Remote getRemote(final String name) {
      for (int i = myRemoteComboBox.getItemCount() - 1; i >= 0; i--) {
        final Remote r = (Remote)myRemoteComboBox.getItemAt(i);
        if (name.equals(r.toString())) {
          return r;
        }
      }
      return null;
    }
  
    /**
     * Setup drop down with remotes
     */
    private void setupRemotes() {
      final ActionListener actionListener = new ActionListener() {
        public void actionPerformed(final ActionEvent e) {
          updateRemotes();
          myMirrorChecks.clear();
          myBranchNames.clear();
          myTagNames.clear();
          try {
            Branch.listAsStrings(myProject, getGitRoot(), false, true, myBranchNames, null);
  