/* Color.java -- represents a color in Java
   Copyright (C) 1999, 2002, 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., 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 java.awt;

import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;
import java.io.Serializable;

/**
 * This class represents a color value in the AWT system. It uses the sRGB
 * (standard Red-Green-Blue) system, along with an alpha value ranging from
 * transparent (0.0f or 0) and opaque (1.0f or 255). The color is not
 * pre-multiplied by the alpha value an any of the accessor methods. Further
 * information about sRGB can be found at
 * <a href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
 * http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html</a>.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @see ColorSpace
 * @see AlphaComposite
 * @since 1.0
 * @status updated to 1.4
 */
public class Color implements Paint, Serializable
{
  /**
   * Compatible with JDK 1.0+.
   */
  private static final long serialVersionUID = 118526816881161077L;

  /** Constant for the color white: R=255, G=255, B=255. */
  public static final Color white = new Color(0xffffff, false);

  /**
   * Constant for the color white: R=255, G=255, B=255.
   *
   * @since 1.4
   */
  public static final Color WHITE = white;

  /** Constant for the color light gray: R=192, G=192, B=192. */
  public static final Color lightGray = new Color(0xc0c0c0, false);

  /**
   * Constant for the color light gray: R=192, G=192, B=192.
   *
   * @since 1.4
   */
  public static final Color LIGHT_GRAY = lightGray;

  /** Constant for the color gray: R=128, G=128, B=128. */
  public static final Color gray = new Color(0x808080, false);

  /**
   * Constant for the color gray: R=128, G=128, B=128.
   *
   * @since 1.4
   */
  public static final Color GRAY = gray;

  /** Constant for the color dark gray: R=64, G=64, B=64. */
  public static final Color darkGray = new Color(0x404040, false);

  /**
   * Constant for the color dark gray: R=64, G=64, B=64.
   *
   * @since 1.4
   */
  public static final Color DARK_GRAY = darkGray;

  /** Constant for the color black: R=0, G=0, B=0. */
  public static final Color black = new Color(0x000000, false);

  /**
   * Constant for the color black: R=0, G=0, B=0.
   *
   * @since 1.4
   */
  public static final Color BLACK = black;

  /** Constant for the color red: R=255, G=0, B=0. */
  public static final Color red = new Color(0xff0000, false);

  /**
   * Constant for the color red: R=255, G=0, B=0.
   *
   * @since 1.4
   */
  public static final Color RED = red;

  /** Constant for the color pink: R=255, G=175, B=175. */
  public static final Color pink = new Color(0xffafaf, false);

  /**
   * Constant for the color pink: R=255, G=175, B=175.
   *
   * @since 1.4
   */
  public static final Color PINK = pink;

  /** Constant for the color orange: R=255, G=200, B=0. */
  public static final Color orange = new Color(0xffc800, false);

  /**
   * Constant for the color orange: R=255, G=200, B=0.
   *
   * @since 1.4
   */
  public static final Color ORANGE = orange;

  /** Constant for the color yellow: R=255, G=255, B=0. */
  public static final Color yellow = new Color(0xffff00, false);

  /**
   * Constant for the color yellow: R=255, G=255, B=0.
   *
   * @since 1.4
   */
  public static final Color YELLOW = yellow;

  /** Constant for the color green: R=0, G=255, B=0. */
  public static final Color green = new Color(0x00ff00, false);

  /**
   * Constant for the color green: R=0, G=255, B=0.
   *
   * @since 1.4
   */
  public static final Color GREEN = green;

  /** Constant for the color magenta: R=255, G=0, B=255. */
  public static final Color magenta = new Color(0xff00ff, false);

  /**
   * Constant for the color magenta: R=255, G=0, B=255.
   *
   * @since 1.4
   */
  public static final Color MAGENTA = magenta;

  /** Constant for the color cyan: R=0, G=255, B=255. */
  public static final Color cyan = new Color(0x00ffff, false);

  /**
   * Constant for the color cyan: R=0, G=255, B=255.
   *
   * @since 1.4
   */
  public static final Color CYAN = cyan;

  /** Constant for the color blue: R=0, G=0, B=255. */
  public static final Color blue = new Color(0x0000ff, false);

  /**
   * Constant for the color blue: R=0, G=0, B=255.
   *
   * @since 1.4
   */
  public static final Color BLUE = blue;

  /** Internal mask for red. */
  private static final int RED_MASK = 255 << 16;

  /** Internal mask for green. */
  private static final int GREEN_MASK = 255 << 8;

  /** Internal mask for blue. */
  private static final int BLUE_MASK = 255;

  /** Internal mask for alpha. Package visible for use in subclass. */
  static final int ALPHA_MASK = 255 << 24;

  /** Amount to scale a color by when brightening or darkening. */
  private static final float BRIGHT_SCALE = 0.7f;

  /**
   * The color value, in sRGB. Note that the actual color may be more
   * precise if frgbvalue or fvalue is non-null. This class stores alpha, red,
   * green, and blue, each 0-255, packed in an int. However, the subclass
   * SystemColor stores an index into an array. Therefore, for serial
   * compatibility (and because of poor design on Sun's part), this value
   * cannot be used directly; instead you must use <code>getRGB()</code>.
   *
   * @see #getRGB()
   * @serial the value of the color, whether an RGB literal or array index
   */
  final int value;

  /**
   * The color value, in sRGB. This may be null if the color was constructed
   * with ints; and it does not include alpha. This stores red, green, and
   * blue, in the range 0.0f - 1.0f.
   *
   * @see #getRGBColorComponents(float[])
   * @see #getRGBComponents(float[])
   * @serial the rgb components of the value
   * @since 1.2
   */
  private float[] frgbvalue;

  /**
   * The color value, in the native ColorSpace components. This may be null
   * if the color was constructed with ints or in the sRGB color space; and
   * it does not include alpha.
   *
   * @see #getRGBColorComponents(float[])
   * @see #getRGBComponents(float[])
   * @serial the original color space components of the color
   * @since 1.2
   */
  private float[] fvalue;

  /**
   * The alpha value. This is in the range 0.0f - 1.0f, but is invalid if
   * deserialized as 0.0 when frgbvalue is null.
   *
   * @see #getRGBComponents(float[])
   * @see #getComponents(float[])
   * @serial the alpha component of this color
   * @since 1.2
   */
  private final float falpha;

  /**
   * The ColorSpace. Null means the default sRGB space.
   *
   * @see #getColor(String)
   * @see #getColorSpace()
   * @see #getColorComponents(float[])
   * @serial the color space for this color
   * @since 1.2
   */
  private final ColorSpace cs;

  /**
   * The paint context for this solid color. Package visible for use in
   * subclass.
   */
  transient ColorPaintContext context;

  /**
   * Initializes a new instance of <code>Color</code> using the specified
   * red, green, and blue values, which must be given as integers in the
   * range of 0-255. Alpha will default to 255 (opaque). When drawing to
   * screen, the actual color may be adjusted to the best match of hardware
   * capabilities.
   *
   * @param red the red component of the RGB value
   * @param green the green component of the RGB value
   * @param blue the blue component of the RGB value
   * @throws IllegalArgumentException if the values are out of range 0-255
   * @see #getRed()
   * @see #getGreen()
   * @see #getBlue()
   * @see #getRGB()
   * @see #Color(int, int, int, int)
   */
  public Color(int red, int green, int blue)
  {
    this(red, green, blue, 255);
  }

  /**
   * Initializes a new instance of <code>Color</code> using the specified
   * red, green, blue, and alpha values, which must be given as integers in
   * the range of 0-255. When drawing to screen, the actual color may be
   * adjusted to the best match of hardware capabilities.
   *
   * @param red the red component of the RGB value
   * @param green the green component of the RGB value
   * @param blue the blue component of the RGB value
   * @param alpha the alpha value of the color
   * @throws IllegalArgumentException if the values are out of range 0-255
   * @see #getRed()
   * @see #getGreen()
   * @see #getBlue()
   * @see #getAlpha()
   * @see #getRGB()
   */
  public Color(int red, int green, int blue, int alpha)
  {
    if ((red & 255) != red || (green & 255) != green || (blue & 255) != blue
        || (alpha & 255) != alpha)
      throw new IllegalArgumentException("Bad RGB values"
                                        +" red=0x"+Integer.toHexString(red)
                                        +" green=0x"+Integer.toHexString(green)
                                        +" blue=0x"+Integer.toHexString(blue)
                                        +" alpha=0x"+Integer.toHexString(alpha)  );

    value = (alpha << 24) | (red << 16) | (green << 8) | blue;
    falpha = 1;
    cs = null;
  }

  /**
   * Initializes a new instance of <code>Color</code> using the specified
   * RGB value. The blue value is in bits 0-7, green in bits 8-15, and
   * red in bits 16-23. The other bits are ignored. The alpha value is set
   * to 255 (opaque). When drawing to screen, the actual color may be
   * adjusted to the best match of hardware capabilities.
   *
   * @param value the RGB value
   * @see ColorModel#getRGBdefault()
   * @see #getRed()
   * @see #getGreen()
   * @see #getBlue()
   * @see #getRGB()
   * @see #Color(int, boolean)
   */
  public Color(int value)
  {
    this(value, false);
  }

  /**
   * Initializes a new instance of <code>Color</code> using the specified
   * RGB value. The blue value is in bits 0-7, green in bits 8-15, and
   * red in bits 16-23. The alpha value is in bits 24-31, unless hasalpha
   * is false, in which case alpha is set to 255. When drawing to screen, the
   * actual color may be adjusted to the best match of hardware capabilities.
   *
   * @param value the RGB value
   * @param hasalpha true if value includes the alpha
   * @see ColorModel#getRGBdefault()
   * @see #getRed()
   * @see #getGreen()
   * @see #getBlue()
   * @see #getAlpha()
   * @see #getRGB()
   */
  public Color(int value, boolean hasalpha)
  {
    // Note: SystemColor calls this constructor, setting falpha to 0; but
    // code in getRGBComponents correctly reports falpha as 1.0 to the user
    // for all instances of SystemColor since frgbvalue is left null here.
    if (hasalpha)
      falpha = ((value & ALPHA_MASK) >> 24) / 255f;
    else
      {
        value |= ALPHA_MASK;
        falpha = 1;
      }
    this.value = value;
    cs = null;
  }

  /**
   * Initializes a new instance of <code>Color</code> using the specified
   * RGB values. These must be in the range of 0.0-1.0. Alpha is assigned
   * the value of 1.0 (opaque). When drawing to screen, the actual color may
   * be adjusted to the best match of hardware capabilities.
   *
   * @param red the red component of the RGB value
   * @param green the green component of the RGB value
   * @param blue the blue component of the RGB value
   * @throws IllegalArgumentException tf the values are out of range 0.0f-1.0f
   * @see #getRed()
   * @see #getGreen()
   * @see #getBlue()
   * @see #getRGB()
   * @see #Color(float, float, float, float)
   */
  public Color(float red, float green, float blue)
  {
    this(red, green, blue, 1.0f);
  }

  /**
   * Initializes a new instance of <code>Color</code> using the specified
   * RGB and alpha values. These must be in the range of 0.0-1.0. When drawing
   * to screen, the actual color may be adjusted to the best match of
   * hardware capabilities.
   *
   * @param red the red component of the RGB value
   * @param green the green component of the RGB value
   * @param blue the blue component of the RGB value
   * @param alpha the alpha value of the color
   * @throws IllegalArgumentException tf the values are out of range 0.0f-1.0f
   * @see #getRed()
   * @see #getGreen()
   * @see #getBlue()
   * @see #getAlpha()
   * @see #getRGB()
   */
  public Color(float red, float green, float blue, float alpha)
  {
    value = convert(red, green, blue, alpha);
    frgbvalue = new float[] {red, green, blue};
    falpha = alpha;
    cs = null;
  }

  /**
   * Creates a color in the given ColorSpace with the specified alpha. The
   * array must be non-null and have enough elements for the color space
   * (for example, RGB requires 3 elements, CMYK requires 4). When drawing
   * to screen, the actual color may be adjusted to the best match of
   * hardware capabilities.
   *
   * @param space the color space of components
   * @param components the color components, except alpha
   * @param alpha the alpha value of the color
   * @throws NullPointerException if cpsace or components is null
   * @throws ArrayIndexOutOfBoundsException if components is too small
   * @throws IllegalArgumentException if alpha or any component is out of range
   * @see #getComponents(float[])
   * @see #getColorComponents(float[])
   */
  public Color(ColorSpace space, float[] components, float alpha)
  {
    frgbvalue = space.toRGB(components);
    fvalue = components;
    falpha = alpha;
    cs = space;
    value = convert(frgbvalue[0], frgbvalue[1], frgbvalue[2], alpha);
  }

  /**
   * Returns the red value for this color, as an integer in the range 0-255
   * in the sRGB color space.
   *
   * @return the red value for this color
   * @see #getRGB()
   */
  public int getRed()
  {
    // Do not inline getRGB() to value, because of SystemColor.
    return (getRGB() & RED_MASK) >> 16;
  }

  /**
   * Returns the green value for this color, as an integer in the range 0-255
   * in the sRGB color space.
   *
   * @return the green value for this color
   * @see #getRGB()
   */
  public int getGreen()
  {
    // Do not inline getRGB() to value, because of SystemColor.
    return (getRGB() & GREEN_MASK) >> 8;
  }

  /**
   * Returns the blue value for this color, as an integer in the range 0-255
   * in the sRGB color space.
   *
   * @return the blue value for this color
   * @see #getRGB()
   */
  public int getBlue()
  {
    // Do not inline getRGB() to value, because of SystemColor.
    return getRGB() & BLUE_MASK;
  }

  /**
   * Returns the alpha value for this color, as an integer in the range 0-255.
   *
   * @return the alpha value for this color
   * @see #getRGB()
   */
  public int getAlpha()
  {
    // Do not inline getRGB() to value, because of SystemColor.
    return (getRGB() & ALPHA_MASK) >>> 24;
  }

  /**
   * Returns the RGB value for this color, in the sRGB color space. The blue
   * value will be in bits 0-7, green in 8-15, red in 16-23, and alpha value in
   * 24-31.
   *
   * @return the RGB value for this color
   * @see ColorModel#getRGBdefault()
   * @see #getRed()
   * @see #getGreen()
   * @see #getBlue()
   * @see #getAlpha()
   */
  public int getRGB()
  {
    return value;
  }

  /**
   * Returns a brighter version of this color. This is done by increasing the
   * RGB values by an arbitrary scale factor. The new color is opaque (an
   * alpha of 255). Note that this method and the <code>darker()</code>
   * method are not necessarily inverses.
   *
   * @return a brighter version of this color
   * @see #darker()
   */
  public Color brighter()
  {
    // Do not inline getRGB() to this.value, because of SystemColor.
    int value = getRGB();
    int red = (value & RED_MASK) >> 16;
    int green = (value & GREEN_MASK) >> 8;
    int blue = value & BLUE_MASK;
    // We have to special case 0-2 because they won't scale by division.
    red = red < 3 ? 3 : (int) Math.min(255, red / BRIGHT_SCALE);
    green = green < 3 ? 3 : (int) Math.min(255, green / BRIGHT_SCALE);
    blue = blue < 3 ? 3 : (int) Math.min(255, blue / BRIGHT_SCALE);
    return new Color(red, green, blue, 255);
  }

  /**
   * Returns a darker version of this color. This is done by decreasing the
   * RGB values by an arbitrary scale factor. The new color is opaque (an
   * alpha of 255). Note that this method and the <code>brighter()</code>
   * method are not necessarily inverses.
   *
   * @return a darker version of this color
   * @see #brighter()
   */
  public Color darker()
  {
    // Do not inline getRGB() to this.value, because of SystemColor.
    int value = getRGB();
    return new Color((int) (((value & RED_MASK) >> 16) * BRIGHT_SCALE),
                     (int) (((value & GREEN_MASK) >> 8) * BRIGHT_SCALE),
                     (int) ((value & BLUE_MASK) * BRIGHT_SCALE), 255);
  }

  /**
   * Returns a hash value for this color. This is simply the color in 8-bit
   * precision, in the format 0xAARRGGBB (alpha, red, green, blue).
   *
   * @return a hash value for this color
   */
  public int hashCode()
  {
    return value;
  }

  /**
   * Tests this object for equality against the specified object.  This will
   * be true if and only if the specified object is an instance of
   * <code>Color</code> and has the same 8-bit integer red, green, and blue
   * values as this object. Note that two colors may be slightly different
   * as float values, but round to the same integer values. Also note that
   * this does not accurately compare SystemColors, since that class does
   * not store its internal data in RGB format like regular colors.
   *
   * @param obj the object to compare to
   * @return true if the specified object is semantically equal to this one
   */
  public boolean equals(Object obj)
  {
    return obj instanceof Color && ((Color) obj).value == value;
  }

  /**
   * Returns a string representation of this object. Subclasses may return
   * any desired format, except for null, but this implementation returns
   * <code>getClass().getName() + "[r=" + getRed() + ",g=" + getGreen()
   * + ",b=" + getBlue() + ']'</code>.
   *
   * @return a string representation of this object
   */
  public String toString()
  {
    return getClass().getName() + "[r=" + ((value & RED_MASK) >> 16)
      + ",g=" + ((value & GREEN_MASK) >> 8) + ",b=" + (value & BLUE_MASK)
      + ']';
  }

  /**
   * Converts the specified string to a number, using Integer.decode, and
   * creates a new instance of <code>Color</code> from the value. The alpha
   * value will be 255 (opaque).
   *
   * @param str the numeric color string
   * @return a new instance of <code>Color</code> for the string
   * @throws NumberFormatException if the string cannot be parsed
   * @throws NullPointerException if the string is null
   * @see Integer#decode(String)
   * @see #Color(int)
   * @since 1.1
   */
  public static Color decode(String str)
  {
    return new Color(Integer.decode(str).intValue(), false);
  }

  /**
   * Returns a new instance of <code>Color</code> from the value of the
   * system property named by the specified string.  If the property does not
   * exist, or cannot be parsed, then <code>null</code> will be returned.
   *
   * @param prop the system property to retrieve
   * @throws SecurityException if getting the property is denied
   * @see #getColor(String, Color)
   * @see Integer#getInteger(String)
   */
  public static Color getColor(String prop)
  {
    return getColor(prop, null);
  }

  /**
   * Returns a new instance of <code>Color</code> from the value of the
   * system property named by the specified string.  If the property does
   * not exist, or cannot be parsed, then the default color value will be
   * returned.
   *
   * @param prop the system property to retrieve
   * @param defcolor the default color
   * @throws SecurityException if getting the property is denied
   * @see Integer#getInteger(String)
   */
  public static Color getColor(String prop, Color defcolor)
  {
    Integer val = Integer.getInteger(prop, null);
    return val == null ? defcolor
      : new Color(val.intValue(), false);
  }

  /**
   * Returns a new instance of <code>Color</code> from the value of the
   * system property named by the specified string.  If the property does
   * not exist, or cannot be parsed, then the default RGB value will be
   * used to create a return value.
   *
   * @param prop the system property to retrieve
   * @param defrgb the default RGB value
   * @throws SecurityException if getting the property is denied
   * @see #getColor(String, Color)
   * @see Integer#getInteger(String, int)
   */
  public static Color getColor(String prop, int defrgb)
  {
    Color c = getColor(prop, null);
    return c == null ? new Color(defrgb, false) : c;
  }

  /**
   * Converts from the HSB (hue, saturation, brightness) color model to the
   * RGB (red, green, blue) color model. The hue may be any floating point;
   * it's fractional portion is used to select the angle in the HSB model.
   * The saturation and brightness must be between 0 and 1. The result is
   * suitable for creating an RGB color with the one-argument constructor.
   *
   * @param hue the hue of the HSB value
   * @param saturation the saturation of the HSB value
   * @param brightness the brightness of the HSB value
   * @return the RGB value
   * @see #getRGB()
   * @see #Color(int)
   * @see ColorModel#getRGBdefault()
   */
  public static int HSBtoRGB(float hue, float saturation, float brightness)
  {
    if (saturation == 0)
      return convert(brightness, brightness, brightness, 0);
    if (saturation < 0 || saturation > 1 || brightness < 0 || brightness > 1)
      throw new IllegalArgumentException();
    hue = hue - (float) Math.floor(hue);
    int i = (int) (6 * hue);
    float f = 6 * hue - i;
    float p = brightness * (1 - saturation);
    float q = brightness * (1 - saturation * f);
    float t = brightness * (1 - saturation * (1 - f));
    switch (i)
      {
      case 0:
        return convert(brightness, t, p, 0);
      case 1:
        return convert(q, brightness, p, 0);
      case 2:
        return convert(p, brightness, t, 0);
      case 3:
        return convert(p, q, brightness, 0);
      case 4:
        return convert(t, p, brightness, 0);
      case 5:
        return convert(brightness, p, q, 0);
      default:
        throw new InternalError("impossible");
      }
  }

  /**
   * Converts from the RGB (red, green, blue) color model to the HSB (hue,
   * saturation, brightness) color model. If the array is null, a new one
   * is created, otherwise it is recycled. The results will be in the range
   * 0.0-1.0 if the inputs are in the range 0-255.
   *
   * @param red the red part of the RGB value
   * @param green the green part of the RGB value
   * @param blue the blue part of the RGB value
   * @param array an array for the result (at least 3 elements), or null
   * @return the array containing HSB value
   * @throws ArrayIndexOutOfBoundsException of array is too small
   * @see #getRGB()
   * @see #Color(int)
   * @see ColorModel#getRGBdefault()
   */
  public static float[] RGBtoHSB(int red, int green, int blue, float array[])
  {
    if (array == null)
      array = new float[3];
    // Calculate brightness.
    int min;
    int max;
    if (red < green)
      {
        min = red;
        max = green;
      }
    else
      {
        min = green;
        max = red;
      }
    if (blue > max)
      max = blue;
    else if (blue < min)
      min = blue;
    array[2] = max / 255f;
    // Calculate saturation.
    if (max == 0)
      array[1] = 0;
    else
      array[1] = ((float) (max - min)) / ((float) max);
    // Calculate hue.
    if (array[1] == 0)
      array[0] = 0;
    else
      {
        float delta = (max - min) * 6;
        if (red == max)
          array[0] = (green - blue) / delta;
        else if (green == max)
          array[0] = 1f / 3 + (blue - red) / delta;
        else
          array[0] = 2f / 3 + (red - green) / delta;
        if (array[0] < 0)
          array[0]++;
      }
    return array;
  }

  /**
   * Returns a new instance of <code>Color</code> based on the specified
   * HSB values. The hue may be any floating point; it's fractional portion
   * is used to select the angle in the HSB model. The saturation and
   * brightness must be between 0 and 1.
   *
   * @param hue the hue of the HSB value
   * @param saturation the saturation of the HSB value
   * @param brightness the brightness of the HSB value
   * @return the new <code>Color</code> object
   */
  public static Color getHSBColor(float hue, float saturation,
                                  float brightness)
  {
    return new Color(HSBtoRGB(hue, saturation, brightness), false);
  }

  /**
   * Returns a float array with the red, green, and blue components, and the
   * alpha value, in the default sRGB space, with values in the range 0.0-1.0.
   * If the array is null, a new one is created, otherwise it is recycled.
   *
   * @param array the array to put results into (at least 4 elements), or null
   * @return the RGB components and alpha value
   * @throws ArrayIndexOutOfBoundsException if array is too small
   */
  public float[] getRGBComponents(float[] array)
  {
    if (array == null)
      array = new float[4];
    getRGBColorComponents(array);
    // Stupid serialization issues require this check.
    array[3] = (falpha == 0 && frgbvalue == null
                ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha);
    return array;
  }

  /**
   * Returns a float array with the red, green, and blue components, in the
   * default sRGB space, with values in the range 0.0-1.0. If the array is
   * null, a new one is created, otherwise it is recycled.
   *
   * @param array the array to put results into (at least 3 elements), or null
   * @return the RGB components
   * @throws ArrayIndexOutOfBoundsException if array is too small
   */
  public float[] getRGBColorComponents(float[] array)
  {
    if (array == null)
      array = new float[3];
    else if (array == frgbvalue)
      return array; // Optimization for getColorComponents(float[]).
    if (frgbvalue == null)
      {
        // Do not inline getRGB() to this.value, because of SystemColor.
        int value = getRGB();
        frgbvalue = new float[] { ((value & RED_MASK) >> 16) / 255f,
                                  ((value & GREEN_MASK) >> 8) / 255f,
                                  (value & BLUE_MASK) / 255f };
      }
    array[0] = frgbvalue[0];
    array[1] = frgbvalue[1];
    array[2] = frgbvalue[2];
    return array;
  }

  /**
   * Returns a float array containing the color and alpha components of this
   * color in the ColorSpace it was created with (the constructors which do
   * not take a ColorSpace parameter use a default sRGB ColorSpace). If the
   * array is null, a new one is created, otherwise it is recycled, and must
   * have at least one more position than components used in the color space.
   *
   * @param array the array to put results into, or null
   * @return the original color space components and alpha value
   * @throws ArrayIndexOutOfBoundsException if array is too small
   */
  public float[] getComponents(float[] array)
  {
    int numComponents = cs == null ? 3 : cs.getNumComponents();
    if (array == null)
      array = new float[1 + numComponents];
    getColorComponents(array);
    // Stupid serialization issues require this check.
    array[numComponents] = (falpha == 0 && frgbvalue == null
                            ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha);
    return array;
  }

  /**
   * Returns a float array containing the color components of this color in
   * the ColorSpace it was created with (the constructors which do not take
   * a ColorSpace parameter use a default sRGB ColorSpace). If the array is
   * null, a new one is created, otherwise it is recycled, and must have at
   * least as many positions as used in the color space.
   *
   * @param array the array to put results into, or null
   * @return the original color space components
   * @throws ArrayIndexOutOfBoundsException if array is too small
   */
  public float[] getColorComponents(float[] array)
  {
    int numComponents = cs == null ? 3 : cs.getNumComponents();
    if (array == null)
      array = new float[numComponents];
    if (fvalue == null) // If fvalue is null, cs should be null too.
      fvalue = getRGBColorComponents(frgbvalue);
    System.arraycopy(fvalue, 0, array, 0, numComponents);
    return array;
  }

  /**
   * Returns a float array containing the color and alpha components of this
   * color in the given ColorSpace. If the array is null, a new one is
   * created, otherwise it is recycled, and must have at least one more
   * position than components used in the color space.
   *
   * @param space the color space to translate to
   * @param array the array to put results into, or null
   * @return the color space components and alpha value
   * @throws ArrayIndexOutOfBoundsException if array is too small
   * @throws NullPointerException if space is null
   */
  public float[] getComponents(ColorSpace space, float[] array)
  {
    int numComponents = space.getNumComponents();
    if (array == null)
      array = new float[1 + numComponents];
    getColorComponents(space, array);
    // Stupid serialization issues require this check.
    array[numComponents] = (falpha == 0 && frgbvalue == null
                            ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha);
    return array;
  }

  /**
   * Returns a float array containing the color components of this color in
   * the given ColorSpace. If the array is null, a new one is created,
   * otherwise it is recycled, and must have at least as many positions as
   * used in the color space.
   *
   * @param space the color space to translate to
   * @return the color space components
   * @throws ArrayIndexOutOfBoundsException if array is too small
   * @throws NullPointerException if space is null
   */
  public float[] getColorComponents(ColorSpace space, float[] array)
  {
    float[] components = space.fromRGB(getRGBColorComponents(frgbvalue));
    if (array == null)
      return components;
    System.arraycopy(components, 0, array, 0, components.length);
    return array;
  }

  /**
   * Returns the color space of this color. Except for the constructor which
   * takes a ColorSpace argument, this will be an implementation of
   * ColorSpace.CS_sRGB.
   *
   * @return the color space
   */
  public ColorSpace getColorSpace()
  {
    return cs == null ? ColorSpace.getInstance(ColorSpace.CS_sRGB) : cs;
  }

  /**
   * Returns a paint context, used for filling areas of a raster scan with
   * this color. Since the color is constant across the entire rectangle, and
   * since it is always in sRGB space, this implementation returns the same
   * object, regardless of the parameters. Subclasses, however, may have a
   * mutable result.
   *
   * @param cm the requested color model
   * @param deviceBounds the bounding box in device coordinates, ignored
   * @param userBounds the bounding box in user coordinates, ignored
   * @param xform the bounds transformation, ignored
   * @param hints any rendering hints, ignored
   * @return a context for painting this solid color
   */
  public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
                                    Rectangle2D userBounds,
                                    AffineTransform xform,
                                    RenderingHints hints)
  {
    if (context == null || !context.getColorModel().equals(cm))
      context = new ColorPaintContext(cm,value);
    return context;
  }

  /**
   * Returns the transparency level of this color.
   *
   * @return one of {@link #OPAQUE}, {@link #BITMASK}, or {@link #TRANSLUCENT}
   */
  public int getTransparency()
  {
    // Do not inline getRGB() to this.value, because of SystemColor.
    int alpha = getRGB() & ALPHA_MASK;
    return alpha == (255 << 24) ? OPAQUE : alpha == 0 ? BITMASK : TRANSLUCENT;
  }

  /**
   * Converts float values to integer value.
   *
   * @param red the red value
   * @param green the green value
   * @param blue the blue value
   * @param alpha the alpha value
   * @return the integer value made of 8-bit sections
   * @throws IllegalArgumentException if parameters are out of range 0.0-1.0
   */
  private static int convert(float red, float green, float blue, float alpha)
  {
    if (red < 0 || red > 1 || green < 0 || green > 1 || blue < 0 || blue > 1
        || alpha < 0 || alpha > 1)
      throw new IllegalArgumentException("Bad RGB values");
    int redval = Math.round(255 * red);
    int greenval = Math.round(255 * green);
    int blueval = Math.round(255 * blue);
    int alphaval = Math.round(255 * alpha);
    return (alphaval << 24) | (redval << 16) | (greenval << 8) | blueval;
  }
} // class Color
