/*
 * 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 com.intellij.util.ui;

import com.intellij.icons.AllIcons;
import com.intellij.openapi.util.IconLoader;
import com.intellij.ui.LayeredIcon;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.*;

public class AsyncProcessIcon extends AnimatedIcon {
  public static final int COUNT = 12;
  public static final int CYCLE_LENGTH = 800;

  private static final Icon[] SMALL_ICONS = findIcons("/process/step_", "/process/step_mask.png");
  private boolean myUseMask;

  public AsyncProcessIcon(@NonNls String name) {
    this(name, SMALL_ICONS, AllIcons.Process.Step_passive);
  }

  public AsyncProcessIcon(@NonNls String name, Icon[] icons, Icon passive) {
    super(name, icons, passive, CYCLE_LENGTH);
    setUseMask(false);
  }

  public AsyncProcessIcon setUseMask(boolean useMask) {
    myUseMask = useMask;
    return this;
  }

  @Override
  protected void paintIcon(Graphics g, Icon icon, int x, int y) {
    if (icon instanceof ProcessIcon) {
      ((ProcessIcon)icon).setLayerEnabled(0, myUseMask);
    }
    super.paintIcon(g, icon, x, y);

    if (icon instanceof ProcessIcon) {
      ((ProcessIcon)icon).setLayerEnabled(0, false);
    }
  }

  private static Icon[] findIcons(String prefix, String maskIconPath) {
    Icon maskIcon = maskIconPath != null ? IconLoader.getIcon(maskIconPath) : null;
    Icon[] icons = new Icon[COUNT];
    for (int i = 0; i <= COUNT - 1; i++) {
      Icon eachIcon = IconLoader.getIcon(prefix + (i + 1) + ".png");
      if (maskIcon != null) {
        icons[i] = new ProcessIcon(maskIcon, eachIcon);
      } else {
        icons[i] = eachIcon;
      }
    }
    return icons;
  }

  public void updateLocation(final JComponent container) {
    final Rectangle newBounds = calculateBounds(container);
    if (!newBounds.equals(getBounds())) {
      setBounds(newBounds);
      // painting problems with scrollpane
      // repaint shouldn't be called from paint method
      SwingUtilities.invokeLater(() -> container.repaint());
    }
  }

  @NotNull
  protected Rectangle calculateBounds(@NotNull JComponent container) {
    Rectangle rec = container.getVisibleRect();
    Dimension iconSize = getPreferredSize();
    return new Rectangle(rec.x + rec.width - iconSize.width, rec.y, iconSize.width, iconSize.height);
  }

  private static class ProcessIcon extends LayeredIcon {
    private ProcessIcon(Icon mask, Icon stepIcon) {
      super(mask, stepIcon);
    }
  }

  public static class Big extends AsyncProcessIcon {
    private static final Icon[] BIG_ICONS = {
            AllIcons.Process.Big.Step_1,
            AllIcons.Process.Big.Step_2,
            AllIcons.Process.Big.Step_3,
            AllIcons.Process.Big.Step_4,
            AllIcons.Process.Big.Step_5,
            AllIcons.Process.Big.Step_6,
            AllIcons.Process.Big.Step_7,
            AllIcons.Process.Big.Step_8,
            AllIcons.Process.Big.Step_9,
            AllIcons.Process.Big.Step_10,
            AllIcons.Process.Big.Step_11,
            AllIcons.Process.Big.Step_12
    };

    public Big(@NonNls final String name) {
      super(name, BIG_ICONS, AllIcons.Process.Big.Step_passive);
    }
  }

  public boolean isDisposed() {
    return myAnimator.isDisposed();
  }
}

@@ -666,53 +666,8 @@
 ns;%0A
-import com.intellij.openapi.util.IconLoader;%0A
 impo
@@ -698,16 +698,16 @@
 edIcon;%0A
+
 import o
@@ -881,46 +881,8 @@
 n %7B%0A
-  public static final int COUNT = 12;%0A
   pu
@@ -958,22 +958,16 @@
 n%5B%5D 
-SMALL_
 ICONS = 
 find
@@ -966,63 +966,708 @@
 S = 
-findIcons(%22/process/step_%22, %22/process/step_mask.png%22)
+%7B%0A          AllIcons.Process.FS.Step_1,%0A          AllIcons.Process.FS.Step_2,%0A          AllIcons.Process.FS.Step_3,%0A          AllIcons.Process.FS.Step_4,%0A          AllIcons.Process.FS.Step_5,%0A          AllIcons.Process.FS.Step_6,%0A          AllIcons.Process.FS.Step_7,%0A          AllIcons.Process.FS.Step_8,%0A          AllIcons.Process.FS.Step_9,%0A          AllIcons.Process.FS.Step_10,%0A          AllIcons.Process.FS.Step_11,%0A          AllIcons.Process.FS.Step_12,%0A          AllIcons.Process.FS.Step_13,%0A          AllIcons.Process.FS.Step_14,%0A          AllIcons.Process.FS.Step_15,%0A          AllIcons.Process.FS.Step_16,%0A          AllIcons.Process.FS.Step_17,%0A          AllIcons.Process.FS.Step_18%0A  %7D
 ;%0A
+%0A
   pr
@@ -1760,14 +1760,8 @@
 me, 
-SMALL_
 ICON
@@ -1780,16 +1780,19 @@
 Process.
+FS.
 Step_pas
@@ -2382,479 +2382,8 @@
  %7D%0A%0A
-  private static Icon%5B%5D findIcons(String prefix, String maskIconPath) %7B%0A    Icon maskIcon = maskIconPath != null ? IconLoader.getIcon(maskIconPath) : null;%0A    Icon%5B%5D icons = new Icon%5BCOUNT%5D;%0A    for (int i = 0; i %3C= COUNT - 1; i++) %7B%0A      Icon eachIcon = IconLoader.getIcon(prefix + (i + 1) + %22.png%22);%0A      if (maskIcon != null) %7B%0A        icons%5Bi%5D = new ProcessIcon(maskIcon, eachIcon);%0A      %7D else %7B%0A        icons%5Bi%5D = eachIcon;%0A      %7D%0A    %7D%0A    return icons;%0A  %7D%0A%0A
   pu
@@ -2702,14 +2702,8 @@
 ter(
-() -%3E 
 cont
@@ -2711,18 +2711,17 @@
 iner
-.
+::
 repaint
-()
 );%0A 

change icons