/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.widgets;


import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;

/**
 * Instances of this class allow the user to select a color
 * from a predefined set of available colors.
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>(none)</dd>
 * <dt><b>Events:</b></dt>
 * <dd>(none)</dd>
 * </dl>
 * <p>
 * IMPORTANT: This class is intended to be subclassed <em>only</em>
 * within the SWT implementation.
 * </p>
 * 
 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample, Dialog tab</a>
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
 * @noextend This class is not intended to be subclassed by clients.
 */
public class ColorDialog extends Dialog {
	private static final int COLORSWATCH_SIZE_DEPTH4 = 40;
	private static final int COLORSWATCH_SIZE_DEPTH8 = 15;
	private static final int COLORSWATCH_SIZE_DEPTH16 = 10; 
	private static final int COLORSWATCH_BORDER = 1;	// border between each color pad

	private Shell shell;								// the dialog shell
	private Canvas colorsCanvas;
	private Label sampleLabel, selectionLabel;
	private Canvas sampleCanvas, selectionCanvas;
	private Button okButton, cancelButton;
	private int colorChooserWidth, colorChooserHeight;

	private boolean okSelected;
	private RGB rgb;
	private int colorSwatchExtent;						// the size of each color square
	private Color colorGrid[][];						// the colors displayed in the dialog
	
/**
 * Constructs a new instance of this class given only its parent.
 *
 * @param parent a composite control which will be the parent of the new instance
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 *
 * @see SWT
 * @see Widget#checkSubclass
 * @see Widget#getStyle
 */
public ColorDialog(Shell parent) {
	this (parent, SWT.APPLICATION_MODAL);
}
/**
 * Constructs a new instance of this class given its parent
 * and a style value describing its behavior and appearance.
 * <p>
 * The style value is either one of the style constants defined in
 * class <code>SWT</code> which is applicable to instances of this
 * class, or must be built by <em>bitwise OR</em>'ing together 
 * (that is, using the <code>int</code> "|" operator) two or more
 * of those <code>SWT</code> style constants. The class description
 * lists the style constants that are applicable to the class.
 * Style bits are also inherited from superclasses.
 * </p>
 *
 * @param parent a composite control which will be the parent of the new instance (cannot be null)
 * @param style the style of control to construct
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 *
 * @see SWT
 * @see Widget#checkSubclass
 * @see Widget#getStyle
 */
public ColorDialog(Shell parent, int style) {
	super (parent, checkStyle (parent, style));
	checkSubclass ();
}
void createChildren() {
	Shell dialog = shell;
	GridLayout layout = new GridLayout (2, false);
	dialog.setLayout(layout);
	
	colorChooserWidth = colorSwatchExtent * colorGrid.length - 1;
	colorChooserHeight = colorSwatchExtent * colorGrid[0].length - 1;
	colorsCanvas = new Canvas(dialog, SWT.BORDER);
	GridData data = new GridData ();
	data.widthHint = colorChooserWidth;
	data.heightHint = colorChooserHeight;
	colorsCanvas.setLayoutData(data);

	Composite buttonsGroup = new Composite (dialog, SWT.NONE);
	buttonsGroup.setLayout(new GridLayout());
	buttonsGroup.setLayoutData(new GridData(GridData.BEGINNING));
	createOkCancel(buttonsGroup);

	Composite bottomGroup = new Composite (dialog,SWT.NONE);
	layout = new GridLayout(2, true);
	layout.marginHeight = 0;
	layout.marginWidth = 0;
	bottomGroup.setLayout(layout);
	bottomGroup.setLayoutData(new GridData(GridData.FILL_BOTH));

	createSampleGroup(bottomGroup);
	createSelectionGroup(bottomGroup);
}
void createOkCancel(Composite parent) {
	okButton = new Button(parent, SWT.PUSH);
	okButton.setText(SWT.getMessage("SWT_OK"));
	shell.setDefaultButton(okButton);
	GridData data = new GridData(GridData.FILL_HORIZONTAL);
	okButton.setLayoutData(data);

	cancelButton = new Button(parent, SWT.PUSH);
	cancelButton.setText(SWT.getMessage("SWT_Cancel"));
	data = new GridData(GridData.FILL_HORIZONTAL);
	cancelButton.setLayoutData(data);
}
void createSampleGroup(Composite parent) {
	Group sampleGroup = new Group(parent, SWT.NULL);
	GridData data = new GridData(GridData.FILL_BOTH);
	data.grabExcessHorizontalSpace = true;
	sampleGroup.setLayout(new GridLayout());
	sampleGroup.setLayoutData(data);
	sampleGroup.setText(SWT.getMessage("SWT_Sample"));

	sampleLabel = new Label(sampleGroup, SWT.CENTER | SWT.BORDER);
	sampleLabel.setAlignment(SWT.CENTER);
	sampleLabel.setText(SWT.getMessage("SWT_A_Sample_Text"));
	data = new GridData(GridData.FILL_HORIZONTAL);
	sampleLabel.setLayoutData(data);

	sampleCanvas = new Canvas(sampleGroup, SWT.BORDER);
	data = new GridData(GridData.FILL_HORIZONTAL);
	data.heightHint = 15;
	sampleCanvas.setLayoutData(data);
}
void createSelectionGroup(Composite parent) {
	Group selectionGroup = new Group(parent, SWT.NULL);
	GridData data = new GridData(GridData.FILL_BOTH);
	data.grabExcessHorizontalSpace = true;
	selectionGroup.setLayout(new GridLayout());
	selectionGroup.setLayoutData(data);
	selectionGroup.setText(SWT.getMessage("SWT_Selection"));

	selectionLabel = new Label(selectionGroup, SWT.CENTER | SWT.BORDER);
	selectionLabel.setAlignment(SWT.CENTER);
	selectionLabel.setText(SWT.getMessage("SWT_Current_Selection"));
	data = new GridData(GridData.FILL_HORIZONTAL);
	data.grabExcessHorizontalSpace = true;
	selectionLabel.setLayoutData(data);

	selectionCanvas = new Canvas(selectionGroup, SWT.BORDER);
	data = new GridData(GridData.FILL_HORIZONTAL);
	data.grabExcessHorizontalSpace = true;
	data.heightHint = 15;
	selectionCanvas.setLayoutData(data);
}
void disposeColors() {
	for (int row = 0; row < colorGrid.length; row++) {
		for (int column = 0; column < colorGrid[row].length; column++) {
			colorGrid[row][column].dispose();
		}
	}
}
void drawColor(int xIndex, int yIndex, Color color, GC gc) {
	int colorExtent = colorSwatchExtent - COLORSWATCH_BORDER;
	gc.setBackground(color);	
	gc.fillRectangle(
		xIndex * colorSwatchExtent,
		yIndex * colorSwatchExtent, 
		colorExtent, colorExtent);
}
/**
 * Returns the currently selected color in the receiver.
 *
 * @return the RGB value for the selected color, may be null
 *
 * @see PaletteData#getRGBs
 */
public RGB getRGB() {
	return rgb;
}
void handleEvents(Event event) {
	if (event.type == SWT.Paint) {
		paint(event);
	}
	else
	if (event.type == SWT.MouseDown) {
		mouseDown(event);
	}	
	else
	if (event.type == SWT.MouseMove) {
		mouseMove(event);
	}
	else
	if (event.type == SWT.Selection) {
		if (event.widget == okButton) {
			okSelected = true;
			shell.setVisible(false);
		}
		else
		if (event.widget == cancelButton) {
			okSelected = false;
			shell.setVisible(false);
		}
	}	
}
void initialize4BitColors() {
	Display display = shell.display;
	
	colorGrid[0][0] = new Color(display, 0, 0, 0);
	colorGrid[0][1] = new Color(display, 255, 255, 255);
	colorGrid[1][0] = new Color(display, 128, 128, 128);
	colorGrid[1][1] = new Color(display, 192, 192, 192);
	
	colorGrid[2][0] = new Color(display, 0, 0, 128);
	colorGrid[2][1] = new Color(display, 0, 0, 255);
	colorGrid[3][0] = new Color(display, 0, 128, 128);
	colorGrid[3][1] = new Color(display, 0, 255, 255);
	
	colorGrid[4][0] = new Color(display, 0, 128, 0);
	colorGrid[4][1] = new Color(display, 0, 255, 0);
	colorGrid[5][0] = new Color(display, 128, 128, 0);
	colorGrid[5][1] = new Color(display, 255, 255, 0);

	colorGrid[6][0] = new Color(display, 128, 0, 0);
	colorGrid[6][1] = new Color(display, 255, 0, 0);
	colorGrid[7][0] = new Color(display, 128, 0, 128);
	colorGrid[7][1] = new Color(display, 255, 0, 255);
}
void initialize8BitColors() {
	Display display = shell.display;
	int numRows = colorGrid[0].length;
	int iterationStep = 64;
	int row = 0, column = 0;
	int red, green, blue;
	// run the loops from 0 to 256 inclusive since this is easiest for the step
	// size, then adjust the 256 case to the proper 255 value when needed
	for (red = 0; red <= 256; red += iterationStep) {
		for (blue = 0; blue <= 256; blue += iterationStep) {
			for (green = 0; green <= 256; green += iterationStep) {
				if (row == numRows) {
					row = 0;
					column++;
				}
				if (red == 256) red = 255;
				if (blue == 256) blue = 255;
				if (green == 256) green = 255;				
				colorGrid[column][row++] = new Color(display, red, green, blue);
			}
		}
	}
}
void initialize16BitColors() {
	Display display = shell.display;
	int numRows = colorGrid[0].length;
	int iterationStep = 51;
	int row = 0, column = 0;
	int red, green, blue;

	for (red = 0; red <= 255; red += iterationStep) {
		for (blue = 0; blue <= 255; blue += iterationStep) {
			if (blue == iterationStep && column < 20) {		// evenly distribute 256 colors on 32 columns
				blue += iterationStep;
			}
			for (green = 0; green <= 255; green += iterationStep) {
				if (row == 2 || row == 5) {					// evenly distribute 256 colors on 8 rows
					colorGrid[column][row++] = new Color(display, red, green - iterationStep / 2, blue);
				}
				if (row == numRows) {
					row = 0;
					column++;
				}
				colorGrid[column][row++] = new Color(display, red, green, blue);
			}
		}
	}
}
void initializeWidgets() {
	Display display = shell.display;
	if (rgb != null) {
		Color selectionColor = new Color(display, rgb);
		selectionCanvas.setBackground(selectionColor);
		selectionLabel.setBackground(selectionColor);
		selectionColor.dispose();
	}
}
void installListeners() {
	Listener listener = new Listener() {
		public void handleEvent(Event event) {handleEvents(event);}
	};
	okButton.addListener(SWT.Selection, listener);
	cancelButton.addListener(SWT.Selection, listener);
	colorsCanvas.addListener(SWT.Paint, listener);
	colorsCanvas.addListener(SWT.MouseDown, listener);
	colorsCanvas.addListener(SWT.MouseMove, listener);
}
void mouseDown(Event event) {
	int swatchExtent = colorSwatchExtent;
	Color color = colorGrid[event.x / swatchExtent][event.y / swatchExtent];
	selectionCanvas.setBackground(color);
	selectionLabel.setBackground(color);	
}
void mouseMove(Event event) {
	int swatchExtent = colorSwatchExtent;
	// adjust for events received from moving over the Canvas' border
	if (!(0 <= event.x && event.x <= colorChooserWidth)) return;
	if (!(0 <= event.y && event.y <= colorChooserHeight)) return;
	int xgrid = Math.min(colorGrid.length - 1, event.x / swatchExtent);
	int ygrid = Math.min(colorGrid[0].length - 1, event.y / swatchExtent);
	Color color = colorGrid[xgrid][ygrid];
	sampleCanvas.setBackground(color);
	sampleLabel.setBackground(color);
}
/**
 * Makes the receiver visible and brings it to the front
 * of the display.
 *
 * @return the selected color, or null if the dialog was
 *         cancelled, no color was selected, or an error
 *         occurred
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public RGB open() {
	shell = new Shell(parent, getStyle() | SWT.TITLE | SWT.BORDER | SWT.APPLICATION_MODAL);
	Display display = shell.display;
	setColorDepth(display.getDepth());
	createChildren();
	installListeners();
	openModal();
	if (okSelected) {
		Color selectionColor = selectionCanvas.getBackground();
		rgb = new RGB(
			selectionColor.getRed(), 
			selectionColor.getGreen(), 
			selectionColor.getBlue());
	}
	disposeColors();	
	if (shell.isDisposed() == false) {
		shell.dispose();
	}	
	if (!okSelected) return null;
	return rgb;
}
/**
 * Open the receiver and set its size to the size calculated by 
 * the layout manager.
 */
void openDialog() {
	Shell dialog = shell;
		
	// Start everything off by setting the shell size to its computed size.
	Point pt = dialog.computeSize(-1, -1, false);
	
	// Ensure that the width of the shell fits the display.
	Display display = dialog.display;
	Rectangle displayRect = display.getBounds();
	int widthLimit = displayRect.width * 7 / 8;
	int heightLimit = displayRect.height * 7 / 8;
	if (pt.x > widthLimit) {
		pt = dialog.computeSize (widthLimit, -1, false);
	}

	/*
	 * If the parent is visible then center this dialog on it,
	 * otherwise center this dialog on the parent's monitor
	 */
	Rectangle parentBounds = null;
	if (parent.isVisible ()) {
		parentBounds = getParent ().getBounds ();
	} else {
		parentBounds = parent.getMonitor ().getBounds ();
	}
	int originX = (parentBounds.width - pt.x) / 2 + parentBounds.x;
	originX = Math.max (originX, 0);
	originX = Math.min (originX, widthLimit - pt.x);
	int originY = (parentBounds.height - pt.y) / 2 + parentBounds.y;
	originY = Math.max (originY, 0);
	originY = Math.min (originY, heightLimit - pt.y);
	dialog.setBounds (originX, originY, pt.x, pt.y);

	String title = getText ();
	if (title.length () == 0) title = SWT.getMessage ("SWT_ColorDialog_Title");
	shell.setText(title);
	
	dialog.open();
}
void openModal() {
	Display display = shell.display;
	initializeWidgets();
	openDialog();
	while (shell.isDisposed() == false && shell.getVisible() == true) {
		if (display.readAndDispatch() == false) {
			display.sleep();
		}
	}
}
void paint(Event event) {
	for (int column = 0; column < colorGrid.length; column++) {
		for (int row = 0; row < colorGrid[0].length; row++) {
			drawColor(column, row, colorGrid[column][row], event.gc);			
		}
	}
}
void setColorDepth(int bits) {
	if (bits == 4) {
		colorSwatchExtent = COLORSWATCH_SIZE_DEPTH4;
		colorGrid = new Color[8][2];
		initialize4BitColors();
		return;
	}
	if (bits == 8) {
		colorSwatchExtent = COLORSWATCH_SIZE_DEPTH8;
		colorGrid = new Color[25][5];
		initialize8BitColors();
		return;				
	}
	// default case: 16, 24 or 32 bits
	colorSwatchExtent = COLORSWATCH_SIZE_DEPTH16;
	colorGrid = new Color[32][8];
	initialize16BitColors();
}
/**
 * Sets the receiver's selected color to be the argument.
 *
 * @param rgb the new RGB value for the selected color, may be
 *        null to let the platform select a default when
 *        open() is called
 * @see PaletteData#getRGBs
 */
public void setRGB(RGB rgb) {
	this.rgb = rgb;
}
}
