/* LineBorder.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 border that consists of a line whose thickness and color can be
 * specified. There also is a variant with rounded corners.
 *
 * @author Sascha Brawer (brawer@dandelis.ch)
 */
public class LineBorder
  extends AbstractBorder
{
  /**
   * Determined using the <code>serialver</code> tool
   * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5.
   */
  static final long serialVersionUID = -787563427772288970L;


  /**
   * A shared instance of a black, one pixel thick, plain LineBorder.
   * The singleton object is lazily created by {@link
   * #createBlackLineBorder()} upon its first invocation.
   */
  private static LineBorder blackLineBorder;


  /**
   * A shared instance of a gray, one pixel thick, plain LineBorder.
   * The singleton object is lazily created by {@link
   * #createBlackGrayBorder()} upon its first invocation.
   */
  private static LineBorder grayLineBorder;


  /**
   * The width of the line in pixels.
   */
  protected int thickness;


  /**
   * The color of the line.
   */
  protected Color lineColor;


  /**
   * Indicates whether the line is drawn with rounded corners
   * (<code>true</code>) or not ((<code>false</code>).
   */
  protected boolean roundedCorners;


  /**
   * Constructs a LineBorder given its color.  The border will be one
   * pixel thick and have plain corners.
   *
   * @param color the color for drawing the border.
   *
   * @see #LineBorder(java.awt.Color, int, boolean)
   */
  public LineBorder(Color color)
  {
    this(color, /* thickness */ 1, /* roundedCorners */ false);
  }


  /**
   * Constructs a LineBorder given its color and thickness.  The
   * border will have plain corners.
   *
   * @param color the color for drawing the border.
   * @param thickness the width of the line in pixels.
   *
   * @see #LineBorder(java.awt.Color, int, boolean)
   */
  public LineBorder(Color color, int thickness)
  {
    this (color, thickness, /* roundedCorners */ false);
  }
  
  
  /**
   * Constructs a LineBorder given its color, thickness, and whether
   * it has rounded corners.
   * 
   * <p><img src="doc-files/LineBorder-1.png" width="500" height="200"
   * alt="[An illustration of two LineBorders]" />
   *
   * <p>Note that the enlarged view in the right-hand picture shows
   * that the implementation draws one more pixel than specified,
   * provided that <code>roundedCorders</code> is <code>true</code>
   * and anti-aliasing is turned on while painting. While this might
   * be considered a bug, the Sun reference implementation (at least
   * JDK 1.3.1 on Apple MacOS X 10.1.5) can be observed to fill
   * exactly the same pixels as shown above. The GNU Classpath
   * LineBorder replicates the observed behavior of the Sun
   * implementation.
   *
   * @param color the color for drawing the border.
   * @param thickness the width of the line in pixels.
   * @param roundedCorners <code>true</code> for rounded corners,
   *        <code>false</code> for plain corners.
   *
   * @since 1.3
   */
  // For the bug mentioned in the JavaDoc, please see also the comment
  // in the paintBorder method below.
  //
  public LineBorder(Color color, int thickness, boolean roundedCorners)
  {
    if ((color == null) || (thickness < 0))
      throw new IllegalArgumentException();

    this.lineColor = color;
    this.thickness = thickness;
    this.roundedCorners = roundedCorners;
  }
  
  
  /**
   * Returns a black, one pixel thick, plain LineBorder. The method
   * may always return the same (singleton) LineBorder instance.
   */
  public static Border createBlackLineBorder()
  {
    /* Swing is not designed to be thread-safe, so there is no
     * need to synchronize the access to the global variable.
     */
    if (blackLineBorder == null)
      blackLineBorder = new LineBorder(Color.black);
    
    return blackLineBorder;
  }
  
  
  /**
   * Returns a gray, one pixel thick, plain LineBorder. The method
   * may always return the same (singleton) LineBorder instance.
   */
  public static Border createGrayLineBorder()
  {
    /* Swing is not designed to be thread-safe, so there is no
     * need to synchronize the access to the global variable.
     */
    if (grayLineBorder == null)
      grayLineBorder = new LineBorder(Color.gray);
    
    return grayLineBorder;
  }
  
  
  /**
   * Paints the line border around 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)
  {
    Color oldColor = g.getColor();

    try
    {
      g.setColor(lineColor);

      /* If width and height were not adjusted, the border would
       * appear one pixel too large in both directions.
       */
      width -= 1;
      height -= 1;

      /* Blurred, too large appearance
       * -----------------------------
       * While Java 2D has introduced line strokes of arbitrary width,
       * it seems desirable to keep this code independent of Java 2D.
       * Therefore, multiple nested rectangles (or rounded rectangles)
       * are drawn in order to simulate a line whose thickness is
       * greater than one pixel.
       *
       * This hack causes a blurred appearance when anti-aliasing is
       * on. Interestingly enough, though, the Sun JDK 1.3.1 (at least
       * on MacOS X 10.1.5) shows exactly the same appearance under
       * this condition. It thus seems likely that Sun does the same
       * hack for simulating thick lines.  For this reason, the
       * blurred appearance seems acceptable -- especially since GNU
       * Classpath tries to be compatible with the Sun reference
       * implementation.
       */
      for (int i = 0; i < thickness; i++)
      {
        if (roundedCorners)
          g.drawRoundRect(x, y, width, height, thickness, thickness);
        else
          g.drawRect(x, y, width, height);

        x += 1;
        y += 1;
        width -= 2;
        height -= 2;
      }
    }
    finally
    {
      g.setColor(oldColor);
    }
  }
  
  
  /**
   * 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, which is the
   *         thickness of the line.
   *
   * @see #getBorderInsets(java.awt.Component, java.awt.Insets)
   */
  public Insets getBorderInsets(Component c)
  {
    return new Insets(thickness, thickness, thickness, thickness);
  }
  
  
  /**
   * 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, which is the thickness
   *        of the line.
   *
   * @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 = thickness;
    return insets;
  }
  
  
  /**
   * Returns the color of the line.
   */
  public Color getLineColor()
  {
    return lineColor;
  }
  
  
  /**
   * Returns the thickness of the line in pixels.
   */
  public int getThickness()
  {
    return thickness;
  }
  
  
  /**
   * Returns whether this LineBorder os drawm with rounded
   * or with plain corners.
   *
   * @return <code>true</code> if the corners are rounded,
   *         <code>false</code> if the corners are plain.
   */
  public boolean getRoundedCorners()
  {
    return roundedCorners;
  }
  
  
  /**
   * Determines whether this border fills every pixel in its area
   * when painting.
   *
   * @return <code>true</code> if the corners are plain and the line
   *         color is fully opaque; <code>false</code> if the corners
   *         are rounded or the line color is partially transparent.
   */
  public boolean isBorderOpaque()
  {
    return (!roundedCorners) && (lineColor.getAlpha() == 255);
  }
}

