/*
 * Copyright 2013-2020 consulo.io
 *
 * 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 consulo.ide.plugins;

import consulo.container.plugin.PluginDescriptor;
import consulo.logging.Logger;
import consulo.platform.base.icon.PlatformIconGroup;
import consulo.ui.image.Image;
import consulo.ui.image.ImageEffects;
import consulo.ui.style.StyleManager;

import javax.annotation.Nonnull;

/**
 * @author VISTALL
 * @since 07/12/2020
 */
public class PluginIconHolder {
  private static final String PLUGIN_ICON_KEY = "PLUGIN_ICON_KEY";

  private static final int ICON_SIZE = 32;

  private static final Logger LOG = Logger.getInstance(PluginIconHolder.class);

  @Nonnull
  public static Image get(@Nonnull PluginDescriptor pluginDescriptor) {
    return pluginDescriptor.computeUserData(PLUGIN_ICON_KEY, s -> ImageEffects.canvas(ICON_SIZE, ICON_SIZE, canvas2D -> {
      // canvas state will dropped on theme change
      Image pluginImage = initializeImage(pluginDescriptor);

      canvas2D.drawImage(pluginImage, 0, 0);
    }));
  }

  public static void put(@Nonnull PluginDescriptor descriptor, @Nonnull Image image) {
    descriptor.computeUserData(PLUGIN_ICON_KEY, s -> decorateIcon(image));
  }

  @Nonnull
  private static Image decorateIcon(@Nonnull Image image) {
    return ImageEffects.resize(image, ICON_SIZE, ICON_SIZE);
  }

  @Nonnull
  private static Image initializeImage(@Nonnull PluginDescriptor pluginDescriptor) {
    byte[] iconBytes = pluginDescriptor.getIconBytes(StyleManager.get().getCurrentStyle().isDark());
    if (iconBytes.length == 0) {
      return decorateIcon(PlatformIconGroup.nodesPluginBig());
    }

    try {
      Image image = Image.fromBytes(Image.ImageType.SVG, iconBytes, ICON_SIZE, ICON_SIZE);
      return decorateIcon(image);
    }
    catch (Throwable e) {
      LOG.warn(e);
    }
    
    return decorateIcon(PlatformIconGroup.nodesPluginBig());
  }
}

@@ -618,16 +618,104 @@
 ugins;%0A%0A
+import com.intellij.openapi.util.NotNullLazyValue;%0Aimport com.intellij.ui.IconDeferrer;%0A
 import c
@@ -980,16 +980,88 @@
 Nonnull;
+%0Aimport java.util.function.Function;%0Aimport java.util.function.Supplier;
 %0A%0A/**%0A *
@@ -1327,16 +1327,169 @@
 lass);%0A%0A
+  private static final Supplier%3CImage%3E ourDecoratedDefaultImage = NotNullLazyValue.createValue(() -%3E decorateIcon(PlatformIconGroup.nodesPluginBig()));%0A%0A
   @Nonnu
@@ -1574,16 +1574,27 @@
  return 
+deferImage(
 pluginDe
@@ -1605,43 +1605,12 @@
 ptor
-.computeUserData(PLUGIN_ICON_KEY, s
+, it
  -%3E 
@@ -1934,73 +1934,410 @@
   de
-scriptor.computeUserData(PLUGIN_ICON_KEY, s -%3E decorateIcon(image
+ferImage(descriptor, it -%3E decorateIcon(image));%0A  %7D%0A%0A  private static Image deferImage(PluginDescriptor pluginDescriptor, Function%3CPluginDescriptor, Image%3E imageFunc) %7B%0A    Image base = ourDecoratedDefaultImage.get();%0A%0A    return pluginDescriptor.computeUserData(PLUGIN_ICON_KEY, s -%3E IconDeferrer.getInstance().defer(base, pluginDescriptor.getPluginId(), pluginId -%3E imageFunc.apply(pluginDescriptor)
 ));%0A
@@ -2970,20 +2970,16 @@
 ;%0A    %7D%0A
-    
 %0A    ret

use icon defer for plugin images, do not load all icon at start