/** Represents a color with red, green, and blue components. */
public class Color {
	public static final Color BLACK = new Color(0.0f, 0.0f, 0.0f);
	public static final Color WHITE = new Color(1.0f, 1.0f, 1.0f);

	private float r;
	private float g;
	private float b;

	private boolean rgbKnown = false;
	private int rgb;

	/** Constructs a color with the given color components. */
	public Color(double r, double g, double b) {
		this((float) r, (float) g, (float) b);
	}

	/** Constructs a color with the given color components. */
	public Color(float r, float g, float b) {
		this.r = clamp(r, 0.0f, 1.0f);
		this.g = clamp(g, 0.0f, 1.0f);
		this.b = clamp(b, 0.0f, 1.0f);
	}

	public String toString() {
		return "Color[" + r + "," + g + "," + b + "]";
	}

	/** Returns the red color component. */
	public float getRed()   { return r; }
	/** Returns the green color component. */
	public float getGreen() { return g; }
	/** Returns the blue color component. */
	public float getBlue()  { return b; }

	/** Constructs a color whose color components are the sum of
	 * this color's components and the parameter color's
	 * components. */
	public Color add(Color other) {
		return new Color(this.r + other.r,
				this.g + other.g,
				this.b + other.b);
	}

	/** Returns the argb encoding of this color. */
	public int getRGB() {
		if(!rgbKnown) {
			rgb = 0xFF000000
				| ((int) (r * 255) << 16)
				| ((int) (g * 255) << 8)
				| ((int) (b * 255));
			rgbKnown = true;
		}
		return rgb;
	}

	private static float clamp(float value, float min, float max) {
		if(value < min) return min;
		if(value > max) return max;
		return value;
	}
}
