package org.eclipse.swt.graphics;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved
 */

import org.eclipse.swt.*;

/**
 * Instances of this class describe the color data used by an image.
 * <p>
 * Depending on the depth of the image, the PaletteData can take one
 * of two forms, indicated by the isDirect field:
 * </p>
 * <dl>
 * <dt>
 * <em>isDirect is false</em>
 * </dt>
 * <dd>
 * If isDirect is <code>false</code>, this palette is an indexed
 * palette which maps pixel values to RGBs. The actual RGB values
 * may be retrieved by using the getRGBs() method.
 * </dd>
 * <dt>
 * <em>isDirect is true</em>
 * </dt>
 * <dd>
 * If isDirect is <code>true</code>, this palette is a direct color
 * palette. Instead of containing RGB values, it contains red,
 * green and blue mask and shift information which indicates how
 * the color components may be extracted from a given pixel.
 * This means that the RGB value is actually encoded in the pixel value.
 * <p>
 * In this case, the shift data is the number of bits required to shift
 * the RGB value to the left in order to align the high bit of the
 * corresponding mask with the high bit of the first byte. This number
 * may be negative, so care must be taken when shifting. For example,
 * with a red mask of 0xFF0000, the red shift would be -16. With a red
 * mask of 0x1F, the red shift would be 3.
 * </p>
 * </dd>
 * </dl>
 *
 * @see Image
 * @see RGB
 */
 
public final class PaletteData {
	
	/**
	 * true if the receiver is a direct palette, 
	 * and false otherwise
	 */
	public boolean isDirect;
	
	/**
	 * the RGB values for an indexed palette, where the
	 * indices of the array correspond to pixel values
	 */
	public RGB[] colors;
	
	/**
	 * the red mask for a direct palette
	 */
	public int redMask;
	
	/**
	 * the green mask for a direct palette
	 */
	public int greenMask;
	
	/**
	 * the blue mask for a direct palette
	 */
	public int blueMask;
	
	/**
	 * the red shift for a direct palette
	 */
	public int redShift;
	
	/**
	 * the green shift for a direct palette
	 */
	public int greenShift;
	
	/**
	 * the blue shift for a direct palette
	 */
	public int blueShift;

/**
 * Constructs a new indexed palette given an array of RGB values.
 *
 * @param colors the array of <code>RGB</code>s for the palette
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
 * </ul>
 */
public PaletteData(RGB[] colors) {
	if (colors == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	this.colors = colors;
	this.isDirect = false;
}

/**
 * Constructs a new direct palette given the red, green and blue masks.
 *
 * @param redMask the red mask
 * @param greenMask the green mask
 * @param blueMask the blue mask
 */
public PaletteData(int redMask, int greenMask, int blueMask) {
	this.redMask = redMask;
	this.greenMask = greenMask;
	this.blueMask = blueMask;
	this.isDirect = true;
	this.redShift = shiftForMask(redMask);
	this.greenShift = shiftForMask(greenMask);
	this.blueShift = shiftForMask(blueMask);
}

/**
 * Returns the pixel value corresponding to the given <code>RBG</code>.
 *
 * @return the pixel value for the given RGB
 * 
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the RGB is not found in the palette</li>
 * </ul>
 */
public int getPixel(RGB rgb) {
	if (rgb == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (isDirect) {
		int pixel = 0;
		pixel |= (redShift < 0 ? rgb.red << -redShift : rgb.red >>> redShift) & redMask;
		pixel |= (greenShift < 0 ? rgb.green << -greenShift : rgb.green >>> greenShift) & greenMask;
		pixel |= (blueShift < 0 ? rgb.blue << -blueShift : rgb.blue >>> blueShift) & blueMask;
		return pixel;
	} else {
		for (int i = 0; i < colors.length; i++) {
			if (colors[i].equals(rgb)) return i;
		}
		/* The RGB did not exist in the palette */
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		return 0;
	}
}

/**
 * Returns an <code>RGB</code> corresponding to the given pixel value.
 *
 * @return the RGB value for the given pixel
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the pixel does not exist in the palette</li>
 * </ul>
 */
public RGB getRGB(int pixel) {
	if (isDirect) {
		int r = pixel & redMask;
		r = (redShift < 0) ? r >>> -redShift : r << redShift;
		int g = pixel & greenMask;
		g = (greenShift < 0) ? g >>> -greenShift : g << greenShift;
		int b = pixel & blueMask;
		b = (blueShift < 0) ? b >>> -blueShift : b << blueShift;
		return new RGB(r, g, b);
	} else {
		if (pixel < 0 || pixel >= colors.length) {
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
		return colors[pixel];
	}
}

/**
 * Returns all the RGB values in the receiver if it is an
 * indexed palette, or null if it is a direct palette.
 *
 * @return the <code>RGB</code>s for the receiver or null
 */
public RGB[] getRGBs() {
	return colors;
}

/**
 * Computes the shift value for a given mask.
 *
 * @param mask the mask to compute the shift for
 * @return the shift amount
 *
 * @see PaletteData
 */
int shiftForMask(int mask) {
	for (int i = 31; i >= 0; i--) { 
		if (((mask >> i) & 0x1) != 0) return 7 - i;
	}
	return 32;
}

}
