/* ColorSpace.java -- transforms between color spaces
   Copyright (C) 2000, 2002 Free Software Foundation

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.color;

import java.io.Serializable;

/**
 * NEEDS DOCUMENTATION
 *
 * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
 * @since 1.2
 */
public abstract class ColorSpace implements Serializable
{
  /**
   * Compatible with JDK 1.2+.
   */
  private static final long serialVersionUID = -409452704308689724L;

  public static final int TYPE_XYZ = 0;
  public static final int TYPE_Lab = 1;
  public static final int TYPE_Luv = 2;
  public static final int TYPE_YCbCr = 3;
  public static final int TYPE_Yxy = 4;
  public static final int TYPE_RGB = 5;
  public static final int TYPE_GRAY = 6;
  public static final int TYPE_HSV = 7;
  public static final int TYPE_HLS = 8;
  public static final int TYPE_CMYK = 9;
  // mysterious gap in the enumeration sequenece
  public static final int TYPE_CMY = 11;
  public static final int TYPE_2CLR = 12;
  public static final int TYPE_3CLR = 13;
  public static final int TYPE_4CLR = 14;
  public static final int TYPE_5CLR = 15;
  public static final int TYPE_6CLR = 16;
  public static final int TYPE_7CLR = 17;
  public static final int TYPE_8CLR = 18;
  public static final int TYPE_9CLR = 19;
  public static final int TYPE_ACLR = 20;
  public static final int TYPE_BCLR = 21;
  public static final int TYPE_CCLR = 22;
  public static final int TYPE_DCLR = 23;
  public static final int TYPE_ECLR = 24;
  public static final int TYPE_FCLR = 25;

  public static final int CS_sRGB = 1000;
  public static final int CS_LINEAR_RGB = 1004;
  public static final int CS_CIEXYZ = 1001;
  public static final int CS_PYCC = 1002;
  public static final int CS_GRAY = 1003;

  private static final int CS_BASE = CS_sRGB;
  private static final int CS_END = CS_LINEAR_RGB + 1;
  private static final int CS_COUNT = CS_END - CS_BASE;

  // Instances are lazily instantiated
  private static final ColorSpace[] INSTANCES = new ColorSpace[CS_COUNT];

  /**
   * @serial
   */
  // Visible in subclass.
  final int type;

  /**
   * @serial
   */
  // Visible in subclass.
  final int numComponents;

  protected ColorSpace(int type, int numcomponents)
  {
    this.type = type;
    numComponents = numcomponents;
  }

  public static ColorSpace getInstance(int colorspace)
  {
    if ((colorspace >= CS_BASE) && (colorspace < CS_END))
      {
        int instanceIndex = colorspace - CS_BASE;
        if (INSTANCES[instanceIndex] == null)
          {
            ICC_Profile profile = new ICC_Profile(colorspace);
            INSTANCES[instanceIndex] = new ICC_ColorSpace(profile);
          }
        return INSTANCES[instanceIndex];
      }
    throw new IllegalArgumentException("unknown/unsupported colorspace");
  }

  public boolean isCS_sRGB()
  {
    return type == CS_sRGB;
  }

  /**
   * Transforms a color value assumed to be in this ColorSpace into a value in
   * the default CS_sRGB color space.
   *
   * @exception ArrayIndexOutOfBoundsException If array length is not at least
   * the number of components in this ColorSpace.
   */
  public abstract float[] toRGB(float[] colorvalue);

  public abstract float[] fromRGB(float[] rgbvalue);

  public abstract float[] toCIEXYZ(float[] colorvalue);

  public abstract float[] fromCIEXYZ(float[] colorvalue);

  public int getType()
  {
    return type;
  }

  public int getNumComponents()
  {
    return numComponents;
  }

  public String getName(int idx)
  {
    return "type " + type;
  }

  /**
   * @since 1.4
   */
  public float getMinValue(int idx)
  {
    if (idx < 0 || idx >= numComponents)
      throw new IllegalArgumentException();
    return 0;
  }

  /**
   * @since 1.4
   */
  public float getMaxValue(int idx)
  {
    if (idx < 0 || idx >= numComponents)
      throw new IllegalArgumentException();
    return 1;
  }
} // class ColorSpace
