/* 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);
     }
  }
  
}
