// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.options.colors.pages;

import com.intellij.application.options.colors.ColorSettingsUtil;
import com.intellij.openapi.editor.colors.ColorKey;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.options.colors.*;
import com.intellij.openapi.util.Pair;
import com.intellij.util.containers.ConcurrentFactoryMap;
import com.intellij.util.containers.JBIterable;
import org.jetbrains.annotations.Nullable;

import java.util.Collections;
import java.util.Map;

public class ColorSettingsPagesImpl extends ColorSettingsPages {
  private final Map<Object, Pair<ColorAndFontDescriptorsProvider, ? extends AbstractKeyDescriptor>> myCache =
    ConcurrentFactoryMap.createMap(this::getDescriptorImpl);

  @Override
  public void registerPage(ColorSettingsPage page) {
    ColorSettingsPage.EP_NAME.getPoint(null).registerExtension(page);
  }

  @Override
  public ColorSettingsPage[] getRegisteredPages() {
    return ColorSettingsPage.EP_NAME.getExtensions();
  }

  @Nullable
  @Override
  public Pair<ColorAndFontDescriptorsProvider, AttributesDescriptor> getAttributeDescriptor(TextAttributesKey key) {
    //noinspection unchecked
    return (Pair<ColorAndFontDescriptorsProvider, AttributesDescriptor>)myCache.get(key);
  }

  @Nullable
  @Override
  public Pair<ColorAndFontDescriptorsProvider, ColorDescriptor> getColorDescriptor(ColorKey key) {
    //noinspection unchecked
    return (Pair<ColorAndFontDescriptorsProvider, ColorDescriptor>)myCache.get(key);
  }

  @Nullable
  private Pair<ColorAndFontDescriptorsProvider, ? extends AbstractKeyDescriptor> getDescriptorImpl(Object key) {
    JBIterable<ColorAndFontDescriptorsProvider> providers = JBIterable.empty();
    for (ColorAndFontDescriptorsProvider page : providers.append(getRegisteredPages()).append(ColorAndFontDescriptorsProvider.EP_NAME.getExtensionList())) {
      Iterable<? extends AbstractKeyDescriptor> descriptors =
        key instanceof TextAttributesKey ? ColorSettingsUtil.getAllAttributeDescriptors(page) :
        key instanceof ColorKey ? JBIterable.of(page.getColorDescriptors()) :
        Collections.emptyList();
      for (AbstractKeyDescriptor descriptor : descriptors) {
        if (descriptor.getKey() == key) {
          return Pair.create(page, descriptor);
        }
      }
    }
    return null;
  }
}

@@ -252,16 +252,56 @@
 gsUtil;%0A
+import com.intellij.openapi.Disposable;%0A
 import c
@@ -401,24 +401,93 @@
 ributesKey;%0A
+import com.intellij.openapi.extensions.ExtensionPointChangeListener;%0A
 import com.i
@@ -520,16 +520,59 @@
 lors.*;%0A
+import com.intellij.openapi.util.Disposer;%0A
 import c
@@ -704,24 +704,66 @@
 JBIterable;%0A
+import org.jetbrains.annotations.NotNull;%0A
 import org.j
@@ -910,16 +910,38 @@
 gsPages 
+implements Disposable 
 %7B%0A  priv
@@ -1106,16 +1106,489 @@
 Impl);%0A%0A
+  @NotNull%0A  private final Disposable myListenersDisposable;%0A  %0A  public ColorSettingsPagesImpl() %7B%0A    myListenersDisposable = Disposer.newDisposable();%0A    ExtensionPointChangeListener%3CColorAndFontDescriptorsProvider%3E listener = (e, pd) -%3E %7B%0A      myCache.clear();%0A    %7D;%0A    ColorAndFontDescriptorsProvider.EP_NAME.addExtensionPointListener(listener, myListenersDisposable);%0A    ColorSettingsPage.EP_NAME.addExtensionPointListener(listener, myListenersDisposable);%0A  %7D%0A%0A
   @Overr
@@ -3175,11 +3175,99 @@
 ull;%0A  %7D
+%0A%0A  @Override%0A  public void dispose() %7B%0A    Disposer.dispose(myListenersDisposable);%0A  %7D
 %0A%7D%0A

reset code settings pages cache