/* BasicButtonUI.java --
   Copyright (C) 2002, 2004, 2005  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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;

import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.plaf.ButtonUI;
import javax.swing.plaf.ComponentUI;

public class BasicButtonUI extends ButtonUI
{
  /**
   * A constant used to pad out elements in the button's layout and
   * preferred size calculations.
   */
  protected int defaultTextIconGap = 4;

  /**
   * A constant added to the defaultTextIconGap to adjust the text
   * within this particular button.
   */
  protected int defaultTextShiftOffset = 0;

  private int textShiftOffset;

  private Color focusColor;

  /**
   * Factory method to create an instance of BasicButtonUI for a given
   * {@link JComponent}, which should be an {@link AbstractButton}.
   *
   * @param c The component to create a UI got
   *
   * @return A new UI capable of drawing the component
   */
  public static ComponentUI createUI(final JComponent c) 
  {
    return new BasicButtonUI();
  }

  public int getDefaultTextIconGap(AbstractButton b)
  {
    return defaultTextIconGap;
  }

  protected void clearTextShiftOffset()
  {
    textShiftOffset = 0;
  }
  
  protected int getTextShiftOffset()
  {
    return textShiftOffset;
  }

  protected void setTextShiftOffset()
  {
    textShiftOffset = defaultTextShiftOffset;
  }

  protected void installDefaults(AbstractButton b)
  {
    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
    focusColor = defaults.getColor("Button.focus");
    b.setForeground(defaults.getColor("Button.foreground"));
    b.setBackground(defaults.getColor("Button.background"));
    b.setMargin(defaults.getInsets("Button.margin"));
    b.setBorder(defaults.getBorder("Button.border"));
    b.setIconTextGap(defaults.getInt("Button.textIconGap"));
    b.setInputMap(JComponent.WHEN_FOCUSED, 
                  (InputMap) defaults.get("Button.focusInputMap"));
    b.setOpaque(true);
  }

  protected void uninstallDefaults(AbstractButton b)
  {
    b.setForeground(null);
    b.setBackground(null);
    b.setBorder(null);
    b.setIconTextGap(defaultTextIconGap);
    b.setMargin(null);
  }

  protected BasicButtonListener listener;

  protected BasicButtonListener createButtonListener(AbstractButton b)
  {
    return new BasicButtonListener(b);
  }

  protected void installListeners(AbstractButton b)
  {
    listener = createButtonListener(b);
    b.addChangeListener(listener);
    b.addPropertyChangeListener(listener);
    b.addFocusListener(listener);    
    b.addMouseListener(listener);
    b.addMouseMotionListener(listener);
  }

  protected void uninstallListeners(AbstractButton b)
  {
    b.removeChangeListener(listener);
    b.removePropertyChangeListener(listener);
    b.removeFocusListener(listener);    
    b.removeMouseListener(listener);
    b.removeMouseMotionListener(listener);
  }

  protected void installKeyboardActions(AbstractButton b)
  {
    listener.installKeyboardActions(b);
  }

  protected void uninstallKeyboardActions(AbstractButton b)
  {
    listener.uninstallKeyboardActions(b);
  }

  /**
   * Install the BasicButtonUI as the UI for a particular component.
   * This means registering all the UI's listeners with the component,
   * and setting any properties of the button which are particular to 
   * this look and feel.
   *
   * @param c The component to install the UI into
   */
  public void installUI(final JComponent c) 
  {
    super.installUI(c);
    if (c instanceof AbstractButton)
      {
        AbstractButton b = (AbstractButton) c;
        installDefaults(b);
        installListeners(b);
        installKeyboardActions(b);
      }
  }

  /**
   * Calculate the preferred size of this component, by delegating to
   * {@link BasicGraphicsUtils.getPreferredButtonSize}.
   *
   * @param c The component to measure
   *
   * @return The preferred dimensions of the component
   */
  public Dimension getPreferredSize(JComponent c) 
  {
    AbstractButton b = (AbstractButton)c;
    Dimension d = 
      BasicGraphicsUtils.getPreferredButtonSize
      (b, defaultTextIconGap + defaultTextShiftOffset);
    return d;
  }

  private static Icon currentIcon(AbstractButton b)
  {
    Icon i = b.getIcon();
    ButtonModel model = b.getModel();

    if (model.isPressed() && b.getPressedIcon() != null)
      i = b.getPressedIcon();

    else if (model.isRollover())
      {
        if (b.isSelected() && b.getRolloverSelectedIcon() != null)
          i = b.getRolloverSelectedIcon();
        else if (b.getRolloverIcon() != null)
          i = b.getRolloverIcon();
      }    

    else if (b.isSelected())
      {
        if (b.isEnabled() && b.getSelectedIcon() != null)
          i = b.getSelectedIcon();
        else if (b.getDisabledSelectedIcon() != null)
          i = b.getDisabledSelectedIcon();
      }

    else if (! b.isEnabled() && b.getDisabledIcon() != null)
      i = b.getDisabledIcon();

    return i;
  }

  /**
   * Paint the component, which is an {@link AbstractButton}, according to 
   * its current state.
   *
   * @param g The graphics context to paint with
   * @param c The component to paint the state of
   */
  public void paint(Graphics g, JComponent c)
  {      
    AbstractButton b = (AbstractButton) c;

    Rectangle tr = new Rectangle();
    Rectangle ir = new Rectangle();
    Rectangle vr = new Rectangle();
    Rectangle br = new Rectangle();

    Font f = c.getFont();

    g.setFont(f);

    SwingUtilities.calculateInnerArea(b, br);
    SwingUtilities.calculateInsetArea(br, b.getMargin(), vr);    
    String text = SwingUtilities.layoutCompoundLabel(c, g.getFontMetrics(f), 
                                                     b.getText(),
                                                     currentIcon(b),
                                                     b.getVerticalAlignment(), 
                                                     b.getHorizontalAlignment(),
                                                     b.getVerticalTextPosition(), 
                                                     b.getHorizontalTextPosition(),
                                                     vr, ir, tr, 
                                                     b.getIconTextGap() 
                                                     + defaultTextShiftOffset);
    
    if ((b.getModel().isArmed() && b.getModel().isPressed()) 
        || b.isSelected())
      paintButtonPressed(g, b);
    else
      paintButtonNormal(g, br, c);
	
    paintIcon(g, c, ir);
    if (text != null)
      paintText(g, b, tr, text);
    paintFocus(g, b, vr, tr, ir);
  }

  /**
   * Paint any focus decoration this {@link JComponent} might have.  The
   * component, which in this case will be an {@link AbstractButton},
   * should only have focus decoration painted if it has the focus, and its
   * "focusPainted" property is <code>true</code>.
   *
   * @param g Graphics context to paint with
   * @param b Button to paint the focus of
   * @param vr Visible rectangle, the area in which to paint
   * @param tr Text rectangle, contained in visible rectangle
   * @param ir Icon rectangle, contained in visible rectangle
   *
   * @see AbstractButton.isFocusPainted()
   * @see JComponent.hasFocus()
   */
  protected void paintFocus(Graphics g, AbstractButton b, Rectangle vr,
                            Rectangle tr, Rectangle ir)
  {
    if (b.hasFocus() && b.isFocusPainted())
      {
        Color saved_color = g.getColor();
        g.setColor(focusColor);
        Rectangle focusRect = ir.union(tr);
        g.drawRect(focusRect.x, focusRect.y,
                   focusRect.width, focusRect.height);
        g.setColor(saved_color);
      }
  }

  /**
   * Paint the icon for this component. Depending on the state of the
   * component and the availability of the button's various icon
   * properties, this might mean painting one of several different icons.
   *
   * @param g Graphics context to paint with
   * @param c Component to paint the icon of
   * @param iconRect Rectangle in which the icon should be painted
   */
  protected void paintIcon(Graphics g, JComponent c, Rectangle iconRect)
  {
    AbstractButton b = (AbstractButton) c;
    Icon i = currentIcon(b);

    if (i != null)
      i.paintIcon(c, g, iconRect.x, iconRect.y);
  }

  /**
   * Paints the background area of an {@link AbstractButton} in the pressed
   * state.  This means filling the supplied area with the {@link
   * pressedBackgroundColor}.
   *
   * @param g The graphics context to paint with
   * @param b The button to paint the state of
   */
  protected void paintButtonPressed(Graphics g, AbstractButton b)
  {
    if (b.isContentAreaFilled())
      {
	Rectangle area = new Rectangle();
	SwingUtilities.calculateInnerArea(b, area);
        g.setColor(b.getBackground().darker());
        g.fillRect(area.x, area.y, area.width, area.height);
      }
  }
    
  /**
   * Paints the background area of an {@link AbstractButton} in the normal,
   * non-pressed state.  This means filling the supplied area with the
   * {@link normalBackgroundColor}.
   *
   * @param g The graphics context to paint with
   * @param area The area in which to paint
   * @param b The component to paint the state of
   */
  private void paintButtonNormal(Graphics g, Rectangle area, JComponent b)
  {
    if (((AbstractButton)b).isContentAreaFilled() && b.isOpaque())
      {
        g.setColor(b.getBackground());
        g.fillRect(area.x, area.y, area.width, area.height);
      }
  }
    
  /**
   * Paints the "text" property of an {@link AbstractButton}, using the
   * {@link textColor} color.
   *
   * @param g The graphics context to paint with
   * @param c The component to paint the state of
   * @param textRect The area in which to paint the text
   * @param text The text to paint
   */
  protected void paintText(Graphics g, JComponent c, Rectangle textRect,
                           String text) 
  {	
    paintText(g, (AbstractButton) c, textRect, text);
  }

  /**
   * Paints the "text" property of an {@link AbstractButton}, using the
   * {@link textColor} color.
   *
   * @param g The graphics context to paint with
   * @param b The button to paint the state of
   * @param textRect The area in which to paint the text
   * @param text The text to paint
   *
   * @since 1.4
   */
  protected void paintText(Graphics g, AbstractButton b, Rectangle textRect,
			   String text)
  {
    Font f = b.getFont();
    g.setFont(f);
    FontMetrics fm = g.getFontMetrics(f);

    if (b.isEnabled())
      {
	g.setColor(b.getForeground());
	g.drawString(text, textRect.x, textRect.y + fm.getAscent());
      }
    else
      {
	g.setColor(b.getBackground().brighter());
	g.drawString(text, textRect.x, textRect.y + fm.getAscent());
	g.setColor(b.getBackground().darker());
	g.drawString(text, textRect.x + 1, textRect.y + fm.getAscent() + 1);
      }
  } 
}
