/* SoftBevelBorder.java --
   Copyright (C) 2003 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.border;

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Insets;


/**
 * A rectangular, three pixel thick border that looks like a BevelBorder
 * with slightly softened corners.
 *
 * <p>Like BevelBorder, SoftBevelBorder has a highlight and a shadow
 * color. In the raised variant, the highlight color is used for the
 * top and left edges, and the shadow color is used for the bottom and
 * right edge.  In the lowered variant, color usage is reversed.  For
 * an image, see the documentation of the individual constructors.
 *
 * @author Sascha Brawer (brawer@dandelis.ch)
 */
public class SoftBevelBorder extends BevelBorder
{
  /**
   * Determined using the <code>serialver</code> tool
   * of Sun JDK 1.4.1_01 on GNU/Linux 2.4.20. Interestingly,
   * the Apple/Sun JDK 1.3.1 on MacOS X 10.1.5 gives a different
   * value, namely -6658357140774549493L.
   */
  static final long serialVersionUID = 5248789787305979975L;


  /**
   * Constructs a SoftBevelBorder whose colors will be derived from the
   * background of the enclosed component. The background color is
   * retrieved each time the border is painted, so a SoftBevelBorder
   * constructed by this method will automatically reflect a change
   * to the component&#x2019;s background color.
   *
   * <p><img src="doc-files/SoftBevelBorder-1.png" width="500" height="200"
   * alt="[An illustration showing raised and lowered SoftBevelBorders]" />
   *
   * @param bevelType the desired appearance of the border. The value
   *        must be either {@link BevelBorder#RAISED}
   *        or {@link BevelBorder#LOWERED}.
   *
   * @throws IllegalArgumentException if <code>bevelType</code> has
   *         an unsupported value.
   */
  public SoftBevelBorder(int bevelType)
  {
    super(bevelType);
  }


  /**
   * Constructs a SoftBevelBorder given its appearance type and two
   * colors for its highlight and shadow.
   *
   * <p><img src="doc-files/SoftBevelBorder-2.png" width="500" height="150"
   * alt="[An illustration showing SoftBevelBorders that were
   * constructed with this method]" />
   *
   * @param bevelType the desired appearance of the border. The value
   *        must be either {@link BevelBorder#RAISED} or {@link
   *        BevelBorder#LOWERED}.
   *
   * @param highlight the color that will be used for the inner side
   *        of the highlighted edges (top and left if if
   *        <code>bevelType</code> is {@link BevelBorder#RAISED};
   *        bottom and right otherwise). The color for the outer side
   *        is a brightened version of this color.
   *
   * @param shadow the color that will be used for the outer side of
   *        the shadowed edges (bottom and right if
   *        <code>bevelType</code> is {@link BevelBorder#RAISED}; top
   *        and left otherwise). The color for the inner side is a
   *        brightened version of this color.
   *
   * @throws IllegalArgumentException if <code>bevelType</code> has an
   *        unsupported value.
   *
   * @throws NullPointerException if <code>highlight</code> or
   *         <code>shadow</code> is <code>null</code>.
   *
   * @see java.awt.Color#brighter()
   */
  public SoftBevelBorder(int bevelType, Color highlight, Color shadow)
  {
    this(bevelType,
         /* highlightOuter */ highlight.brighter(),
         /* highlightInner */ highlight,
         /* shadowOuter */    shadow,
         /* shadowInner */    shadow.brighter());
  }


  /**
   * Constructs a SoftBevelBorder given its appearance type and all
   * colors.
   *
   * <p><img src="doc-files/SoftBevelBorder-3.png" width="500" height="150"
   * alt="[An illustration showing SoftBevelBorders that were
   * constructed with this method]" />
   *
   * @param bevelType the desired appearance of the border. The value
   *        must be either {@link BevelBorder#RAISED} or {@link
   *        BevelBorder#LOWERED}.
   *
   * @param highlightOuter the color that will be used for the outer
   *        side of the highlighted edges (top and left if
   *        <code>bevelType</code> is {@link BevelBorder#RAISED};
   *        bottom and right otherwise).
   *
   * @param highlightInner the color that will be used for the inner
   *        side of the highlighted edges.
   *
   * @param shadowOuter the color that will be used for the outer side
   *        of the shadowed edges (bottom and right if
   *        <code>bevelType</code> is {@link BevelBorder#RAISED}; top
   *        and left otherwise).
   *
   * @param shadowInner the color that will be used for the inner
   *        side of the shadowed edges.
   *
   * @throws IllegalArgumentException if <code>bevelType</code> has
   *         an unsupported value.
   *
   * @throws NullPointerException if one of the passed colors
   *         is <code>null</code>.
   */
  public SoftBevelBorder(int bevelType,
                         Color highlightOuter, Color highlightInner,
                         Color shadowOuter, Color shadowInner)
  {
    super(bevelType,
          highlightOuter, highlightInner,
          shadowOuter, shadowInner);
  }


  /**
   * Paints the border for a given component.
   *
   * @param c the component whose border is to be painted.
   * @param g the graphics for painting.
   * @param x the horizontal position for painting the border.
   * @param y the vertical position for painting the border.
   * @param width the width of the available area for painting the border.
   * @param height the height of the available area for painting the border.
   */
  public void paintBorder(Component c, Graphics  g,
                          int x, int y, int width, int height)
  {
    switch (bevelType)
    {
    case RAISED:
      paintSoftBevel(g, x, y, width, height,
                     getHighlightOuterColor(c), getHighlightInnerColor(c),
                     getShadowInnerColor(c), getShadowOuterColor(c));
      break;

    case LOWERED:
      paintSoftBevel(g, x, y, width, height,
                     getShadowOuterColor(c), getShadowInnerColor(c),
                     getHighlightInnerColor(c), getHighlightOuterColor(c));
      break;
    }
  }


  /**
   * Measures the width of this border.
   *
   * @param c the component whose border is to be measured.
   *
   * @return an Insets object whose <code>left</code>, <code>right</code>,
   *         <code>top</code> and <code>bottom</code> fields indicate the
   *         width of the border at the respective edge.
   *
   * @see #getBorderInsets(java.awt.Component, java.awt.Insets)
   */
  public Insets getBorderInsets(Component c)
  {
    return new Insets(3, 3, 3, 3);
  }


  /**
   * Measures the width of this border, storing the results into a
   * pre-existing Insets object.
   *
   * @param insets an Insets object for holding the result values.
   *        After invoking this method, the <code>left</code>,
   *        <code>right</code>, <code>top</code> and
   *        <code>bottom</code> fields indicate the width of the
   *        border at the respective edge.
   *
   * @return the same object that was passed for <code>insets</code>.
   *
   * @see #getBorderInsets(Component)
   */
  public Insets getBorderInsets(Component c, Insets insets)
  {
    insets.left = insets.right = insets.top = insets.bottom = 3;
    return insets;
  }


  /**
   * Determines whether this border fills every pixel in its area
   * when painting.
   *
   * <p>The enlarged view (see documentation for constructors) shows
   * that a SoftBevelBorder does not paint all pixels. Therefore,
   * this method always returns <code>false</code>.
   *
   * @return <code>false</code>.
   */
  public boolean isBorderOpaque()
  {
    return false;
  }


  /**
   * Paints a soft bevel in four colors.
   *
   * <pre>
   * +++++++++++.
   * ++.........#    + = color a
   * +..        #    . = color b
   * +.         #    X = color c
   * ..        X#    # = color d
   * . ##########</pre>
   *
   * @param g the graphics for painting.
   * @param x the horizontal position for painting the border.
   * @param y the vertical position for painting the border.
   * @param width the width of the available area for painting the border.
   * @param height the height of the available area for painting the border.
   * @param a the color for the outer side of the top and left edges.
   * @param b the color for the inner side of the top and left edges.
   * @param c the color for the inner side of the bottom and right edges.
   * @param d the color for the outer side of the bottom and right edges.
   */
  private static void paintSoftBevel(Graphics g,
                                     int x, int y, int width, int height,
                                     Color a, Color b, Color c, Color d)
  {
    Color oldColor;

    oldColor = g.getColor();
    g.translate(x, y);
    width = width - 1;
    height = height - 1;

    try
    {
      /* To understand this code, it might be helpful to look at the
       * images that are included with the JavaDoc, especially
       * SoftBevelBorder-3.png. They are located in the "doc-files"
       * subdirectory.
       */
      g.setColor(a);
      g.drawLine(0, 0, width - 1, 0);                   // a, horizontal
      g.drawLine(0, 1, 2, 1);                           // a, horizontal
      g.drawLine(0, 2, 0, height - 1);                  // a, vertical

      g.setColor(b);
      g.drawLine(width, 0, width, 0);                   // b, horizontal
      g.drawLine(2, 1, width - 1, 1);                   // b, horizontal
      g.drawLine(1, 2, 2, 2);                           // b, horizontal
      g.drawLine(1, 3, 1, height - 1);                  // b, vertical
      g.drawLine(0, height - 1, 0, height);             // b, vertical

      g.setColor(c);
      g.drawLine(width - 1, height - 1,                 // c, one pixel
                 width - 1, height - 1);

      g.setColor(d);
      g.drawLine(2, height, width, height);             // d, horizontal
      g.drawLine(width, 2, width, height - 1);          // d, vertical
    }
    finally
    {
      g.translate(-x, -y);
      g.setColor(oldColor);
    }
  }
}
