/*
 * Copyright 2000-2012 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.ide.ui.laf.darcula.ui;

import com.intellij.openapi.ui.GraphicsConfig;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
import org.intellij.lang.annotations.MagicConstant;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicArrowButton;
import javax.swing.plaf.basic.BasicSpinnerUI;
import java.awt.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;

/**
 * @author Konstantin Bulenkov
 */
public class DarculaSpinnerUI extends BasicSpinnerUI {
  private FocusAdapter myFocusListener = new FocusAdapter() {
    @Override
    public void focusGained(FocusEvent e) {
      spinner.repaint();
    }

    @Override
    public void focusLost(FocusEvent e) {
      spinner.repaint();
    }
  };

  @SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
  public static ComponentUI createUI(JComponent c) {
    return new DarculaSpinnerUI();
  }

  @Override
  protected void replaceEditor(JComponent oldEditor, JComponent newEditor) {
    super.replaceEditor(oldEditor, newEditor);
    if (oldEditor != null) {
      oldEditor.getComponents()[0].removeFocusListener(myFocusListener);
    }
    if (newEditor != null) {
      newEditor.getComponents()[0].addFocusListener(myFocusListener);
    }
  }

  @Override
  protected JComponent createEditor() {
    final JComponent editor = super.createEditor();
    editor.getComponents()[0].addFocusListener(myFocusListener);
    return editor;
  }

  @Override
  public void paint(Graphics g, JComponent c) {
    super.paint(g, c);
    final Border border = spinner.getBorder();
    if (border != null) {
      border.paintBorder(c, g, 0, 0, spinner.getWidth(), spinner.getHeight());
    }
  }

  @Override
  protected Component createPreviousButton() {
    JButton button = createArrow(SwingConstants.SOUTH);
    button.setName("Spinner.previousButton");
    button.setBorder(new EmptyBorder(1, 1, 1, 1));
    installPreviousButtonListeners(button);
    return button;
  }

  @Override
  protected Component createNextButton() {
    JButton button = createArrow(SwingConstants.NORTH);
    button.setName("Spinner.nextButton");
    button.setBorder(new EmptyBorder(1, 1, 1, 1));
    installNextButtonListeners(button);
    return button;
  }


  @Override
  protected LayoutManager createLayout() {
    return new LayoutManagerDelegate(super.createLayout()) {
      @Override
      public void layoutContainer(Container parent) {
        super.layoutContainer(parent);
        final JComponent editor = spinner.getEditor();
        if (editor != null) {
          final Rectangle bounds = editor.getBounds();
          editor.setBounds(bounds.x, bounds.y, bounds.width - 6, bounds.height);
        }
      }
    };
  }

  private JButton createArrow(@MagicConstant(intValues = {SwingConstants.NORTH, SwingConstants.SOUTH}) int direction) {
    final Color shadow = UIUtil.getPanelBackground();
    final Color darkShadow = UIUtil.getLabelForeground();
    JButton b = new BasicArrowButton(direction, shadow, shadow, darkShadow, shadow) {
      @Override
      public void paint(Graphics g) {
        int y = direction == NORTH ? getHeight() - 6 : 2;
        paintTriangle(g, 0, y, 0, direction, DarculaSpinnerUI.this.spinner.isEnabled());
      }

      @Override
      public boolean isOpaque() {
        return false;
      }

      @Override
      public void paintTriangle(Graphics g, int x, int y, int size, int direction, boolean isEnabled) {
        final GraphicsConfig config = GraphicsUtil.setupAAPainting(g);
        int mid;
        final int w = 8;
        final int h = 6;
        mid = w  / 2;

        g.setColor(isEnabled ? darkShadow : darkShadow.darker());

        g.translate(x, y);
        switch (direction) {
          case SOUTH:
            g.fillPolygon(new int[]{0, w, mid}, new int[]{1, 1, h}, 3);
            break;
          case NORTH:
            g.fillPolygon(new int[]{0, w, mid}, new int[]{h - 1, h - 1, 0}, 3);
            break;
          case WEST:
          case EAST:
        }
        g.translate(-x, -y);
        config.restore();
      }
    };
    Border buttonBorder = UIManager.getBorder("Spinner.arrowButtonBorder");
    if (buttonBorder instanceof UIResource) {
      // Wrap the border to avoid having the UIResource be replaced by
      // the ButtonUI. This is the opposite of using BorderUIResource.
      b.setBorder(new CompoundBorder(buttonBorder, null));
    }
    else {
      b.setBorder(buttonBorder);
    }
    b.setInheritsPopupMenu(true);
    return b;
  }

  static class LayoutManagerDelegate implements LayoutManager {
    protected final LayoutManager myDelegate;

    LayoutManagerDelegate(LayoutManager delegate) {
      myDelegate = delegate;
    }

    @Override
    public void addLayoutComponent(String name, Component comp) {
      myDelegate.addLayoutComponent(name, comp);
    }

    @Override
    public void removeLayoutComponent(Component comp) {
      myDelegate.removeLayoutComponent(comp);
    }

    @Override
    public Dimension preferredLayoutSize(Container parent) {
      return myDelegate.preferredLayoutSize(parent);
    }

    @Override
    public Dimension minimumLayoutSize(Container parent) {
      return myDelegate.minimumLayoutSize(parent);
    }

    @Override
    public void layoutContainer(Container parent) {
      myDelegate.layoutContainer(parent);
    }
  }
}

@@ -17,17 +17,17 @@
 2000-201
-2
+3
  JetBrai
@@ -686,16 +686,77 @@
 Config;%0A
+import com.intellij.ui.Gray;%0Aimport com.intellij.ui.JBColor;%0A
 import c
@@ -3802,20 +3802,130 @@
 lor 
-darkShadow =
+enabledColor = new JBColor(Gray._255, UIUtil.getLabelForeground());%0A    final Color disabledColor = new JBColor(Gray._200,
  UIU
@@ -3944,24 +3944,34 @@
 Foreground()
+.darker())
 ;%0A    JButto
@@ -4024,26 +4024,28 @@
 shadow, 
-darkShadow
+enabledColor
 , shadow
@@ -4185,17 +4185,38 @@
 ngle(g, 
-0
+(getWidth() - 8)/2 - 1
 , y, 0, 
@@ -4676,40 +4676,36 @@
 d ? 
-darkShadow : darkShadow.darker()
+enabledColor : disabledColor
 );%0A%0A

arrows should be centered