/*
 * Copyright 2000-2011 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.ui;

import com.intellij.openapi.actionSystem.*;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;
import java.util.HashSet;
import java.util.Set;

/**
 * @author Konstantin Bulenkov
 */
public abstract class AnActionButton extends AnAction implements ShortcutProvider {
  private boolean myEnabled = true;
  private boolean myVisible = true;
  private ShortcutSet myShortcut;
  private AnAction myAction = null;
  private JComponent myContextComponent;
  private Set<AnActionButtonUpdater> myUpdaters;

  public AnActionButton(String text) {
    super(text);
  }

  public AnActionButton(String text, String description, @Nullable Icon icon) {
    super(text, description, icon);
  }

  @SuppressWarnings("NullableProblems")
  public AnActionButton(String text, Icon icon) {
    this(text, null, icon);
  }

  public AnActionButton() {
  }
  
  public static AnActionButton fromAction(final AnAction action) {
    final Presentation presentation = action.getTemplatePresentation();
    return new AnActionButton(presentation.getText(),
                                                     presentation.getDescription(),
                                                     presentation.getIcon()) {

      @Override
      public void actionPerformed(AnActionEvent e) {
        action.actionPerformed(e);
      }

      @Override
      public void updateButton(AnActionEvent e) {
        action.update(e);
        final boolean enabled = e.getPresentation().isEnabled();
        final boolean visible = e.getPresentation().isVisible();
        if (enabled && visible) {
          super.updateButton(e);
        }
      }
    };
  }

  public boolean isEnabled() {
    return myEnabled;
  }

  public void setEnabled(boolean enabled) {
    myEnabled = enabled;
  }

  public boolean isVisible() {
    return myVisible;
  }

  public void setVisible(boolean visible) {
    myVisible = visible;
  }

  @Override
  public final void update(AnActionEvent e) {
    boolean myActionVisible = true;
    boolean myActionEnabled = true;
    if (myAction != null) {      
      myAction.update(e);
      myActionEnabled = e.getPresentation().isEnabled();
      myActionVisible = e.getPresentation().isVisible();
    }
    boolean enabled = isEnabled() && isContextComponentOk() && myActionEnabled;
    if (enabled) {
      for (AnActionButtonUpdater updater : myUpdaters) {
        if (!updater.isEnabled(e)) {
          enabled = false;
          break;
        }
      }
    }
    e.getPresentation().setEnabled(enabled);
    e.getPresentation().setVisible(isVisible() && myActionVisible);

    if (enabled) {
      updateButton(e);
    }
  }
  
  public final void addCustomUpdater(@NotNull AnActionButtonUpdater updater) {
    if (myUpdaters == null) {
      myUpdaters = new HashSet<AnActionButtonUpdater>();
    }
    myUpdaters.add(updater);
  }

  public void updateButton(AnActionEvent e) {
  }

  @Override
  public ShortcutSet getShortcut() {
    return myShortcut;
  }

  public void setShortcut(ShortcutSet shortcut) {
    myShortcut = shortcut;
  }

  public void setContextComponent(JComponent contextComponent) {
    myContextComponent = contextComponent;
  }

  public JComponent getContextComponent() {
    return myContextComponent;
  }

  private boolean isContextComponentOk() {
    return myContextComponent == null
           || (myContextComponent.isVisible() && UIUtil.getParentOfType(JLayeredPane.class, myContextComponent) != null);
  }

  public final RelativePoint getPreferredPopupPoint() {
    Container c = myContextComponent;
    ActionToolbar toolbar = null;
    while ((c = c.getParent()) != null) {
      if (c instanceof JComponent
          && (toolbar = (ActionToolbar)((JComponent)c).getClientProperty(ActionToolbar.ACTION_TOOLBAR_PROPERTY_KEY)) != null) {
        break;
      }
    }
    if (toolbar instanceof JComponent) {
      for (Component comp : ((JComponent)toolbar).getComponents()) {
        if (comp instanceof ActionButtonComponent) {
          if (comp instanceof AnActionHolder) {
            if (((AnActionHolder)comp).getAction() == this) {
              return new RelativePoint(comp.getParent(), new Point(comp.getX(), comp.getY() + comp.getHeight()));
            }
          }
        }
      }
    }
    return null;
  }
}

@@ -3064,32 +3064,54 @@
 %0A    if (enabled
+ && myUpdaters != null
 ) %7B%0A      for (A

fix test line markers