/*
 * Copyright 2000-2012 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.
 */

/*
 * Class BreakpointPropertiesPanel
 * @author Jeka
 */
package com.intellij.debugger.ui.breakpoints;

import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.InstanceFilter;
import com.intellij.debugger.engine.evaluation.CodeFragmentKind;
import com.intellij.debugger.engine.evaluation.DefaultCodeFragmentFactory;
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
import com.intellij.debugger.settings.DebuggerSettings;
import com.intellij.debugger.ui.CompletionEditor;
import com.intellij.debugger.ui.DebuggerExpressionComboBox;
import com.intellij.debugger.ui.DebuggerStatementEditor;
import com.intellij.debugger.ui.JavaDebuggerSupport;
import com.intellij.ide.util.ClassFilter;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.FixedSizeButton;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.ui.FieldPanel;
import com.intellij.ui.MultiLineTooltipUI;
import com.intellij.ui.popup.util.DetailView;
import com.intellij.util.IJSwingUtilities;
import com.intellij.xdebugger.impl.DebuggerSupport;
import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointChooser;
import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointItem;
import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointNoneItem;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

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

public abstract class BreakpointPropertiesPanel {

  private BreakpointChooser myMasterBreakpointChooser;

  public void setDetailView(DetailView detailView) {
    myMasterBreakpointChooser.setDetailView(detailView);
  }

  protected final Project myProject;
  private final Key<? extends Breakpoint> myBreakpointCategory;
  private boolean myCompact;
  private JPanel myPanel;
  private final DebuggerExpressionComboBox myConditionCombo;
  private final DebuggerExpressionComboBox myLogExpressionCombo;
  private JTextField myPassCountField;
  private final FieldPanel myInstanceFiltersField;

  private final FieldPanel myClassFiltersField;
  private com.intellij.ui.classFilter.ClassFilter[] myClassFilters;
  private com.intellij.ui.classFilter.ClassFilter[] myClassExclusionFilters;
  private InstanceFilter[] myInstanceFilters;

  private JCheckBox myLogExpressionCheckBox;
  private JCheckBox myLogMessageCheckBox;
  protected JCheckBox myPassCountCheckbox;
  private JCheckBox myInstanceFiltersCheckBox;
  private JCheckBox myClassFiltersCheckBox;

  private JPanel myInstanceFiltersFieldPanel;
  private JPanel myClassFiltersFieldPanel;
  private JPanel myConditionComboPanel;
  private JPanel myLogExpressionComboPanel;
  private JPanel myDependentBreakpointComboPanel;
  private JPanel mySpecialBoxPanel;
  private PsiClass myBreakpointPsiClass;

  private JRadioButton myRbSuspendThread;
  private JRadioButton myRbSuspendAll;
  private JCheckBox myCbSuspend;
  private JButton myMakeDefaultButton;

  private JRadioButton myDisableAgainRadio;
  private JRadioButton myLeaveEnabledRadioButton;

  private JLabel myEnableOrDisableLabel;
  private JPanel myDependsOnPanel;
  private JPanel myInstanceFiltersPanel;
  private JPanel myClassFiltersPanel;
  private JPanel myPassCountPanel;
  private JPanel myConditionsPanel;
  private JPanel myActionsPanel;
  private JCheckBox myConditionCheckbox;
  private JCheckBox myTemporaryCheckBox;
  private JCheckBox myEnabledCheckbox;

  ButtonGroup mySuspendPolicyGroup;
  public static final String CONTROL_LOG_MESSAGE = "logMessage";
  private final FixedSizeButton myConditionMagnifierButton;
  private boolean myMoreOptionsVisible = true;
  private Breakpoint myBreakpoint;

  public boolean isSaveOnRemove() {
    return mySaveOnRemove;
  }

  public void setSaveOnRemove(boolean saveOnRemove) {
    mySaveOnRemove = saveOnRemove;
  }

  private boolean mySaveOnRemove = false;

  public boolean isMoreOptionsVisible() {
    return myMoreOptionsVisible;
  }

  private void createUIComponents() {
    myPanel = new JPanel() {
      @Override
      public void removeNotify() {
        super.removeNotify();
        if (mySaveOnRemove) {
          saveTo(myBreakpoint, new Runnable() {
            @Override
            public void run() {}
          });
        }
      }
    };
  }

  public interface Delegate {

    void showActionsPanel();
  }
  private Delegate myDelegate;

  public JComponent getControl(String control) {
    if(CONTROL_LOG_MESSAGE.equals(control)) {
      return myLogExpressionCombo;
    }
    return null;
  }

  public void dispose() {
    if (myConditionCombo != null) {
      myConditionCombo.dispose();
    }
    if (myLogExpressionCombo != null) {
      myLogExpressionCombo.dispose();
    }
  }

  public void setActionsPanelVisible(boolean b) {
    myActionsPanel.setVisible(b);
  }

  public void setMoreOptionsVisible(boolean b) {
    myMoreOptionsVisible = b;
    myDependsOnPanel.setVisible(b);
    myConditionsPanel.setVisible(b);
    if (b) {
      myActionsPanel.setVisible(true);
    }
    if (!b) {
      myPanel.setPreferredSize(new Dimension(500, -1));
    }
  }

  public void setDelegate(Delegate delegate) {
    myDelegate = delegate;
  }

  private class MyTextField extends JTextField {
    public MyTextField() {
    }

    @Override
    public String getToolTipText(MouseEvent event) {
      reloadClassFilters();
      updateClassFilterEditor(false);
      reloadInstanceFilters();
      updateInstanceFilterEditor(false);
      String toolTipText = super.getToolTipText(event);
      return getToolTipText().length() == 0 ? null : toolTipText;
    }

    @Override
    public JToolTip createToolTip() {
      JToolTip toolTip = new JToolTip(){{
        setUI(new MultiLineTooltipUI());
      }};
      toolTip.setComponent(this);
      return toolTip;
    }
  }

  private static void insert(JPanel panel, JComponent component) {
    panel.setLayout(new BorderLayout());
    panel.add(component, BorderLayout.CENTER);
  }

  public BreakpointPropertiesPanel(final Project project, final Key<? extends Breakpoint> breakpointCategory, boolean compact) {
    myProject = project;
    myBreakpointCategory = breakpointCategory;
    myCompact = compact;

    mySuspendPolicyGroup = new ButtonGroup();
    mySuspendPolicyGroup.add(myRbSuspendAll);
    mySuspendPolicyGroup.add(myRbSuspendThread);

    updateSuspendPolicyRbFont();
    final ItemListener suspendPolicyChangeListener = new ItemListener() {
      @Override
      public void itemStateChanged(final ItemEvent e) {
        final BreakpointDefaults defaults = getBreakpointManager(myProject).getBreakpointDefaults(breakpointCategory);
        myMakeDefaultButton.setEnabled(!defaults.getSuspendPolicy().equals(getSelectedSuspendPolicy()) || defaults.isConditionEnabled() != myConditionCheckbox.isSelected());
      }
    };

    myCbSuspend.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent event) {
        final boolean enabled = myCbSuspend.isSelected();
        myRbSuspendAll.setEnabled(enabled);
        myRbSuspendThread.setEnabled(enabled);
      }
    });


    myRbSuspendAll.addItemListener(suspendPolicyChangeListener);
    myRbSuspendThread.addItemListener(suspendPolicyChangeListener);
    myConditionCheckbox.addItemListener(suspendPolicyChangeListener);

    myMakeDefaultButton.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(final ActionEvent e) {
        final BreakpointManager breakpointManager = getBreakpointManager(myProject);
        final String suspendPolicy = getSelectedSuspendPolicy();
        breakpointManager.setBreakpointDefaults(breakpointCategory, new BreakpointDefaults(suspendPolicy, myConditionCheckbox.isSelected()));
        updateSuspendPolicyRbFont();
        if (DebuggerSettings.SUSPEND_THREAD.equals(suspendPolicy)) {
          myRbSuspendThread.requestFocus();
        }
        else {
          myRbSuspendAll.requestFocus();
        }
        myMakeDefaultButton.setEnabled(false);
      }
    });

    myConditionCombo = new DebuggerExpressionComboBox(project, "LineBreakpoint condition");
    myConditionCombo.addDocumentListener(new DocumentListener() {
      @Override
      public void beforeDocumentChange(DocumentEvent event) {
        myConditionCheckbox.setSelected(true);
      }

      @Override
      public void documentChanged(DocumentEvent event) {

      }
    });

    myConditionCombo.getEditorComponent().addMouseListener(new MouseAdapter() {
      @Override
      public void mouseClicked(MouseEvent event) {
        myConditionCombo.setEnabled(true);
        myConditionCheckbox.setSelected(true);
      }
    });

    if (myCompact) {
      myPanel.addFocusListener(new FocusAdapter() {
        @Override
        public void focusGained(FocusEvent event) {
          DebuggerExpressionComboBox focus;
          if (myLogExpressionCheckBox.isSelected()) {
            focus = myLogExpressionCombo;
          } else {
            focus = myConditionCombo;
          }
          IdeFocusManager.findInstance().requestFocus(focus, true);
        }
      });
    }

    myLogExpressionCombo = new DebuggerExpressionComboBox(project, "LineBreakpoint logMessage");

    myInstanceFiltersField = new FieldPanel(new MyTextField(), "", null,
     new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        reloadInstanceFilters();
        EditInstanceFiltersDialog _dialog = new EditInstanceFiltersDialog(myProject);
        _dialog.setFilters(myInstanceFilters);
        _dialog.show();
        if(_dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
          myInstanceFilters = _dialog.getFilters();
          updateInstanceFilterEditor(true);
        }
      }
    },
     null
    );

    myClassFiltersField = new FieldPanel(new MyTextField(), "", null,
     new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        reloadClassFilters();

        ClassFilter classFilter = createClassConditionFilter();

        EditClassFiltersDialog _dialog = new EditClassFiltersDialog(myProject, classFilter);
        _dialog.setFilters(myClassFilters, myClassExclusionFilters);
        _dialog.show();
        if (_dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
          myClassFilters = _dialog.getFilters();
          myClassExclusionFilters = _dialog.getExclusionFilters();
          updateClassFilterEditor(true);
        }
      }
    },
     null
    );
    ToolTipManager.sharedInstance().registerComponent(myClassFiltersField.getTextField());
    ToolTipManager.sharedInstance().registerComponent(myInstanceFiltersField.getTextField());

    JComponent specialBox = createSpecialBox();
    if(specialBox != null) {
      insert(mySpecialBoxPanel, specialBox);
    } 
    else {
      mySpecialBoxPanel.setVisible(false);
    }

    final JPanel conditionPanel = new JPanel(new BorderLayout());
    conditionPanel.add(myConditionCombo, BorderLayout.CENTER);
    myConditionMagnifierButton = new FixedSizeButton(myConditionCombo);
    conditionPanel.add(myConditionMagnifierButton, BorderLayout.EAST);
    myConditionMagnifierButton.setFocusable(false);
    myConditionMagnifierButton.addActionListener(new MagnifierButtonAction(project, myConditionCombo, "Condition"));

    insert(myConditionComboPanel, conditionPanel);
    insert(myLogExpressionComboPanel, myLogExpressionCombo);

    insert(myInstanceFiltersFieldPanel, myInstanceFiltersField);
    insert(myClassFiltersFieldPanel, myClassFiltersField);

    DebuggerUIUtil.enableEditorOnCheck(myLogExpressionCheckBox, myLogExpressionCombo);
    ActionListener updateListener = new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        updateCheckboxes();
      }
    };

    myPassCountCheckbox.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent event) {
        if (myPassCountCheckbox.isSelected()) {
          myConditionCheckbox.setSelected(false);
        }
        updateCheckboxes();
      }
    });
    myInstanceFiltersCheckBox.addActionListener(updateListener);
    myClassFiltersCheckBox.addActionListener(updateListener);
    myConditionCheckbox.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent event) {
        if (myConditionCheckbox.isSelected()) {
          myPassCountCheckbox.setSelected(false);
        }
        updateCheckboxes();
      }
    });
    DebuggerUIUtil.focusEditorOnCheck(myPassCountCheckbox, myPassCountField);
    DebuggerUIUtil.focusEditorOnCheck(myLogExpressionCheckBox, myLogExpressionCombo);
    DebuggerUIUtil.focusEditorOnCheck(myInstanceFiltersCheckBox, myInstanceFiltersField.getTextField());
    DebuggerUIUtil.focusEditorOnCheck(myClassFiltersCheckBox, myClassFiltersField.getTextField());
    DebuggerUIUtil.focusEditorOnCheck(myConditionCheckbox, myConditionCombo);

    IJSwingUtilities.adjustComponentsOnMac(myCbSuspend);
    IJSwingUtilities.adjustComponentsOnMac(myLogExpressionCheckBox);
    IJSwingUtilities.adjustComponentsOnMac(myLogMessageCheckBox);
    IJSwingUtilities.adjustComponentsOnMac(myTemporaryCheckBox);
    IJSwingUtilities.adjustComponentsOnMac(myEnabledCheckbox);
  }

  private List<BreakpointItem> getBreakpointItemsExceptMy() {
    List<BreakpointItem> items = new ArrayList<BreakpointItem>();
    final DebuggerSupport support = DebuggerSupport.getDebuggerSupport(JavaDebuggerSupport.class);
    support.getBreakpointPanelProvider().provideBreakpointItems(myProject, items);
    for (BreakpointItem item : items) {
      if (item.getBreakpoint() == myBreakpoint) {
        items.remove(item);
        break;
      }
    }
    items.add(new BreakpointNoneItem());
    return items;
  }

  private void saveMasterBreakpoint() {
    Breakpoint masterBreakpoint = (Breakpoint)myMasterBreakpointChooser.getSelectedBreakpoint();
    if (masterBreakpoint == null) {
      getBreakpointManager(myProject).removeBreakpointRule(myBreakpoint);
    }
    else {
      EnableBreakpointRule rule = findMasterBreakpointRule();
      boolean selected = myLeaveEnabledRadioButton.isSelected();
      if (rule != null) {
        if (rule.getMasterBreakpoint() != masterBreakpoint || rule.isLeaveEnabled() != selected) {
          getBreakpointManager(myProject).removeBreakpointRule(rule);
        }
        else {
          return;
        }
      }
      getBreakpointManager(myProject).addBreakpointRule(new EnableBreakpointRule(getBreakpointManager(myProject), masterBreakpoint, myBreakpoint, selected));
    }
  }

  private String getSelectedSuspendPolicy() {
    if (myRbSuspendThread.isSelected()) {
      return DebuggerSettings.SUSPEND_THREAD;
    }
    return DebuggerSettings.SUSPEND_ALL;
  }

  private void updateSuspendPolicyRbFont() {
    final String defPolicy = getBreakpointManager(myProject).getBreakpointDefaults(myBreakpointCategory).getSuspendPolicy();
    
    final Font font = myRbSuspendAll.getFont().deriveFont(Font.PLAIN);
    final Font boldFont = font.deriveFont(Font.BOLD);
    
    myRbSuspendAll.setFont(DebuggerSettings.SUSPEND_ALL.equals(defPolicy)? boldFont : font);
    myRbSuspendThread.setFont(DebuggerSettings.SUSPEND_THREAD.equals(defPolicy)? boldFont : font);
  }

  protected ClassFilter createClassConditionFilter() {
    ClassFilter classFilter;
    if(myBreakpointPsiClass != null) {
      classFilter = new ClassFilter() {
        @Override
        public boolean isAccepted(PsiClass aClass) {
          return myBreakpointPsiClass == aClass || aClass.isInheritor(myBreakpointPsiClass, true);
        }
      };
    }
    else {
      classFilter = null;
    }
    return classFilter;
  }

  protected JComponent createSpecialBox() {
    return null;
  }

  /**
   * Init UI components with the values from Breakpoint
   */
  public void initFrom(Breakpoint breakpoint, boolean moreOptionsVisible1) {
    myBreakpoint = breakpoint;
    boolean moreOptionsVisible = moreOptionsVisible1;
    boolean actionsPanelVisible = moreOptionsVisible1;

    initMasterBreakpointPanel();

    if (breakpoint.COUNT_FILTER > 0) {
      myPassCountField.setText(Integer.toString(breakpoint.COUNT_FILTER));
      moreOptionsVisible = true;
    }
    else {
      myPassCountField.setText("");
    }

    PsiElement context = breakpoint.getEvaluationElement();
    myPassCountCheckbox.setSelected(breakpoint.COUNT_FILTER_ENABLED);

    myConditionCheckbox.setSelected(breakpoint.CONDITION_ENABLED);

    myConditionCombo.setEnabled(breakpoint.CONDITION_ENABLED);

    myConditionCombo.setContext(context);
    myConditionCombo.setText(breakpoint.getCondition() != null ? breakpoint.getCondition() : emptyText());

    myCbSuspend.setSelected(breakpoint.SUSPEND);
    myRbSuspendThread.setEnabled(myCbSuspend.isSelected());
    myRbSuspendAll.setEnabled(myCbSuspend.isSelected());

    if(!breakpoint.SUSPEND) {
      actionsPanelVisible = true;
    }
    if(DebuggerSettings.SUSPEND_THREAD.equals(breakpoint.SUSPEND_POLICY)){
      myRbSuspendThread.setSelected(true);
    }
    else {
      myRbSuspendAll.setSelected(true);
    }

    myCbSuspend.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent event) {
        if (!myActionsPanel.isVisible()) {
          if (!myCbSuspend.isSelected()) {
            if (myDelegate != null) {
              myDelegate.showActionsPanel();
            }
          }
        }
        myRbSuspendThread.setEnabled(myCbSuspend.isSelected());
        myRbSuspendAll.setEnabled(myCbSuspend.isSelected());
      }
    });
    myLogMessageCheckBox.setSelected(breakpoint.LOG_ENABLED);
    myTemporaryCheckBox.setSelected(breakpoint.REMOVE_AFTER_HIT);
    myEnabledCheckbox.setSelected(breakpoint.ENABLED);
    myEnabledCheckbox.setText(breakpoint.getShortName() + " enabled");

    DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().addBreakpointManagerListener(new BreakpointManagerListener() {
      @Override
      public void breakpointsChanged() {
        myEnabledCheckbox.setSelected(myBreakpoint.ENABLED);
      }
    });

    myEnabledCheckbox.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent event) {
        if (myBreakpoint.ENABLED != myEnabledCheckbox.isSelected()) {
          myBreakpoint.ENABLED = myEnabledCheckbox.isSelected();
          getBreakpointManager(myProject).fireBreakpointChanged(myBreakpoint);
          myBreakpoint.updateUI();
        }
      }
    });
    myTemporaryCheckBox.setVisible(breakpoint instanceof LineBreakpoint);
    myLogExpressionCheckBox.setSelected(breakpoint.LOG_EXPRESSION_ENABLED);
    if (breakpoint.LOG_ENABLED || breakpoint.LOG_EXPRESSION_ENABLED || (breakpoint instanceof LineBreakpoint && breakpoint.REMOVE_AFTER_HIT)) {
      actionsPanelVisible = true;
    }

    myLogExpressionCombo.setContext(context);

    if (breakpoint.getLogMessage() != null) {
      myLogExpressionCombo.setText(breakpoint.getLogMessage());
    }
    else {
      myLogExpressionCombo.setText(emptyText());
    }

    myLogExpressionCombo.setEnabled(breakpoint.LOG_EXPRESSION_ENABLED);
    if (breakpoint.LOG_EXPRESSION_ENABLED) {
      actionsPanelVisible = true;
    }

    myInstanceFiltersCheckBox.setSelected(breakpoint.INSTANCE_FILTERS_ENABLED);
    myInstanceFiltersField.setEnabled(breakpoint.INSTANCE_FILTERS_ENABLED);
    myInstanceFiltersField.getTextField().setEditable(breakpoint.INSTANCE_FILTERS_ENABLED);
    myInstanceFilters = breakpoint.getInstanceFilters();
    updateInstanceFilterEditor(true);
    if (breakpoint.INSTANCE_FILTERS_ENABLED) {
      moreOptionsVisible = true;
    }

    myClassFiltersCheckBox.setSelected(breakpoint.CLASS_FILTERS_ENABLED);
    myClassFiltersField.setEnabled(breakpoint.CLASS_FILTERS_ENABLED);
    myClassFiltersField.getTextField().setEditable(breakpoint.CLASS_FILTERS_ENABLED);
    myClassFilters = breakpoint.getClassFilters();
    myClassExclusionFilters = breakpoint.getClassExclusionFilters();
    updateClassFilterEditor(true);
    if (breakpoint.CLASS_FILTERS_ENABLED) {
      moreOptionsVisible = true;
    }

    myBreakpointPsiClass = breakpoint.getPsiClass();

    updateCheckboxes();

    setActionsPanelVisible(actionsPanelVisible && !moreOptionsVisible1);
    setMoreOptionsVisible(moreOptionsVisible);
  }

  private void initMasterBreakpointPanel() {
    final EnableBreakpointRule rule = findMasterBreakpointRule();

    final Breakpoint baseBreakpoint = rule != null ? rule.getMasterBreakpoint() : null;
    updateMasterBreakpointPanel(rule);


    myMasterBreakpointChooser = new BreakpointChooser(myProject, new BreakpointChooser.Delegate() {
      @Override
      public void breakpointChosen(Project project, BreakpointItem item) {
        final boolean enabled = item != null && item.getBreakpoint() != null;
        myLeaveEnabledRadioButton.setEnabled(enabled);
        myDisableAgainRadio.setEnabled(enabled);
        myEnableOrDisableLabel.setEnabled(enabled);

        if (item != null) {

          saveMasterBreakpoint();
        }

        updateMasterBreakpointPanel(findMasterBreakpointRule());

      }
    }, baseBreakpoint, getBreakpointItemsExceptMy());

    insert(myDependentBreakpointComboPanel, myMasterBreakpointChooser.getComponent());

  }

  private @Nullable EnableBreakpointRule findMasterBreakpointRule() {
    return myBreakpoint != null? getBreakpointManager(myProject).findBreakpointRule(myBreakpoint) : null;
  }

  private void updateMasterBreakpointPanel(@Nullable EnableBreakpointRule rule) {
    final boolean leaveEnabled = rule != null && rule.isLeaveEnabled();
    if (leaveEnabled) {
      myLeaveEnabledRadioButton.setSelected(true);
    }
    else {
      myDisableAgainRadio.setSelected(true);
    }
  }

  private static TextWithImportsImpl emptyText() {
    return new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, "");
  }

  /**
   * Save values in the UI components to the breakpoint object
   */
  public void saveTo(Breakpoint breakpoint, @NotNull Runnable afterUpdate) {

    saveMasterBreakpoint();
    try {
      String text = myPassCountField.getText().trim();
      breakpoint.COUNT_FILTER = !text.isEmpty() ? Integer.parseInt(text) : 0;
      if (breakpoint.COUNT_FILTER < 0) {
        breakpoint.COUNT_FILTER = 0;
      }
    }
    catch (Exception ignored) {
    }

    breakpoint.COUNT_FILTER_ENABLED = breakpoint.COUNT_FILTER > 0 && myPassCountCheckbox.isSelected();
    breakpoint.setCondition(myConditionCombo.getText());
    breakpoint.CONDITION_ENABLED = myConditionCheckbox.isSelected();
    breakpoint.setLogMessage(myLogExpressionCombo.getText());
    breakpoint.LOG_EXPRESSION_ENABLED = !breakpoint.getLogMessage().isEmpty() && myLogExpressionCheckBox.isSelected();
    breakpoint.LOG_ENABLED = myLogMessageCheckBox.isSelected();
    breakpoint.ENABLED = myEnabledCheckbox.isSelected();
    breakpoint.REMOVE_AFTER_HIT = myTemporaryCheckBox.isSelected();
    breakpoint.SUSPEND = myCbSuspend.isSelected();
    breakpoint.SUSPEND_POLICY = getSelectedSuspendPolicy();
    reloadInstanceFilters();
    reloadClassFilters();
    updateInstanceFilterEditor(true);
    updateClassFilterEditor(true);

    breakpoint.INSTANCE_FILTERS_ENABLED = myInstanceFiltersField.getText().length() > 0 && myInstanceFiltersCheckBox.isSelected();
    breakpoint.CLASS_FILTERS_ENABLED = myClassFiltersField.getText().length() > 0 && myClassFiltersCheckBox.isSelected();
    breakpoint.setClassFilters(myClassFilters);
    breakpoint.setClassExclusionFilters(myClassExclusionFilters);
    breakpoint.setInstanceFilters(myInstanceFilters);

    myConditionCombo.addRecent(myConditionCombo.getText());
    myLogExpressionCombo.addRecent(myLogExpressionCombo.getText());
    breakpoint.updateUI(afterUpdate);
  }

  private static String concatWithEx(List<String> s, String concator, int N, String NthConcator) {
    String result = "";
    int i = 1;
    for (Iterator iterator = s.iterator(); iterator.hasNext(); i++) {
      String str = (String) iterator.next();
      result += str;
      if(iterator.hasNext()){
        if(i % N == 0){
          result += NthConcator;
        }
        else {
          result += concator;
        }
      }
    }
    return result;
  }

  private void updateInstanceFilterEditor(boolean updateText) {
    List<String> filters = new ArrayList<String>();
    for (InstanceFilter instanceFilter : myInstanceFilters) {
      if (instanceFilter.isEnabled()) {
        filters.add(Long.toString(instanceFilter.getId()));
      }
    }
    if (updateText) {
      myInstanceFiltersField.setText(StringUtil.join(filters, " "));
    }

    String tipText = concatWithEx(filters, " ", (int)Math.sqrt(myInstanceFilters.length) + 1, "\n");
    myInstanceFiltersField.getTextField().setToolTipText(tipText);
  }

  private void reloadInstanceFilters() {
    String filtersText = myInstanceFiltersField.getText();

    ArrayList<InstanceFilter> idxs = new ArrayList<InstanceFilter>();
    int startNumber = -1;
    for(int i = 0; i <= filtersText.length(); i++) {
      if(i < filtersText.length() && Character.isDigit(filtersText.charAt(i))) {
        if(startNumber == -1) {
          startNumber = i;
        }
      }
      else {
        if(startNumber >=0) {
          idxs.add(InstanceFilter.create(filtersText.substring(startNumber, i)));
          startNumber = -1;
        }
      }
    }
    for (InstanceFilter instanceFilter : myInstanceFilters) {
      if (!instanceFilter.isEnabled()) {
        idxs.add(instanceFilter);
      }
    }
    myInstanceFilters = idxs.toArray(new InstanceFilter[idxs.size()]);
  }

  private void updateClassFilterEditor(boolean updateText) {
    List<String> filters = new ArrayList<String>();
    for (com.intellij.ui.classFilter.ClassFilter classFilter : myClassFilters) {
      if (classFilter.isEnabled()) {
        filters.add(classFilter.getPattern());
      }
    }
    List<String> excludeFilters = new ArrayList<String>();
    for (com.intellij.ui.classFilter.ClassFilter classFilter : myClassExclusionFilters) {
      if (classFilter.isEnabled()) {
        excludeFilters.add("-" + classFilter.getPattern());
      }
    }
    if (updateText) {
      String editorText = StringUtil.join(filters, " ");
      if(!filters.isEmpty()) {
        editorText += " ";
      }
      editorText += StringUtil.join(excludeFilters, " ");
      myClassFiltersField.setText(editorText);
    }

    int width = (int)Math.sqrt(myClassExclusionFilters.length + myClassFilters.length) + 1;
    String tipText = concatWithEx(filters, " ", width, "\n");
    if(!filters.isEmpty()) {
      tipText += "\n";
    }
    tipText += concatWithEx(excludeFilters, " ", width, "\n");
    myClassFiltersField.getTextField().setToolTipText(tipText);
  }

  private void reloadClassFilters() {
    String filtersText = myClassFiltersField.getText();

    ArrayList<com.intellij.ui.classFilter.ClassFilter> classFilters     = new ArrayList<com.intellij.ui.classFilter.ClassFilter>();
    ArrayList<com.intellij.ui.classFilter.ClassFilter> exclusionFilters = new ArrayList<com.intellij.ui.classFilter.ClassFilter>();
    int startFilter = -1;
    for(int i = 0; i <= filtersText.length(); i++) {
      if(i < filtersText.length() && !Character.isWhitespace(filtersText.charAt(i))){
        if(startFilter == -1) {
          startFilter = i;
        }
      }
      else {
        if(startFilter >=0) {
          if(filtersText.charAt(startFilter) == '-') {
            exclusionFilters.add(new com.intellij.ui.classFilter.ClassFilter(filtersText.substring(startFilter + 1, i)));
          }
          else {
            classFilters.add(new com.intellij.ui.classFilter.ClassFilter(filtersText.substring(startFilter, i)));
          }
          startFilter = -1;
        }
      }
    }
    for (com.intellij.ui.classFilter.ClassFilter classFilter : myClassFilters) {
      if (!classFilter.isEnabled()) {
        classFilters.add(classFilter);
      }
    }
    for (com.intellij.ui.classFilter.ClassFilter classFilter : myClassExclusionFilters) {
      if (!classFilter.isEnabled()) {
        exclusionFilters.add(classFilter);
      }
    }
    myClassFilters          = classFilters    .toArray(new com.intellij.ui.classFilter.ClassFilter[classFilters    .size()]);
    myClassExclusionFilters = exclusionFilters.toArray(new com.intellij.ui.classFilter.ClassFilter[exclusionFilters.size()]);
  }

  public void setEnabled(boolean enabled) {
    myPanel.setEnabled(enabled);
    Component[] components = myPanel.getComponents();
    for (Component component : components) {
      component.setEnabled(enabled);
    }
  }

  protected void updateCheckboxes() {
    boolean passCountApplicable = true;
    if (myInstanceFiltersCheckBox.isSelected() || myClassFiltersCheckBox.isSelected()) {
      passCountApplicable = false;
    }
    myPassCountCheckbox.setEnabled(passCountApplicable);

    final boolean passCountSelected = myPassCountCheckbox.isSelected();
    myInstanceFiltersCheckBox.setEnabled(!passCountSelected);
    myClassFiltersCheckBox.setEnabled(!passCountSelected);

    myPassCountField.setEditable(myPassCountCheckbox.isSelected());
    myPassCountField.setEnabled (myPassCountCheckbox.isSelected());

    myConditionCombo.setEnabled(myConditionCheckbox.isSelected());
    myConditionMagnifierButton.setEnabled(myConditionCheckbox.isSelected());

    myInstanceFiltersField.setEnabled(myInstanceFiltersCheckBox.isSelected());
    myInstanceFiltersField.getTextField().setEditable(myInstanceFiltersCheckBox.isSelected());

    myClassFiltersField.setEnabled(myClassFiltersCheckBox.isSelected());
    myClassFiltersField.getTextField().setEditable(myClassFiltersCheckBox.isSelected());
  }

  public JPanel getPanel() {
    return myPanel;
  }

  private static BreakpointManager getBreakpointManager(Project project) {
    return DebuggerManagerEx.getInstanceEx(project).getBreakpointManager();
  }

  private static class MagnifierButtonAction implements ActionListener {
    private final Project myProject;
    private final CompletionEditor myTargetEditor;
    private final String myDialogTitle;
    private DebuggerStatementEditor myEditor;

    private MagnifierButtonAction(final Project project, final CompletionEditor targetEditor, final String dialogTitle) {
      myProject = project;
      myTargetEditor = targetEditor;
      myDialogTitle = dialogTitle;
    }

    @Override
    public void actionPerformed(final ActionEvent e) {
      new DialogWrapper(myTargetEditor, true){
        @Override
        public void show() {
          setTitle(myDialogTitle);
          setModal(true);
          init();
          super.show();
        }

        @Override
        public JComponent getPreferredFocusedComponent() {
          return myEditor;
        }

        @Override
        @Nullable
        protected JComponent createCenterPanel() {
          final JPanel panel = new JPanel(new BorderLayout());
          myEditor = new DebuggerStatementEditor(myProject, myTargetEditor.getContext(), myTargetEditor.getRecentsId(), DefaultCodeFragmentFactory.getInstance());
          myEditor.setPreferredSize(new Dimension(400, 150));
          myEditor.setText(myTargetEditor.getText());
          panel.add(myEditor, BorderLayout.CENTER);
          return panel;
        }

        @Override
        protected void doOKAction() {
          myTargetEditor.setText(myEditor.getText());
          super.doOKAction();
        }
      }.show();
    }
  }
}
