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

