/* BasicArrowButton.java --
   Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing.plaf.basic;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Polygon;

import javax.swing.ButtonModel;
import javax.swing.JButton;
import javax.swing.SwingConstants;

/**
 * A button that displays an arrow (triangle) that points {@link #NORTH},
 * {@link #SOUTH}, {@link #EAST} or {@link #WEST}.  This button is used by
 * the {@link BasicComboBoxUI} class.
 *
 * @see BasicComboBoxUI#createArrowButton
 */
public class BasicArrowButton extends JButton implements SwingConstants
{

  /**
   * The direction that the arrow points.
   *
   * @see #getDirection()
   */
  protected int direction;

  /**
   * The color the arrow is painted in if disabled and the bottom and right
   * edges of the button.
   * This is package-private to avoid an accessor method.
   */
  transient Color shadow = Color.GRAY;

  /**
   * The color the arrow is painted in if enabled and the bottom and right
   * edges of the button.
   * This is package-private to avoid an accessor method.
   */
  transient Color darkShadow = new Color(102, 102, 102);

  /**
   * The top and left edges of the button.
   * This is package-private to avoid an accessor method.
   */
  transient Color highlight = Color.WHITE;

  /**
   * Creates a new <code>BasicArrowButton</code> object with an arrow pointing
   * in the specified direction.  If the <code>direction</code> is not one of
   * the specified constants, no arrow is drawn.
   *
   * @param direction The direction the arrow points in (one of:
   * {@link #NORTH}, {@link #SOUTH}, {@link #EAST} and {@link #WEST}).
   */
  public BasicArrowButton(int direction)
  {
    super();
    setDirection(direction);
    setFocusable(false);
  }

  /**
   * Creates a new BasicArrowButton object with the given colors and
   * direction.
   *
   * @param direction The direction to point in (one of:
   * {@link #NORTH}, {@link #SOUTH}, {@link #EAST} and {@link #WEST}).
   * @param background The background color.
   * @param shadow The shadow color.
   * @param darkShadow The dark shadow color.
   * @param highlight The highlight color.
   */
  public BasicArrowButton(int direction, Color background, Color shadow,
                          Color darkShadow, Color highlight)
  {
    this(direction);
    setBackground(background);
    this.shadow = shadow;
    this.darkShadow = darkShadow;
    this.highlight = highlight;
    setFocusable(false);
  }

  /**
   * Returns whether the focus can traverse to this component.  This method
   * always returns <code>false</code>.
   *
   * @return <code>false</code>.
   */
  public boolean isFocusTraversable()
  {
    return false;
  }

  /**
   * Returns the direction of the arrow (one of: {@link #NORTH},
   * {@link #SOUTH}, {@link #EAST} and {@link #WEST}).
   *
   * @return The direction of the arrow.
   */
  public int getDirection()
  {
    return direction;
  }

  /**
   * Sets the direction of the arrow.
   *
   * @param dir The new direction of the arrow (one of: {@link #NORTH},
   *            {@link #SOUTH}, {@link #EAST} and {@link #WEST}).
   */
  public void setDirection(int dir)
  {
    this.direction = dir;
  }

  /**
   * Paints the arrow button. The painting is delegated to the
   * paintTriangle method.
   *
   * @param g The Graphics object to paint with.
   */
  public void paint(Graphics g)
  {
    super.paint(g);

    int height = getHeight();
    int size = height / 4;

    int x = (getWidth() - size) / 2;
    int y = (height - size) / 2;

    ButtonModel m = getModel();
    if (m.isArmed())
      {
        x++;
        y++;
      }

    paintTriangle(g, x, y, size, direction, isEnabled());
  }

  /**
   * Returns the preferred size of the arrow button.
   *
   * @return The preferred size (always 16 x 16).
   */
  public Dimension getPreferredSize()
  {
    // since Dimension is NOT immutable, we must return a new instance
    // every time (if we return a cached value, the caller might modify it)
    // - tests show that the reference implementation does the same.
    return new Dimension(16, 16);
  }

  /**
   * Returns the minimum size of the arrow button.
   *
   * @return The minimum size (always 5 x 5).
   */
  public Dimension getMinimumSize()
  {
    // since Dimension is NOT immutable, we must return a new instance
    // every time (if we return a cached value, the caller might modify it)
    // - tests show that the reference implementation does the same.
    return new Dimension(5, 5);
  }

  /**
   * Returns the maximum size of the arrow button.
   *
   * @return The maximum size (always Integer.MAX_VALUE x Integer.MAX_VALUE).
   */
  public Dimension getMaximumSize()
  {
    // since Dimension is NOT immutable, we must return a new instance
    // every time (if we return a cached value, the caller might modify it)
    // - tests show that the reference implementation does the same.
    return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
  }

  /**
   * Paints a triangle with the given size, location and direction.  It is
   * difficult to explain the rationale behind the positioning of the triangle
   * relative to the given (x, y) position - by trial and error we seem to
   * match the behaviour of the reference implementation (which is missing a
   * specification for this method).
   *
   * @param g  the graphics device.
   * @param x  the x-coordinate for the triangle's location.
   * @param y  the y-coordinate for the triangle's location.
   * @param size  the arrow size (depth).
   * @param direction  the direction of the arrow (one of: {@link #NORTH},
   *            {@link #SOUTH}, {@link #EAST} and {@link #WEST}).
   * @param isEnabled  if <code>true</code> the arrow is drawn in the enabled
   *                   state, otherwise it is drawn in the disabled state.
   */
  public void paintTriangle(Graphics g, int x, int y, int size, int direction,
                            boolean isEnabled)
  {
    Color savedColor = g.getColor();
    switch (direction)
      {
      case NORTH:
        paintTriangleNorth(g, x, y, size, isEnabled);
        break;
      case SOUTH:
        paintTriangleSouth(g, x, y, size, isEnabled);
        break;
      case LEFT:
      case WEST:
        paintTriangleWest(g, x, y, size, isEnabled);
        break;
      case RIGHT:
      case EAST:
        paintTriangleEast(g, x, y, size, isEnabled);
        break;
      }
    g.setColor(savedColor);
  }

  /**
   * Paints an upward-pointing triangle.  This method is called by the
   * {@link #paintTriangle(Graphics, int, int, int, int, boolean)} method.
   *
   * @param g  the graphics device.
   * @param x  the x-coordinate for the anchor point.
   * @param y  the y-coordinate for the anchor point.
   * @param size  the arrow size (depth).
   * @param isEnabled  if <code>true</code> the arrow is drawn in the enabled
   *                   state, otherwise it is drawn in the disabled state.
   */
  private void paintTriangleNorth(Graphics g, int x, int y, int size,
          boolean isEnabled)
  {
    int tipX = x + (size - 2) / 2;
    int tipY = y;
    int baseX1 = tipX - (size - 1);
    int baseX2 = tipX + (size - 1);
    int baseY = y + (size - 1);
    Polygon triangle = new Polygon();
    triangle.addPoint(tipX, tipY);
    triangle.addPoint(baseX1, baseY);
    triangle.addPoint(baseX2, baseY);
    if (isEnabled)
     {
       g.setColor(Color.DARK_GRAY);
       g.fillPolygon(triangle);
       g.drawPolygon(triangle);
     }
    else
     {
       g.setColor(Color.GRAY);
       g.fillPolygon(triangle);
       g.drawPolygon(triangle);
       g.setColor(Color.WHITE);
       g.drawLine(baseX1 + 1, baseY + 1, baseX2 + 1, baseY + 1);
     }
  }

  /**
   * Paints an downward-pointing triangle.  This method is called by the
   * {@link #paintTriangle(Graphics, int, int, int, int, boolean)} method.
   *
   * @param g  the graphics device.
   * @param x  the x-coordinate for the anchor point.
   * @param y  the y-coordinate for the anchor point.
   * @param size  the arrow size (depth).
   * @param isEnabled  if <code>true</code> the arrow is drawn in the enabled
   *                   state, otherwise it is drawn in the disabled state.
   */
  private void paintTriangleSouth(Graphics g, int x, int y, int size,
          boolean isEnabled)
  {
    int tipX = x + (size - 2) / 2;
    int tipY = y + (size - 1);
    int baseX1 = tipX - (size - 1);
    int baseX2 = tipX + (size - 1);
    int baseY = y;
    Polygon triangle = new Polygon();
    triangle.addPoint(tipX, tipY);
    triangle.addPoint(baseX1, baseY);
    triangle.addPoint(baseX2, baseY);
    if (isEnabled)
     {
       g.setColor(Color.DARK_GRAY);
       g.fillPolygon(triangle);
       g.drawPolygon(triangle);
     }
    else
     {
       g.setColor(Color.GRAY);
       g.fillPolygon(triangle);
       g.drawPolygon(triangle);
       g.setColor(Color.WHITE);
       g.drawLine(tipX + 1, tipY, baseX2, baseY + 1);
       g.drawLine(tipX + 1, tipY + 1, baseX2 + 1, baseY + 1);
     }
  }

  /**
   * Paints a right-pointing triangle.  This method is called by the
   * {@link #paintTriangle(Graphics, int, int, int, int, boolean)} method.
   *
   * @param g  the graphics device.
   * @param x  the x-coordinate for the anchor point.
   * @param y  the y-coordinate for the anchor point.
   * @param size  the arrow size (depth).
   * @param isEnabled  if <code>true</code> the arrow is drawn in the enabled
   *                   state, otherwise it is drawn in the disabled state.
   */
  private void paintTriangleEast(Graphics g, int x, int y, int size,
          boolean isEnabled)
  {
    int tipX = x + (size - 1);
    int tipY = y + (size - 2) / 2;
    int baseX = x;
    int baseY1 = tipY - (size - 1);
    int baseY2 = tipY + (size - 1);

    Polygon triangle = new Polygon();
    triangle.addPoint(tipX, tipY);
    triangle.addPoint(baseX, baseY1);
    triangle.addPoint(baseX, baseY2);
    if (isEnabled)
     {
       g.setColor(Color.DARK_GRAY);
       g.fillPolygon(triangle);
       g.drawPolygon(triangle);
     }
    else
     {
       g.setColor(Color.GRAY);
       g.fillPolygon(triangle);
       g.drawPolygon(triangle);
       g.setColor(Color.WHITE);
       g.drawLine(baseX + 1, baseY2, tipX, tipY + 1);
       g.drawLine(baseX + 1, baseY2 + 1, tipX + 1, tipY + 1);
     }
  }

  /**
   * Paints a left-pointing triangle.  This method is called by the
   * {@link #paintTriangle(Graphics, int, int, int, int, boolean)} method.
   *
   * @param g  the graphics device.
   * @param x  the x-coordinate for the anchor point.
   * @param y  the y-coordinate for the anchor point.
   * @param size  the arrow size (depth).
   * @param isEnabled  if <code>true</code> the arrow is drawn in the enabled
   *                   state, otherwise it is drawn in the disabled state.
   */
  private void paintTriangleWest(Graphics g, int x, int y, int size,
          boolean isEnabled)
  {
    int tipX = x;
    int tipY = y + (size - 2) / 2;
    int baseX = x + (size - 1);
    int baseY1 = tipY - (size - 1);
    int baseY2 = tipY + (size - 1);

    Polygon triangle = new Polygon();
    triangle.addPoint(tipX, tipY);
    triangle.addPoint(baseX, baseY1);
    triangle.addPoint(baseX, baseY2);
    if (isEnabled)
     {
       g.setColor(Color.DARK_GRAY);
       g.fillPolygon(triangle);
       g.drawPolygon(triangle);
     }
    else
     {
       g.setColor(Color.GRAY);
       g.fillPolygon(triangle);
       g.drawPolygon(triangle);
       g.setColor(Color.WHITE);
       g.drawLine(baseX + 1, baseY1 + 1, baseX + 1, baseY2 + 1);
     }
  }

}
