package net.returnvoid.color;

/*
 * This code is copyright (c) Diana Lange 2017
 *
 * The library is published under the Creative Commons license NonCommercial 4.0.
 * Please check https://creativecommons.org/licenses/by-nc/4.0/ for more information.
 * 
 * This program is distributed in the hope that it will be useful, but without any warranty.
 */

/**
 * A base interface for all color spaces.
 * 
 * @author Diana Lange
 *
 */
public interface RColor {

	/**
	 * Returns the color values of the current object. Depending on the color
	 * space these are: <br>
	 * [0] = red [1] = green [2] = blue [3] = alpha<br>
	 * [0] = hue [1] = saturation [2] = brightness [3] = alpha<br>
	 * [0] = x [1] = y [2] = z [3] = alpha<br>
	 * [0] = L [1] = a [2] = b [3] = alpha<br>
	 * [0] = L [1] = C [2] = Hue [3] = alpha<br>
	 * 
	 * @return the colors.
	 */
	public float[] getValues();

	/**
	 * Returns the normalized color values of the current object. The ranges of
	 * all values will be between [0,1]. Depending on the color space the values
	 * are: <br>
	 * [0] = red [1] = green [2] = blue [3] = alpha<br>
	 * [0] = hue [1] = saturation [2] = brightness [3] = alpha<br>
	 * [0] = x [1] = y [2] = z [3] = alpha<br>
	 * [0] = L [1] = a [2] = b [3] = alpha<br>
	 * [0] = L [1] = C [2] = Hue [3] = alpha<br>
	 * 
	 * @return the colors.
	 */
	public float[] getValuesNormalized();

	/**
	 * Returns a String representation of the current color using hexadecimal
	 * numbers. The range will be between "FFFFFFFF" and "00000000". Example:
	 * <br>
	 * 
	 * <pre>
	 * RGBColor rgb = new RGBColor(255, 0, 128, 0);
	 * rgb.getHexString(); // "00FF0080"
	 * </pre>
	 * 
	 * @return the color value of the object.
	 */
	public String getHexString();

	/**
	 * Returns a String representation of the current color using hexadecimal
	 * numbers. The alpha value will be ignored ('Op' in method name stands for
	 * Opaque). The range will be between "FFFFFF" and "000000". Example: <br>
	 * 
	 * <pre>
	 * RGBColor rgb = new RGBColor(255, 0, 128, 0);
	 * rgb.getOpHexString(); // "FF0080"
	 * </pre>
	 * 
	 * @return the color value of the object.
	 */
	public String getOpHexString();

	/**
	 * Returns a int representation of the current color - but ignoring the
	 * alpha value. The output will always be opaque ('Op' in method name stands
	 * for Opaque). The range will be between 0xFFFFFFFF and 0xFF000000. Using
	 * this, the color object can be used to set the color within Processing.
	 * Example: <br>
	 * 
	 * <pre>
	 * HSBColor hsb = new HSBColor(244, 100, 100, 50);
	 * fill(hsb.getOpColor());
	 * </pre>
	 * 
	 * @return the color value of the object.
	 */
	public int getOpColor();

	/**
	 * Returns a int representation of the current color. The range will be
	 * between 0xFFFFFFFF and 0x00000000. Using this, the color object can be
	 * used to set the color within Processing. Example: <br>
	 * 
	 * <pre>
	 * HSBColor hsb = new HSBColor(244, 100, 100);
	 * fill(hsb.getColor());
	 * </pre>
	 * 
	 * @return the color value of the object.
	 */
	public int getColor();

	/**
	 * Sets the value of alpha / transparency. The range of alpha depends on the
	 * model of the color space. For RGB alpha will have a range of [0, 255].
	 * For all other color spaces the range is [0, 100]. Zero always means that
	 * the color is completely transparent. The high value means that the color
	 * is completely opaque.
	 * 
	 * @param alpha
	 *            The value of the colors transparency.
	 * 
	 * @return The current color object.
	 */
	public RColor setAlpha(Float alpha);

	/**
	 * Returns the value of alpha / transparency. The range of alpha depends on
	 * the model of the color space. For RGB alpah will have a range of [0,
	 * 255]. For all other color spaces the range is [0, 100]. Zero always means
	 * that the color is completely transparent. The high value means that the
	 * color is completely opaque.
	 * 
	 * @return The value of transparency.
	 */
	public Float getAlpha();

	/**
	 * Returns the color space of the color.
	 * 
	 * @return The color space.
	 */
	public ColorSpace getColorSpace();

	/**
	 * Returns the name of the color space e.g. "RGBColor"
	 * 
	 * @return The name of the color space.
	 */
	public String getName();

	/**
	 * Returns a RGBColor representation of the current color. If the color is
	 * already a RGBColor, the original object will be return otherwise a new
	 * object will be created with converted color values. The resulting color
	 * referes to sRGB.
	 * 
	 * @return The RGBColor of the object.
	 */
	public RGBColor toRGB();

	/**
	 * Returns a HSBColor representation of the current color. If the color is
	 * already a HSBColor, the original object will be return otherwise a new
	 * object will be created with converted color values.
	 * 
	 * @return The HSBColor of the object.
	 */
	public HSBColor toHSB();

	/**
	 * Returns a XYZColor representation of the current color. If the color is
	 * already a XYZColor, the original object will be return otherwise a new
	 * object will be created with converted color values. The XYZColor refers
	 * to a D65/2° standard illuminant.
	 * 
	 * @return The XYZColor of the object.
	 */
	public XYZColor toXYZ();

	/**
	 * Returns a LabColor representation of the current color. If the color is
	 * already a LabColor, the original object will be return otherwise a new
	 * object will be created with converted color values. The conversion is
	 * done using the XYZColor.REFERENCE_X,Y and Z values as specific
	 * illuminants and observers.
	 * 
	 * @return The LabColor of the object.
	 */
	public LabColor toLab();

	/**
	 * Returns a LCHColor representation of the current color. If the color is
	 * already a LCHColor, the original object will be return otherwise a new
	 * object will be created with converted color values.
	 * 
	 * @return The LCHColor of the object.
	 */
	public LCHColor toLCH();

	/**
	 * Creates a deep copy of the object.
	 * 
	 * @return The copied object.
	 */
	public RColor copy();

	/**
	 * Checks if the input color is equal to this object. Two colors are equal
	 * if they are member of the same color space and all channel values are
	 * equal.
	 * 
	 * @param other
	 *            The other color
	 * @return True if both colors are considered the same;
	 */
	public boolean equals(RColor other);

}