/*
 * 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.openapi.options.newEditor;

import com.intellij.AbstractBundle;
import com.intellij.CommonBundle;
import com.intellij.ide.ui.laf.darcula.ui.DarculaTextBorder;
import com.intellij.ide.ui.laf.darcula.ui.DarculaTextFieldUI;
import com.intellij.ide.ui.search.SearchUtil;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.internal.statistic.UsageTrigger;
import com.intellij.internal.statistic.beans.ConvertUsagesUtil;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.AnActionListener;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.*;
import com.intellij.openapi.options.ex.ConfigurableWrapper;
import com.intellij.openapi.options.ex.GlassPanel;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.*;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.EdtRunnable;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.IdeGlassPaneUtil;
import com.intellij.ui.LightColors;
import com.intellij.ui.OnePixelSplitter;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.SearchTextField;
import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.ui.navigation.History;
import com.intellij.ui.navigation.Place;
import com.intellij.ui.treeStructure.SimpleNode;
import com.intellij.ui.treeStructure.filtered.FilteringTreeBuilder;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.update.Activatable;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.UiNotifyConnector;
import com.intellij.util.ui.update.Update;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.*;
import java.util.List;

public class OptionsEditor extends JPanel implements DataProvider, Place.Navigator, Disposable, AWTEventListener {
  public static DataKey<OptionsEditor> KEY = DataKey.create("options.editor");

  private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.options.newEditor.OptionsEditor");

  @NonNls private static final String MAIN_SPLITTER_PROPORTION = "options.splitter.main.proportions";
  @NonNls private static final String DETAILS_SPLITTER_PROPORTION = "options.splitter.details.proportions";

  @NonNls private static final String NOT_A_NEW_COMPONENT = "component.was.already.instantiated";

  private final History myHistory = new History(this);

  private final OptionsTree myTree;
  private final SettingsTreeView myTreeView;
  private final SearchTextField mySearch;
  private final Splitter myMainSplitter;
  //[back/forward] JComponent myToolbarComponent;

  private final DetailsComponent myOwnDetails =
    new DetailsComponent().setEmptyContentText("Select configuration element in the tree to edit its settings");
  private final ContentWrapper myContentWrapper = new ContentWrapper();


  private final Map<Configurable, ConfigurableContent> myConfigurable2Content = new HashMap<Configurable, ConfigurableContent>();
  private final Map<Configurable, ActionCallback> myConfigurable2LoadCallback = new HashMap<Configurable, ActionCallback>();

  private final MergingUpdateQueue myModificationChecker;

  private final SpotlightPainter mySpotlightPainter = new SpotlightPainter();
  private final MergingUpdateQueue mySpotlightUpdate;
  private final LoadingDecorator myLoadingDecorator;
  private final SettingsFilter myFilter;

  private final Wrapper mySearchWrapper = new Wrapper();
  private final JPanel myLeftSide;

  //[back/forward] private ActionToolbar myToolbar;
  private Window myWindow;
  private final PropertiesComponent myProperties;
  private volatile boolean myDisposed;

  private final KeyListener myTreeKeyListener = new KeyListener() {
    @Override
    public void keyPressed(KeyEvent event) {
      keyTyped(event);
    }

    @Override
    public void keyReleased(KeyEvent event) {
      keyTyped(event);
    }

    @Override
    public void keyTyped(KeyEvent event) {
      Object source = event.getSource();
      if (source instanceof JTree) {
        JTree tree = (JTree)source;
        if (tree.getInputMap().get(KeyStroke.getKeyStrokeForEvent(event)) == null) {
          myFilter.myDocumentWasChanged = false;
          try {
            mySearch.keyEventToTextField(event);
          }
          finally {
            if (myFilter.myDocumentWasChanged && !isFilterFieldVisible()) {
              setFilterFieldVisible(true, false, false);
            }
          }
        }
      }
    }
  };

  public OptionsEditor(Project project, ConfigurableGroup[] groups, Configurable preselectedConfigurable) {
    myProperties = PropertiesComponent.getInstance(project);

    mySearch = new MySearchField() {
      @Override
      protected void onTextKeyEvent(final KeyEvent e) {
        if (myTreeView != null) {
          myTreeView.myTree.processKeyEvent(e);
        }
        else {
          myTree.processTextEvent(e);
        }
      }
    };

    myFilter = new SettingsFilter(project, groups, mySearch) {
      @Override
      Configurable getConfigurable(SimpleNode node) {
        if (node instanceof OptionsTree.EditorNode) {
          return ((OptionsTree.EditorNode)node).getConfigurable();
        }
        return SettingsTreeView.getConfigurable(node);
      }

      @Override
      SimpleNode findNode(Configurable configurable) {
        return myTreeView != null
               ? myTreeView.findNode(configurable)
               : myTree.findNodeFor(configurable);
      }

      @Override
      void updateSpotlight(boolean now) {
        if (!now) {
          mySpotlightUpdate.queue(new Update(this) {
            @Override
            public void run() {
              if (!mySpotlightPainter.updateForCurrentConfigurable()) {
                updateSpotlight(false);
              }
            }
          });
        }
        else if (!mySpotlightPainter.updateForCurrentConfigurable()) {
          updateSpotlight(false);
        }
      }
    };

    if (Registry.is("ide.new.settings.dialog")) {
      myTreeView = new SettingsTreeView(myFilter, groups);
      myTreeView.myTree.addKeyListener(myTreeKeyListener);
      myTree = null;
    }
    else {
      myTreeView = null;
      myTree = new OptionsTree(myFilter, groups);
      myTree.addKeyListener(myTreeKeyListener);
    }

    getContext().addColleague(myTreeView != null ? myTreeView : myTree);
    Disposer.register(this, myTreeView != null ? myTreeView : myTree);

    /* [back/forward]
    final DefaultActionGroup toolbarActions = new DefaultActionGroup();
    toolbarActions.add(new BackAction(myTree));
    toolbarActions.add(new ForwardAction(myTree));
    toolbarActions.addSeparator();
    toolbarActions.add(new ShowSearchFieldAction(this));
    myToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, toolbarActions, true);
    myToolbar.setTargetComponent(this);
    myToolbarComponent = myToolbar.getComponent();

    myHistory.addListener(new HistoryListener.Adapter() {
      @Override
      public void navigationFinished(final Place from, final Place to) {
        UIUtil.invokeLaterIfNeeded(new Runnable() {
          public void run() {
            if (myToolbarComponent.isShowing()) {
              myToolbar.updateActionsImmediately();
            }
          }
        });
      }
    }, this);
    */


    myLeftSide = new JPanel(new BorderLayout()) {
      @Override
      public Dimension getMinimumSize() {
        Dimension dimension = super.getMinimumSize();
        JComponent component = myTreeView != null ? myTreeView : myTree;
        dimension.width = Math.max(component.getMinimumSize().width, mySearchWrapper.getPreferredSize().width);
        return dimension;
      }
    };

    /* [back/forward]

    final NonOpaquePanel toolbarPanel = new NonOpaquePanel(new BorderLayout());
    toolbarPanel.add(myToolbarComponent, BorderLayout.WEST);
    toolbarPanel.add(mySearchWrapper, BorderLayout.CENTER);
    */

    myLeftSide.add(mySearchWrapper, BorderLayout.NORTH);
    myLeftSide.add(myTreeView != null ? myTreeView : myTree, BorderLayout.CENTER);

    setLayout(new BorderLayout());

    myMainSplitter = Registry.is("ide.new.settings.dialog") ? new OnePixelSplitter(false) : new Splitter(false);
    myMainSplitter.setFirstComponent(myLeftSide);

    myLoadingDecorator = new LoadingDecorator(myOwnDetails.getComponent(), this, 150);
    myMainSplitter.setSecondComponent(myLoadingDecorator.getComponent());


    myMainSplitter.setProportion(readProportion(0.3f, MAIN_SPLITTER_PROPORTION));
    myContentWrapper.mySplitter.setProportion(readProportion(0.2f, DETAILS_SPLITTER_PROPORTION));

    add(myMainSplitter, BorderLayout.CENTER);

    MyColleague colleague = new MyColleague();
    getContext().addColleague(colleague);

    mySpotlightUpdate = new MergingUpdateQueue("OptionsSpotlight", 200, false, this, this, this);

    if (preselectedConfigurable != null) {
      selectInTree(preselectedConfigurable);
    }
    else {
      if (myTreeView != null) {
        myTreeView.selectFirst();
      }
      else {
        myTree.selectFirst();
      }
    }

    Toolkit.getDefaultToolkit().addAWTEventListener(this,
                                                    AWTEvent.MOUSE_EVENT_MASK | AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);

    ActionManager.getInstance().addAnActionListener(new AnActionListener() {
      @Override
      public void beforeActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) {
      }

      @Override
      public void afterActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) {
        queueModificationCheck();
      }

      @Override
      public void beforeEditorTyping(char c, DataContext dataContext) {
      }
    }, this);

    myModificationChecker = new MergingUpdateQueue("OptionsModificationChecker", 1000, false, this, this, this);

    IdeGlassPaneUtil.installPainter(myOwnDetails.getContentGutter(), mySpotlightPainter, this);

    /*
    String visible = PropertiesComponent.getInstance(myProject).getValue(SEARCH_VISIBLE);
    if (visible == null) {
      visible = "true";
    }
    */

    setFilterFieldVisible(true, false, false);

    new UiNotifyConnector.Once(this, new Activatable() {
      @Override
      public void showNotify() {
        myWindow = SwingUtilities.getWindowAncestor(OptionsEditor.this);
      }

      @Override
      public void hideNotify() {
      }
    });
  }

  private ActionCallback selectInTree(Configurable configurable) {
    return myTreeView != null
           ? myTreeView.select(configurable)
           : myTree.select(configurable);
  }

  /** @see #select(com.intellij.openapi.options.Configurable) */
  @Deprecated
  public ActionCallback select(Class<? extends Configurable> configurableClass) {
    final Configurable configurable = findConfigurable(configurableClass);
    if (configurable == null) {
      return new ActionCallback.Rejected();
    }
    return select(configurable);
  }

  /** @see #findConfigurableById(String) */
  @Deprecated
  @Nullable
  public <T extends Configurable> T findConfigurable(Class<T> configurableClass) {
    return myTreeView != null
           ? myTreeView.findConfigurable(configurableClass)
           : myTree.findConfigurable(configurableClass);
  }

  @Nullable
  public SearchableConfigurable findConfigurableById(@NotNull String configurableId) {
    return myTreeView != null
           ? myTreeView.findConfigurableById(configurableId)
           : myTree.findConfigurableById(configurableId);
  }

  public ActionCallback clearSearchAndSelect(Configurable configurable) {
    clearFilter();
    return select(configurable, "");
  }

  public ActionCallback select(Configurable configurable) {
    if (myFilter.getFilterText().isEmpty()) {
      return select(configurable, "");
    }
    else {
      return myFilter.update(true, true);
    }
  }

  public ActionCallback select(Configurable configurable, final String text) {
    myFilter.update(text, false, true);
    return selectInTree(configurable);
  }

  private float readProportion(final float defaultValue, final String propertyName) {
    float proportion = defaultValue;
    try {
      final String p = myProperties.getValue(propertyName);
      if (p != null) {
        proportion = Float.valueOf(p);
      }
    }
    catch (NumberFormatException e) {
      LOG.debug(e);
    }
    return proportion;
  }

  private ActionCallback processSelected(final Configurable configurable, final Configurable oldConfigurable) {
    if (isShowing(configurable)) return new ActionCallback.Done();

    final ActionCallback result = new ActionCallback();

    if (configurable == null) {
      myOwnDetails.setContent(null);

      myFilter.updateSpotlight(true);
      checkModified(oldConfigurable);

      result.setDone();

    } else {
      getUiFor(configurable).doWhenDone(new EdtRunnable() {
        @Override
        public void runEdt() {
          if (myDisposed) return;

          final Configurable current = getContext().getCurrentConfigurable();
          if (current != configurable) {
            result.setRejected();
            return;
          }

          myHistory.pushQueryPlace();

          updateDetails();

          myOwnDetails.setContent(myContentWrapper);
          myOwnDetails.setBannerMinHeight(mySearchWrapper.getHeight());
          myOwnDetails.setText(getBannerText(configurable));
          if (myTreeView != null) {
            myOwnDetails.forProject(myTreeView.findConfigurableProject(configurable));
          }
          else if (Registry.is("ide.new.settings.dialog")) {
            myOwnDetails.forProject(myTree.getConfigurableProject(configurable));
          }

          final ConfigurableContent content = myConfigurable2Content.get(current);

          content.setText(getBannerText(configurable));
          content.setBannerActions(new Action[] {new ResetAction(configurable)});

          content.updateBannerActions();

          myLoadingDecorator.stopLoading();

          myFilter.updateSpotlight(false);

          checkModified(oldConfigurable);
          checkModified(configurable);

          FilteringTreeBuilder builder = myTreeView != null ? myTreeView.myBuilder : myTree.myBuilder;
          if (builder.getSelectedElements().size() == 0) {
            select(configurable).notify(result);
          } else {
            result.setDone();
          }
        }
      });
    }

    return result;
  }

  private static void assertIsDispatchThread() {
    ApplicationManager.getApplication().assertIsDispatchThread();
  }

  private ActionCallback getUiFor(final Configurable configurable) {
    assertIsDispatchThread();

    if (myDisposed) {
      return new ActionCallback.Rejected();
    }

    final ActionCallback result = new ActionCallback();

    if (!myConfigurable2Content.containsKey(configurable)) {

      final ActionCallback readyCallback = myConfigurable2LoadCallback.get(configurable);
      if (readyCallback != null) {
        return readyCallback;
      }

      myConfigurable2LoadCallback.put(configurable, result);
      myLoadingDecorator.startLoading(false);
      final Application app = ApplicationManager.getApplication();
      Runnable action = new Runnable() {
        @Override
        public void run() {
          app.runReadAction(new Runnable() {
            @Override
            public void run() {
              ((ApplicationEx)app).runEdtSafeAction(new Runnable() {
                @Override
                public void run() {
                  if (myFilter.myProject.isDisposed()) {
                    result.setRejected();
                  }
                  else {
                    initConfigurable(configurable).notifyWhenDone(result);
                  }
                }
              });
            }
          });
        }
      };
      if (app.isUnitTestMode()) {
        action.run();
      }
      else {
        app.executeOnPooledThread(action);
      }
    }
    else {
      result.setDone();
    }

    return result;
  }

  private ActionCallback initConfigurable(@NotNull final Configurable configurable) {
    final ActionCallback result = new ActionCallback();

    final ConfigurableContent content;

    if (configurable instanceof MasterDetails) {
      content = new Details((MasterDetails)configurable);
    }
    else {
      content = new Simple(configurable);
    }

    if (!myConfigurable2Content.containsKey(configurable)) {
      if (configurable instanceof Place.Navigator) {
        ((Place.Navigator)configurable).setHistory(myHistory);
      }
      configurable.reset();
    }

    UIUtil.invokeLaterIfNeeded(new Runnable() {
      @Override
      public void run() {
        if (myDisposed) return;
        myConfigurable2Content.put(configurable, content);
        result.setDone();
      }
    });

    return result;
  }

  private String[] getBannerText(Configurable configurable) {
    if (myTreeView != null) {
      return myTreeView.getPathNames(configurable);
    }
    final List<Configurable> list = myTree.getPathToRoot(configurable);
    final String[] result = new String[list.size()];
    int add = 0;
    for (int i = list.size() - 1; i >=0; i--) {
      result[add++] = list.get(i).getDisplayName().replace('\n', ' ');
    }
    return result;
  }

  private void checkModified(final Configurable configurable) {
    fireModification(configurable);
  }

  private void fireModification(final Configurable actual) {

    Collection<Configurable> toCheck = collectAllParentsAndSiblings(actual);

    for (Configurable configurable : toCheck) {
      fireModificationForItem(configurable);
    }

  }

  private Collection<Configurable> collectAllParentsAndSiblings(final Configurable actual) {
    ArrayList<Configurable> result = new ArrayList<Configurable>();
    Configurable nearestParent = getContext().getParentConfigurable(actual);

    if (nearestParent != null) {
      Configurable parent = nearestParent;
      while (parent != null) {
        result.add(parent);
        parent = getContext().getParentConfigurable(parent);
      }

      result.addAll(getContext().getChildren(nearestParent));
    } else {
      result.add(actual);
    }


    return result;
  }

  private void fireModificationForItem(final Configurable configurable) {
    if (configurable != null) {
      if (!myConfigurable2Content.containsKey(configurable) && isParentWithContent(configurable)) {

        ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
          @Override
          public void run() {
            ApplicationManager.getApplication().runReadAction(new Runnable() {
              @Override
              public void run() {
                if (myDisposed) return;
                initConfigurable(configurable).doWhenDone(new Runnable() {
                  @Override
                  public void run() {
                    if (myDisposed) return;
                    fireModificationInt(configurable);
                  }
                });
              }
            });
          }
        });
      }
      else if (myConfigurable2Content.containsKey(configurable)) {
        fireModificationInt(configurable);
      }
    }
  }

  private static boolean isParentWithContent(final Configurable configurable) {
    return configurable instanceof SearchableConfigurable.Parent &&
        ((SearchableConfigurable.Parent)configurable).hasOwnContent();
  }

  private void fireModificationInt(final Configurable configurable) {
    if (configurable.isModified()) {
      getContext().fireModifiedAdded(configurable, null);
    } else if (!configurable.isModified() && !getContext().getErrors().containsKey(configurable)) {
      getContext().fireModifiedRemoved(configurable, null);
    }
  }

  private void updateDetails() {
    final Configurable current = getContext().getCurrentConfigurable();

    assert current != null;

    final ConfigurableContent content = myConfigurable2Content.get(current);
    content.set(myContentWrapper);
  }

  private boolean isShowing(Configurable configurable) {
    final ConfigurableContent content = myConfigurable2Content.get(configurable);
    return content != null && content.isShowing();
  }

  @Nullable
  public String getHelpTopic() {
    Configurable current = getContext().getCurrentConfigurable();
    while (current != null) {
      String topic = current.getHelpTopic();
      if (topic != null) return topic;
      current = getContext().getParentConfigurable(current);
    }
    return null;
  }

  public boolean isFilterFieldVisible() {
    return mySearch.getParent() == mySearchWrapper;
  }

  public void setFilterFieldVisible(final boolean visible, boolean requestFocus, boolean checkFocus) {
    if (isFilterFieldVisible() && checkFocus && requestFocus && !isSearchFieldFocused()) {
      UIUtil.requestFocus(mySearch);
      return;
    }

    mySearchWrapper.setContent(visible ? mySearch : null);

    myLeftSide.revalidate();
    myLeftSide.repaint();

    if (visible && requestFocus) {
      UIUtil.requestFocus(mySearch);
    }
  }

  public boolean isSearchFieldFocused() {
    return mySearch.getTextEditor().isFocusOwner();
  }

  private class ResetAction extends AbstractAction {
    Configurable myConfigurable;

    ResetAction(final Configurable configurable) {
      myConfigurable = configurable;
      putValue(NAME, "Reset");
      putValue(SHORT_DESCRIPTION, "Rollback changes for this configuration element");
    }

    @Override
    public void actionPerformed(final ActionEvent e) {
      reset(myConfigurable, true);
      checkModified(myConfigurable);
    }

    @Override
    public boolean isEnabled() {
      return myFilter.myContext.isModified(myConfigurable) || getContext().getErrors().containsKey(myConfigurable);
    }
  }

  private static class ContentWrapper extends NonOpaquePanel {

    private final JLabel myErrorLabel;

    private JComponent mySimpleContent;
    private ConfigurationException myException;


    private JComponent myMaster;
    private JComponent myToolbar;
    private DetailsComponent myDetails;

    private final Splitter mySplitter = new Splitter(false);
    private JPanel myLeft = new JPanel(new BorderLayout());
    public float myLastSplitterProportion;

    private ContentWrapper() {
      setLayout(new BorderLayout());
      myErrorLabel = new JLabel();
      myErrorLabel.setOpaque(true);
      myErrorLabel.setBackground(LightColors.RED);

      myLeft = new JPanel(new BorderLayout());

      mySplitter.addPropertyChangeListener(Splitter.PROP_PROPORTION, new PropertyChangeListener() {
        @Override
        public void propertyChange(final PropertyChangeEvent evt) {
          myLastSplitterProportion = ((Float)evt.getNewValue()).floatValue();
        }
      });
    }

    void setContent(JComponent c, ConfigurationException e, boolean scrollable) {
      if (c != null && mySimpleContent == c && myException == e) return;

      removeAll();

      if (c != null) {
        if (scrollable) {
          JScrollPane scroll = ScrollPaneFactory.createScrollPane(c);
          scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
          scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
          scroll.getVerticalScrollBar().setUnitIncrement(10);
          scroll.setBorder(null);
          add(scroll, BorderLayout.CENTER);
        }
        else {
          add(c, BorderLayout.CENTER);
        }
      }

      if (e != null) {
        myErrorLabel.setText(UIUtil.toHtml(e.getMessage()));
        add(myErrorLabel, BorderLayout.NORTH);
      }

      mySimpleContent = c;
      myException = e;

      myMaster = null;
      myToolbar = null;
      myDetails = null;
      mySplitter.setFirstComponent(null);
      mySplitter.setSecondComponent(null);
    }

    void setContent(JComponent master, JComponent toolbar, DetailsComponent details, ConfigurationException e) {
      if (myMaster == master && myToolbar == toolbar && myDetails == details && myException == e) return;

      myMaster = master;
      myToolbar = toolbar;
      myDetails = details;
      myException = e;


      removeAll();
      myLeft.removeAll();

      myLeft.add(myToolbar, BorderLayout.NORTH);
      myLeft.add(myMaster, BorderLayout.CENTER);

      myDetails.setBannerMinHeight(myToolbar.getPreferredSize().height);

      mySplitter.setFirstComponent(myLeft);
      mySplitter.setSecondComponent(myDetails.getComponent());
      mySplitter.setProportion(myLastSplitterProportion);

      add(mySplitter, BorderLayout.CENTER);

      mySimpleContent = null;
    }


    @Override
    public boolean isNull() {
      final boolean superNull = super.isNull();
      if (superNull) return superNull;

      if (myMaster == null) {
        return NullableComponent.Check.isNull(mySimpleContent);
      } else {
        return NullableComponent.Check.isNull(myMaster);
      }
    }
  }

  public void reset(Configurable configurable, boolean notify) {
    configurable.reset();
    if (notify) {
      getContext().fireReset(configurable);
    }
  }

  public void apply() {
    Map<Configurable, ConfigurationException> errors = new LinkedHashMap<Configurable, ConfigurationException>();
    final Set<Configurable> modified = getContext().getModified();
    for (Configurable each : modified) {
      try {
        each.apply();
        UsageTrigger.trigger("ide.settings." + ConvertUsagesUtil.escapeDescriptorName(each.getDisplayName()));
        if (!each.isModified()) {
          getContext().fireModifiedRemoved(each, null);
        }
      }
      catch (ConfigurationException e) {
        errors.put(each, e);
        LOG.debug(e);
      }
    }

    getContext().fireErrorsChanged(errors, null);

    if (!errors.isEmpty()) {
      selectInTree(errors.keySet().iterator().next());
    }
  }


  @Override
  public Object getData(@NonNls final String dataId) {
    if (KEY.is(dataId)) {
      return this;
    }
    return History.KEY.is(dataId) ? myHistory : null;
  }

  public JComponent getPreferredFocusedComponent() {
    return myTreeView != null ? myTreeView.myTree : mySearch;//myTree.getTree();
  }

  @Override
  public Dimension getPreferredSize() {
    return new Dimension(1200, 768);
  }

  @Override
  public ActionCallback navigateTo(@Nullable final Place place, final boolean requestFocus) {
    final Configurable config = (Configurable)place.getPath("configurable");
    final String filter = (String)place.getPath("filter");

    final ActionCallback result = new ActionCallback();

    myFilter.update(filter, false, true).doWhenDone(new Runnable() {
      @Override
      public void run() {
        selectInTree(config).notifyWhenDone(result);
      }
    });

    return result;
  }

  @Override
  public void queryPlace(@NotNull final Place place) {
    final Configurable current = getContext().getCurrentConfigurable();
    place.putPath("configurable", current);
    place.putPath("filter", myFilter.getFilterText());

    if (current instanceof Place.Navigator) {
      ((Place.Navigator)current).queryPlace(place);
    }
  }

  @Override
  public void dispose() {
    assertIsDispatchThread();

    if (myDisposed) {
      return;
    }

    myDisposed = true;

    myProperties.setValue(MAIN_SPLITTER_PROPORTION, String.valueOf(myMainSplitter.getProportion()));
    myProperties.setValue(DETAILS_SPLITTER_PROPORTION, String.valueOf(myContentWrapper.myLastSplitterProportion));

    Toolkit.getDefaultToolkit().removeAWTEventListener(this);


    final Set<Configurable> configurables = new HashSet<Configurable>();
    configurables.addAll(myConfigurable2Content.keySet());
    configurables.addAll(myConfigurable2LoadCallback.keySet());
    for (final Configurable each : configurables) {
      ActionCallback loadCb = myConfigurable2LoadCallback.get(each);
      if (loadCb != null) {
        loadCb.doWhenProcessed(new Runnable() {
          @Override
          public void run() {
            assertIsDispatchThread();
            each.disposeUIResources();
          }
        });
      } else {
        each.disposeUIResources();
      }
    }

    Disposer.clearOwnFields(this);
  }

  public OptionsEditorContext getContext() {
    return myFilter.myContext;
  }

  private class MyColleague extends OptionsEditorColleague.Adapter {
    @Override
    public ActionCallback onSelected(final Configurable configurable, final Configurable oldConfigurable) {
      return processSelected(configurable, oldConfigurable);
    }

    @Override
    public ActionCallback onModifiedRemoved(final Configurable configurable) {
      return updateIfCurrent(configurable);
    }

    @Override
    public ActionCallback onModifiedAdded(final Configurable configurable) {
      return updateIfCurrent(configurable);
    }

    @Override
    public ActionCallback onErrorsChanged() {
      return updateIfCurrent(getContext().getCurrentConfigurable());
    }

    private ActionCallback updateIfCurrent(final Configurable configurable) {
      if (getContext().getCurrentConfigurable() == configurable && configurable != null) {
        updateDetails();
        final ConfigurableContent content = myConfigurable2Content.get(configurable);
        content.updateBannerActions();
        return new ActionCallback.Done();
      } else {
        return new ActionCallback.Rejected();
      }
    }
  }

  public void flushModifications() {
    fireModification(getContext().getCurrentConfigurable());
  }

  public boolean canApply() {
    return !getContext().getModified().isEmpty();
  }

  @Override
  public void eventDispatched(final AWTEvent event) {
    if (event.getID() == MouseEvent.MOUSE_PRESSED || event.getID() == MouseEvent.MOUSE_RELEASED || event.getID() == MouseEvent.MOUSE_DRAGGED) {
      final MouseEvent me = (MouseEvent)event;
      if (SwingUtilities.isDescendingFrom(me.getComponent(), SwingUtilities.getWindowAncestor(myContentWrapper)) || isPopupOverEditor(me.getComponent())) {
        queueModificationCheck();
        myFilter.setHoldingFilter(false);
      }
    }
    else if (event.getID() == KeyEvent.KEY_PRESSED || event.getID() == KeyEvent.KEY_RELEASED) {
      final KeyEvent ke = (KeyEvent)event;
      if (SwingUtilities.isDescendingFrom(ke.getComponent(), myContentWrapper)) {
        queueModificationCheck();
      }
    }
  }

  private void queueModificationCheck() {
    final Configurable configurable = getContext().getCurrentConfigurable();
    myModificationChecker.queue(new Update(this) {
      @Override
      public void run() {
        checkModified(configurable);
      }

      @Override
      public boolean isExpired() {
        return getContext().getCurrentConfigurable() != configurable;
      }
    });
  }

  private boolean isPopupOverEditor(Component c) {
    final Window wnd = SwingUtilities.getWindowAncestor(c);
    return (wnd instanceof JWindow || wnd instanceof JDialog && ((JDialog)wnd).getModalityType() == Dialog.ModalityType.MODELESS) && myWindow != null && wnd.getParent() == myWindow;
  }

  private static class MySearchField extends SearchTextField {

    private boolean myDelegatingNow;

    private MySearchField() {
      super(false);
      addKeyListener(new KeyAdapter() {});
      if (Registry.is("ide.new.settings.dialog")) {
        final JTextField editor = getTextEditor();
        if (!SystemInfo.isMac) {
          editor.putClientProperty("JTextField.variant", "search");
          if (!(editor.getUI() instanceof DarculaTextFieldUI)) {
            editor.setUI((DarculaTextFieldUI)DarculaTextFieldUI.createUI(editor));
            editor.setBorder(new DarculaTextBorder());
          }
        }
        setBackground(UIUtil.getSidePanelColor());
        setBorder(new EmptyBorder(5, 10, 2, 10));
      }
    }

    @Override
    protected boolean isSearchControlUISupported() {
      return true;
    }

    @Override
    protected boolean preprocessEventForTextField(final KeyEvent e) {
      final KeyStroke stroke = KeyStroke.getKeyStrokeForEvent(e);
      if (!myDelegatingNow) {
        if ("pressed ESCAPE".equals(stroke.toString()) && getText().length() > 0) {
          setText(""); // reset filter on ESC
          return true;
        }

        if (getTextEditor().isFocusOwner()) {
          try {
            myDelegatingNow = true;
            boolean treeNavigation =
              stroke.getModifiers() == 0 && (stroke.getKeyCode() == KeyEvent.VK_UP || stroke.getKeyCode() == KeyEvent.VK_DOWN);

            if ("pressed ENTER".equals(stroke.toString())) {
              return true; // avoid closing dialog on ENTER
            }

            final Object action = getTextEditor().getInputMap().get(stroke);
            if (action == null || treeNavigation) {
              onTextKeyEvent(e);
              return true;
            }
          }
          finally {
            myDelegatingNow = false;
          }
        }
      }
      return false;
    }


    protected void onTextKeyEvent(final KeyEvent e) {

    }
  }

  private class SpotlightPainter extends AbstractPainter {
    Map<Configurable, String> myConfigurableToLastOption = new HashMap<Configurable, String>();

    GlassPanel myGP = new GlassPanel(myOwnDetails.getContentGutter());
    boolean myVisible;

    @Override
    public void executePaint(final Component component, final Graphics2D g) {
      if (myVisible && myGP.isVisible()) {
        myGP.paintSpotlight(g, myOwnDetails.getContentGutter());
      }
    }

    public boolean updateForCurrentConfigurable() {
      final Configurable current = getContext().getCurrentConfigurable();

      if (current != null && !myConfigurable2Content.containsKey(current)) {
        return ApplicationManager.getApplication().isUnitTestMode();
      }

      String text = myFilter.getFilterText();

      try {
        final boolean sameText =
          myConfigurableToLastOption.containsKey(current) && text.equals(myConfigurableToLastOption.get(current));


        if (current == null) {
          myVisible = false;
          myGP.clear();
          return true;
        }

        SearchableConfigurable searchable;
        if (current instanceof SearchableConfigurable) {
          searchable = (SearchableConfigurable)current;
        } else {
          searchable = new SearachableWrappper(current);
        }

        myGP.clear();

        final Runnable runnable = SearchUtil.lightOptions(searchable, myContentWrapper, text, myGP);
        if (runnable != null) {
          myVisible = true;//myContext.isHoldingFilter();
          runnable.run();

          boolean pushFilteringFurther = !sameText && !myFilter.contains(current);

          final Runnable ownSearch = searchable.enableSearch(text);
          if (pushFilteringFurther && ownSearch != null) {
            ownSearch.run();
          }
          fireNeedsRepaint(myOwnDetails.getComponent());
        } else {
          myVisible = false;
        }
      }
      finally {
        myConfigurableToLastOption.put(current, text);
      }

      return true;
    }


    @Override
    public boolean needsRepaint() {
      return true;
    }
  }

  private static class SearachableWrappper implements SearchableConfigurable {
    private final Configurable myConfigurable;

    private SearachableWrappper(final Configurable configurable) {
      myConfigurable = configurable;
    }

    @Override
    @NotNull
    public String getId() {
      return myConfigurable.getClass().getName();
    }

    @Override
    public Runnable enableSearch(final String option) {
      return null;
    }

    @Override
    @Nls
    public String getDisplayName() {
      return myConfigurable.getDisplayName();
    }

    @Override
    public String getHelpTopic() {
      return myConfigurable.getHelpTopic();
    }

    @Override
    public JComponent createComponent() {
      return myConfigurable.createComponent();
    }

    @Override
    public boolean isModified() {
      return myConfigurable.isModified();
    }

    @Override
    public void apply() throws ConfigurationException {
      myConfigurable.apply();
    }

    @Override
    public void reset() {
      myConfigurable.reset();
    }

    @Override
    public void disposeUIResources() {
      myConfigurable.disposeUIResources();
    }
  }

  private abstract static class ConfigurableContent {
    abstract void set(ContentWrapper wrapper);

    abstract boolean isShowing();

    abstract void setBannerActions(Action[] actions);

    abstract void updateBannerActions();

    abstract void setText(final String[] bannerText);
  }

  /**
   * Returns default view for the specified configurable.
   * It uses the configurable identifier to retrieve description.
   *
   * @param searchable the configurable that does not have any view
   * @return default view for the specified configurable
   */
  private JComponent createDefaultComponent(SearchableConfigurable searchable) {
    JPanel panel = new JPanel(new BorderLayout(0, 9));
    try {
      panel.add(BorderLayout.NORTH, new JLabel(getDefaultDescription(searchable)));
    }
    catch (AssertionError error) {
      return null; // description is not set
    }
    if (searchable instanceof Configurable.Composite) {
      JPanel box = new JPanel();
      box.setLayout(new BoxLayout(box, BoxLayout.Y_AXIS));
      panel.add(BorderLayout.CENTER, box);

      Configurable.Composite composite = (Configurable.Composite)searchable;
      for (final Configurable configurable : composite.getConfigurables()) {
        LinkLabel label = new LinkLabel(configurable.getDisplayName(), null) {
          @Override
          public void doClick() {
            select(configurable, null);
          }
        };
        label.setBorder(BorderFactory.createEmptyBorder(1, 17, 1, 1));
        box.add(label);
      }
    }
    return panel;
  }

  @NotNull
  private static String getDefaultDescription(SearchableConfigurable configurable) {
    String key = configurable.getId() + ".settings.description";
    if (configurable instanceof ConfigurableWrapper) {
      ConfigurableWrapper wrapper = (ConfigurableWrapper) configurable;
      ConfigurableEP ep = wrapper.getExtensionPoint();
      ResourceBundle resourceBundle = AbstractBundle.getResourceBundle(ep.bundle, ep.getPluginDescriptor().getPluginClassLoader());
      return CommonBundle.message(resourceBundle, key);
    }
    return OptionsBundle.message(key);
  }

  private class Simple extends ConfigurableContent {
    JComponent myComponent;
    Configurable myConfigurable;

    Simple(final Configurable configurable) {
      myConfigurable = configurable;
      myComponent = configurable.createComponent();
      if (myComponent == null && configurable instanceof SearchableConfigurable) {
        myComponent = createDefaultComponent((SearchableConfigurable)configurable);
      }
      if (myComponent != null) {
        final Object clientProperty = myComponent.getClientProperty(NOT_A_NEW_COMPONENT);
        if (clientProperty != null && ApplicationManager.getApplication().isInternal()) {
          LOG.warn("Settings component for " + configurable.getClass()+ " must be created anew, not reused, in createComponent() and destroyed in disposeUIResources()");
        }
        else {
          myComponent.putClientProperty(NOT_A_NEW_COMPONENT, Boolean.TRUE);
        }
      }
    }

    @Override
    void set(final ContentWrapper wrapper) {
      myOwnDetails.setDetailsModeEnabled(true);
      wrapper.setContent(myComponent, getContext().getErrors().get(myConfigurable), !ConfigurableWrapper.isNoScroll(myConfigurable));
    }

    @Override
    boolean isShowing() {
      return myComponent != null && myComponent.isShowing();
    }

    @Override
    void setBannerActions(final Action[] actions) {
      myOwnDetails.setBannerActions(actions);
    }

    @Override
    void updateBannerActions() {
      myOwnDetails.updateBannerActions();
    }

    @Override
    void setText(final String[] bannerText) {
      myOwnDetails.setText(bannerText);
    }
  }

  private class Details extends ConfigurableContent {
    MasterDetails myConfigurable;
    DetailsComponent myDetails;
    JComponent myMaster;
    JComponent myToolbar;

    Details(final MasterDetails configurable) {
      myConfigurable = configurable;
      myConfigurable.initUi();
      myDetails = myConfigurable.getDetails();
      myMaster = myConfigurable.getMaster();
      myToolbar = myConfigurable.getToolbar();
    }

    @Override
    void set(final ContentWrapper wrapper) {
      myOwnDetails.setDetailsModeEnabled(false);
      myDetails.setPrefix(getBannerText((Configurable)myConfigurable));
      wrapper.setContent(myMaster, myToolbar, myDetails, getContext().getErrors().get(myConfigurable));
    }

    @Override
    void setBannerActions(final Action[] actions) {
      myDetails.setBannerActions(actions);
    }

    @Override
    boolean isShowing() {
      return myDetails.getComponent().isShowing();
    }

    @Override
    void updateBannerActions() {
      myDetails.updateBannerActions();
    }

    @Override
    void setText(final String[] bannerText) {
      myDetails.update();
    }
  }

  public void clearFilter() {
    mySearch.setText("");
  }

  @Override
  public void setHistory(final History history) {
  }
}
