/*******************************************************************************
 * Copyright (c) 2000, 2009 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.*;

import java.util.*;

/**
 * Instances of this class allow the user to select a font
 * from all available fonts in the system.
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>(none)</dd>
 * <dt><b>Events:</b></dt>
 * <dd>(none)</dd>
 * </dl>
 * <p>
 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
 * </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 FontDialog extends Dialog {
	private FontData [] fontData;
	private FontData currentFontData;
	private Font sampleFont;	// the displayed sample font
	private Color sampleColor;	// the displayed sample color
	private RGB rgb;
	private boolean okSelected = false;
	private boolean ignoreEvents = false;
	/*
	 * Table containing all available fonts as FontData objects.
	 * The table is structured as a series of embedded Hashtables as follows:
	 * <br>characterRegistryName -> faceName -> extendedStyle -> size -> style
	 */
	private Hashtable characterSets = new Hashtable ();

	// widgets	
	private Shell shell;
	private List fontSetList;
	private List charSetList, faceNameList, extStyleList;
	private List fontStyleList, fontSizeList;
	private Label sampleLabel;
	private Button upButton, downButton, newButton, removeButton;
	private Button okButton, cancelButton, colorButton;	

	// constants
	private static final String TEXT_SAMPLE = "AaBbYyZz";
	private static String SCALABLE_SIZES [];
	private static final int DEFAULT_SIZE = 14;
	private static final String DEFAULT_STYLE = "medium";
	private static final Integer SCALABLE_KEY = new Integer (0);
	private static final int LIST_WIDTH = 200;
	private static final int EXTSTYLE_WIDTH = 150;
	private static final int LIST_HEIGHT = 150;
	private static final int SAMPLE_HEIGHT = 75;
	private static final String PREFIX_ISO8859 = "iso8859";
	private static final String PREFIX_ISO646 = "iso646";
	private static final String PREFIX_UNICODE = "ucs";
	private static final String PREFIX_JAPANESE = "jis";
	private static final String PREFIX_SIMPLIFIEDCHINESE = "gb";
	private static final String PREFIX_TRADITIONALCHINESE = "cns";
	private static final String PREFIX_KOREAN = "ks";
	private static final String [] ISO_CHARSETS = new String [] {
		"",	// 0 undefined
		SWT.getMessage ("SWT_Charset_Western"),
		SWT.getMessage ("SWT_Charset_EastEuropean"),
		SWT.getMessage ("SWT_Charset_SouthEuropean"),
		SWT.getMessage ("SWT_Charset_NorthEuropean"),
		SWT.getMessage ("SWT_Charset_Cyrillic"),
		SWT.getMessage ("SWT_Charset_Arabic"),
		SWT.getMessage ("SWT_Charset_Greek"),
		SWT.getMessage ("SWT_Charset_Hebrew"),
		SWT.getMessage ("SWT_Charset_Turkish"),
		SWT.getMessage ("SWT_Charset_Nordic"),
		SWT.getMessage ("SWT_Charset_Thai"),
		"",	// 12 undefined
		SWT.getMessage ("SWT_Charset_BalticRim"),
		SWT.getMessage ("SWT_Charset_Celtic"),
		SWT.getMessage ("SWT_Charset_Euro"),
		SWT.getMessage ("SWT_Charset_Romanian")
	};

	static {
		SCALABLE_SIZES = new String [69];
		for (int i = 0; i < 69; i++) {
			SCALABLE_SIZES [i] = String.valueOf (i + 4);
		}
	}

/**
 * Constructs a new instance of this class given only its parent.
 *
 * @param parent a shell 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>
 */
public FontDialog (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 shell which will be the parent of the new instance
 * @param style the style of dialog 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>
 */
public FontDialog (Shell parent, int style) {
	super (parent, checkStyle (parent, style));
	checkSubclass ();
}

/**
 * Add the fonts found in 'fonts' to the list of fonts.
 * Fonts are stored by character set and face name. For each character 
 * set/face name combination there is one FontExtStyles object that 
 * captures the different extended styles and the sizes and styles 
 * available for that extended style.
 */
void addFonts (FontData fonts []) {
	for (int i = 0; i < fonts.length; i++) {
		FontData font = fonts [i];
		String charSetName = getTranslatedCharSet (font, true);
		Hashtable charSet = (Hashtable) characterSets.get (charSetName);
		if (charSet == null) {
			charSet = new Hashtable (9);
			characterSets.put (charSetName, charSet);
		}

		String faceName = getTranslatedFaceName (font);
		Hashtable faceSet = (Hashtable) charSet.get (faceName);
		if (faceSet == null) {
			faceSet = new Hashtable (9);
			charSet.put (faceName, faceSet);
		}

		String extStyleName = font.addStyle;
		Hashtable extStyleSet = (Hashtable) faceSet.get (extStyleName);
		if (extStyleSet == null) {
			extStyleSet = new Hashtable (9);
			faceSet.put (extStyleName, extStyleSet);
		}
		
		Integer sizeValue = new Integer (font.getHeight ());
		Hashtable sizeSet = (Hashtable) extStyleSet.get (sizeValue);
		if (sizeSet == null) {
			sizeSet = new Hashtable (9);
			extStyleSet.put (sizeValue, sizeSet);
		}
		
		String style = font.weight;
		sizeSet.put (style,font);
	}
}

void centerListIndex (List list, int index) {
	int visibleItems = list.getSize ().y / list.getItemHeight ();
	int topIndex = Math.max (0, index - visibleItems / 2);
	list.setTopIndex (topIndex);
}

FontData copyFontData (FontData data) {
	FontData result = new FontData ();
	result.addStyle = data.addStyle;
	result.averageWidth = data.averageWidth;
	result.characterSetName = data.characterSetName;
	result.characterSetRegistry = data.characterSetRegistry;
	result.fontFamily = data.fontFamily;
	result.foundry = data.foundry;
	result.horizontalResolution = data.horizontalResolution;
	result.pixels = data.pixels;
	result.points = data.points;
	result.setWidth = data.setWidth;
	result.slant = data.slant;
	result.spacing = data.spacing;
	result.verticalResolution = data.verticalResolution;
	result.weight = data.weight;
	return result;
}

void createButtons (Composite parent) {
	int buttonAlignment = GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING;
	okButton = new Button (parent, SWT.PUSH);
	okButton.setText (SWT.getMessage ("SWT_OK"));
	okButton.setLayoutData (new GridData (buttonAlignment));
	shell.setDefaultButton (okButton);
	
	cancelButton = new Button (parent, SWT.PUSH);
	cancelButton.setText (SWT.getMessage ("SWT_Cancel"));
	cancelButton.setLayoutData (new GridData (buttonAlignment));

	colorButton = new Button (parent, SWT.PUSH);
	colorButton.setText (SWT.getMessage ("SWT_Color"));
	colorButton.setLayoutData (new GridData (buttonAlignment));
}

void createControls (Composite parent) {
	Composite composite = new Composite (parent, SWT.NONE);
	GridLayout layout = new GridLayout ();
	layout.numColumns = 2;
	composite.setLayout (layout);

	Composite controls = new Composite (composite, SWT.NONE);
	layout = new GridLayout ();
	layout.marginHeight = layout.marginWidth = 0;
	layout.numColumns = 3;
	controls.setLayout (layout);
	
	// labels row (1)
	new Label (controls, SWT.NONE).setText (SWT.getMessage ("SWT_Character_set") + ":");
	new Label (controls, SWT.NONE).setText (SWT.getMessage ("SWT_Font") + ":");
	new Label (controls, SWT.NONE).setText (SWT.getMessage ("SWT_Extended_style") + ":");	

	// lists row (2)
	charSetList = new List (controls, SWT.V_SCROLL | SWT.BORDER);
	GridData gridData = new GridData (GridData.FILL_HORIZONTAL);
	gridData.heightHint = LIST_HEIGHT;
	gridData.widthHint = LIST_WIDTH;
	charSetList.setLayoutData (gridData);

	faceNameList = new List (controls, SWT.V_SCROLL | SWT.BORDER);
	gridData = new GridData (GridData.FILL_HORIZONTAL);
	gridData.heightHint = LIST_HEIGHT;
	gridData.widthHint = LIST_WIDTH;
	faceNameList.setLayoutData (gridData);

	extStyleList = new List (controls, SWT.V_SCROLL | SWT.MULTI | SWT.BORDER);
	gridData = new GridData (GridData.FILL_HORIZONTAL);
	gridData.heightHint = LIST_HEIGHT;
	gridData.widthHint = EXTSTYLE_WIDTH;
	extStyleList.setLayoutData (gridData);

	// labels row (3)
	new Label (controls, SWT.NONE).setText (SWT.getMessage ("SWT_Size") + ":");	
	new Label (controls, SWT.NONE).setText (SWT.getMessage ("SWT_Style") + ":");
	new Label (controls, SWT.NONE);		// filler

	// lists row (4)
	fontSizeList = new List (controls, SWT.V_SCROLL | SWT.BORDER);
	gridData = new GridData (GridData.FILL_HORIZONTAL);
	gridData.heightHint = LIST_HEIGHT;
	gridData.widthHint = LIST_WIDTH;
	fontSizeList.setLayoutData (gridData);

	fontStyleList = new List (controls, SWT.V_SCROLL | SWT.BORDER);
	gridData = new GridData (GridData.FILL_HORIZONTAL);
	gridData.heightHint = LIST_HEIGHT;
	gridData.widthHint = LIST_WIDTH;
	fontStyleList.setLayoutData (gridData);

	new Label (controls, SWT.NONE);		// filler

	// font sets group
	Group fontSetGroup = new Group (controls, SWT.NONE);
	fontSetGroup.setText(SWT.getMessage ("SWT_FontSet"));
	layout = new GridLayout ();
	layout.numColumns = 2;
	fontSetGroup.setLayout (layout);
	GridData data = new GridData (GridData.FILL_BOTH);
	data.horizontalSpan = 3;
	fontSetGroup.setLayoutData (data);

	fontSetList = new List (fontSetGroup, SWT.V_SCROLL | SWT.BORDER);
	data = new GridData (GridData.FILL_BOTH);
	data.grabExcessHorizontalSpace = true;
	fontSetList.setLayoutData (data);

	Composite buttonsGroup = new Composite (fontSetGroup, SWT.NONE);
	layout = new GridLayout ();
	layout.numColumns = 3;
	layout.makeColumnsEqualWidth = false;
	layout.marginHeight = layout.marginWidth = 0;
	layout.horizontalSpacing = layout.verticalSpacing = 0; 
	buttonsGroup.setLayout (layout);
	
	Composite upDownButtonsGroup = new Composite (buttonsGroup, SWT.NONE);
	layout = new GridLayout ();
	layout.marginHeight = layout.marginWidth = 0;
	layout.horizontalSpacing = layout.verticalSpacing = 0; 
	upDownButtonsGroup.setLayout(layout);

	int buttonAlignment = GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING;
	upButton = new Button (upDownButtonsGroup, SWT.PUSH);
	upButton.setLayoutData (new GridData (buttonAlignment));
	upButton.setText (SWT.getMessage ("SWT_Up"));
	downButton = new Button (upDownButtonsGroup, SWT.PUSH);
	downButton.setLayoutData (new GridData (buttonAlignment));
	downButton.setText (SWT.getMessage ("SWT_Down"));

	new Label (buttonsGroup, SWT.SEPARATOR | SWT.VERTICAL);	

	Composite newRemoveButtonsGroup = new Composite (buttonsGroup, SWT.NONE);
	layout = new GridLayout ();
	layout.marginHeight = layout.marginWidth = 0;
	layout.horizontalSpacing = layout.verticalSpacing = 0; 
	newRemoveButtonsGroup.setLayout(layout);
		
	newButton = new Button (newRemoveButtonsGroup, SWT.PUSH);
	newButton.setLayoutData (new GridData (buttonAlignment));
	newButton.setText (SWT.getMessage ("SWT_NewFont"));
	removeButton = new Button (newRemoveButtonsGroup, SWT.PUSH);
	removeButton.setLayoutData (new GridData (buttonAlignment));
	removeButton.setText (SWT.getMessage ("SWT_Remove"));
	
	// font sample group
	Group sampleGroup = new Group (controls, SWT.NONE);
	sampleGroup.setText (SWT.getMessage ("SWT_Sample"));
	gridData = new GridData ();
	gridData.heightHint = SAMPLE_HEIGHT;	
	gridData.horizontalSpan = 3;
	gridData.horizontalAlignment = GridData.FILL;	
	sampleGroup.setLayoutData (gridData);
	layout = new GridLayout ();
	layout.marginWidth = 10;
	layout.marginHeight = 10;
	sampleGroup.setLayout (layout);
	
	sampleLabel = new Label (sampleGroup, SWT.CENTER);
	sampleLabel.setText (TEXT_SAMPLE);
	gridData = new GridData ();
	gridData.grabExcessHorizontalSpace = true;
	gridData.grabExcessVerticalSpace = true;	
	gridData.verticalAlignment = GridData.FILL;	
	gridData.horizontalAlignment = GridData.FILL;	
	sampleLabel.setLayoutData (gridData);
	
	Composite okCancelGroup = new Composite (composite, SWT.NONE);
	layout = new GridLayout ();
	layout.marginHeight = layout.marginWidth = layout.verticalSpacing = 0;
	okCancelGroup.setLayout (layout);
	okCancelGroup.setLayoutData (new GridData (GridData.VERTICAL_ALIGN_BEGINNING));
	createButtons (okCancelGroup);
}

Hashtable getExtStyles (String charsetName, String faceName) {
	Hashtable faces = getFaces (charsetName);
	if (faces == null) return null;
	return (Hashtable) faces.get (faceName);
}

Hashtable getFaces (String charsetName) {
	return (Hashtable) getFonts ().get (charsetName);
}

/**
 * Returns a FontData object describing the font that was
 * selected in the dialog, or null if none is available.
 * 
 * @return the FontData for the selected font, or null
 * @deprecated use #getFontList ()
 */
public FontData getFontData () {
	if (fontData != null && fontData.length > 0) {
		return fontData [0];
	}
	return null;

}

FontData getFontData (String charsetName, String faceName, String extStyle, int size, String style) {
	Hashtable styles = getStyles (charsetName, faceName, extStyle, size);
	if (styles == null) return null;
	return (FontData) styles.get (style);
}

/**
 * Returns a FontData set describing the font that was
 * selected in the dialog, or null if none is available.
 * 
 * @return the FontData for the selected font, or null
 * @since 2.1.1
 */
public FontData [] getFontList () {
	return fontData;
}

/**
 * Returns the collection of fonts that are displayed by the 
 * receiver.
 * See the class definition for an explanation of the structure
 * of the returned Hashtable.
 */
Hashtable getFonts () {
	return characterSets;
}

String getListSelection (List list) {
	String [] selection = list.getSelection ();
	if (selection.length > 0) return selection [0];
	return "";
}

/**
 * Returns an RGB describing the color that was selected
 * in the dialog, or null if none is available.
 *
 * @return the RGB value for the selected color, or null
 *
 * @see PaletteData#getRGBs
 * 
 * @since 2.1
 */
public RGB getRGB () {
	return rgb;
}

/**
 * Returns a FontData object that can be used to load the selected 
 * font.
 */
FontData getSelectionFontData () {
	String charSetName = getListSelection (charSetList);
	String faceName = getListSelection (faceNameList);
	String extStyle = getListSelection (extStyleList);
	int size = DEFAULT_SIZE;
	try {
		size = Integer.valueOf (getListSelection (fontSizeList)).intValue ();
		if (size < 1) size = DEFAULT_SIZE;
	} catch (NumberFormatException e) {
		/*
		 * This block is purposely left empty since a default
		 * value is already specified above.
		 */
	}
	String style = getListSelection (fontStyleList);
	FontData result = getFontData (charSetName, faceName, extStyle, size, style);

	if (result != null) {
		result = copyFontData (result);
	} else {
		/*
		* One or more of the dialog's widgets contain custom typed values.
		* Create a FontData that mirrors these values so that the Font created
		* below will try to find the best match.
		*/
		result = new FontData ();
		result.characterSetRegistry = charSetName;
		result.setName (faceName);
		result.addStyle = extStyle;
		result.weight = style;
	}
	result.setHeight (size);
	return result;
}

Hashtable getSizes (String charsetName, String faceName, String extStyle) {
	Hashtable extStyles = getExtStyles (charsetName, faceName);
	if (extStyles == null) return null;
	return (Hashtable) extStyles.get (extStyle);
}

Hashtable getStyles (String charsetName, String faceName, String extStyle, int size) {
	Hashtable sizes = getSizes (charsetName, faceName, extStyle);
	if (sizes == null) return null;
	Hashtable result = (Hashtable) sizes.get (new Integer (size));
	if (result == null)
		result = (Hashtable) sizes.get (SCALABLE_KEY);
	return result;
}
	
/**
 * Returns the character set found in 'fontData' prefixed
 * with a string explaining the character set.
 */
String getTranslatedCharSet (FontData fontData, boolean includeDescription) {
	String characterSet = fontData.characterSetRegistry;
	String translatedCharSet = null;

	if (characterSet.startsWith (PREFIX_ISO8859)) {
		int charSetName = 1;
		try {
			charSetName = Integer.valueOf (fontData.characterSetName).intValue ();
		} catch (NumberFormatException e) {
			/*
			 * This block is purposely left empty since a default
			 * value is already specified above.
			 */
		}
		characterSet = PREFIX_ISO8859 + "-" + charSetName;
		if (charSetName < ISO_CHARSETS.length) {
			translatedCharSet = ISO_CHARSETS [charSetName];
		}
	}
	else	
	if (characterSet.startsWith (PREFIX_ISO646)) {
		translatedCharSet = SWT.getMessage("SWT_Charset_ASCII");
	}
	else	
	if (characterSet.startsWith (PREFIX_UNICODE)) {
		translatedCharSet = SWT.getMessage("SWT_Charset_Unicode");
	}
	else	
	if (characterSet.startsWith (PREFIX_JAPANESE)) {
		translatedCharSet = SWT.getMessage("SWT_Charset_Japanese");
	}
	else	
	if (characterSet.startsWith (PREFIX_SIMPLIFIEDCHINESE)) {
		translatedCharSet = SWT.getMessage("SWT_Charset_SimplifiedChinese");
	}
	else	
	if (characterSet.startsWith (PREFIX_TRADITIONALCHINESE)) {
		translatedCharSet = SWT.getMessage("SWT_Charset_TraditionalChinese");
	}
	else	
	if (characterSet.startsWith (PREFIX_KOREAN)) {
		translatedCharSet = SWT.getMessage("SWT_Charset_Korean");
	}
	if (includeDescription && translatedCharSet != null) {
		translatedCharSet = characterSet + " (" + translatedCharSet + ')';
	}
	else {
		translatedCharSet = characterSet;
	}
	return translatedCharSet;
}

/**
 * Returns the face name as specified in FontData.familyName followed by
 * the foundry set in parantheses if available.
 * We display the face name first so that the list sorts the fonts by 
 * face name, not by foundry. Users generally want to select fonts based 
 * on the face name and not by foundry. Once they've found the desired 
 * face name in the list they can compare the font variations from 
 * different foundries if available.
 */
String getTranslatedFaceName (FontData fontData) {
	StringBuffer faceNameBuffer;
	
	if (fontData.foundry != null && fontData.foundry.length () > 0) {
		faceNameBuffer = new StringBuffer (fontData.fontFamily);
		faceNameBuffer.append (" (");
		faceNameBuffer.append (fontData.foundry);
		faceNameBuffer.append (')');			
	}
	else {
		faceNameBuffer = new StringBuffer (fontData.getName ());
	}
	return faceNameBuffer.toString ();
}

/**
 * Handle the events the receiver is listening to.
 * List selections cause the downstream lists to be initialized 
 * with font data and the sample text to be updated.
 */
void handleEvent (Event event) {
	if (ignoreEvents) return;
	if (event.widget instanceof List) {
		List list = (List) event.widget;
		String text = getListSelection (list);
		int oldSelectIndex = ((Integer)list.getData ()).intValue ();
		int newSelectIndex = list.indexOf (text);
		if (oldSelectIndex != newSelectIndex || newSelectIndex == -1) {
			ignoreEvents = true;
			if (list == charSetList) initFaceNameList ();
			else if (list == faceNameList) initExtStyleList ();
			else if (list == extStyleList) initSizeList ();
			else if (list == fontSizeList) initStyleList ();
			else if (event.widget == fontSetList) {
				currentFontData = fontData [fontSetList.getSelectionIndex ()];
				setFontControls (currentFontData);
				updateButtonEnablements ();
			}
	
			updateSampleFont ();
			updateFontList ();
			list.setData (new Integer (newSelectIndex));
			if (newSelectIndex != -1) {
				list.select (newSelectIndex);
			}
			ignoreEvents = false;
		}
		return;
	}
	
	if (event.widget instanceof Button) {
		if (event.widget == okButton) {
			okSelected = true;
			shell.close ();
		}
		else if (event.widget == cancelButton) {
			okSelected = false;
			shell.close ();
		}
		else if (event.widget == colorButton) {
			ColorDialog colorDialog = new ColorDialog (shell, SWT.NONE);
			colorDialog.setRGB (rgb);
			RGB newRgb = colorDialog.open ();
			if (newRgb != null) {
				rgb = newRgb;
				updateSampleColor ();
			}
		}
		else if (event.widget == newButton) {
			FontData [] newFontData = new FontData [fontData.length + 1];
			System.arraycopy (fontData, 0, newFontData, 0, fontData.length);
			FontData source = fontData [fontSetList.getSelectionIndex ()];
			FontData newFd = copyFontData (source);
			newFontData [newFontData.length - 1] = newFd;
			this.fontData = newFontData;
			updateFontList ();
			fontSetList.select (newFontData.length - 1);
			fontSetList.setData (new Integer (newFontData.length - 1));
			fontSetList.showSelection();
			updateButtonEnablements ();
		}
		else if (event.widget == removeButton) {
			int selectionIndex = fontSetList.getSelectionIndex ();
			FontData [] newFontData = new FontData [fontData.length - 1];
			System.arraycopy (fontData, 0, newFontData, 0, selectionIndex);
			System.arraycopy (fontData, selectionIndex + 1, newFontData, selectionIndex, newFontData.length - selectionIndex);
			fontData = newFontData;
			updateFontList ();
			updateButtonEnablements ();
			setFontControls (fontData [fontSetList.getSelectionIndex ()]);
		}
		else if (event.widget == upButton) {
			int selectionIndex = fontSetList.getSelectionIndex ();
			FontData temp = fontData [selectionIndex];
			fontData [selectionIndex] = fontData [selectionIndex - 1];
			fontData [selectionIndex - 1] = temp;
			fontSetList.select (selectionIndex - 1);
			fontSetList.setData (new Integer (selectionIndex - 1));
			updateFontList ();
			updateButtonEnablements ();
		}
		else if (event.widget == downButton) {
			int selectionIndex = fontSetList.getSelectionIndex ();
			FontData temp = fontData [selectionIndex];
			fontData [selectionIndex] = fontData [selectionIndex + 1];
			fontData [selectionIndex + 1] = temp;
			fontSetList.select (selectionIndex + 1);
			fontSetList.setData (new Integer (selectionIndex + 1));
			updateFontList ();
			updateButtonEnablements ();
		}
	}
}

void hookListeners () {
	Listener listener = new Listener () {
		public void handleEvent (Event event) {
			FontDialog.this.handleEvent (event);
		}
	};
	okButton.addListener (SWT.Selection, listener);
	cancelButton.addListener (SWT.Selection, listener);
	colorButton.addListener (SWT.Selection, listener);	
	charSetList.addListener (SWT.Selection, listener);
	faceNameList.addListener (SWT.Selection, listener);
	fontStyleList.addListener (SWT.Selection, listener);
	extStyleList.addListener (SWT.Selection, listener);
	fontSizeList.addListener (SWT.Selection, listener);
	newButton.addListener (SWT.Selection, listener);
	removeButton.addListener (SWT.Selection, listener);
	upButton.addListener (SWT.Selection, listener);
	downButton.addListener (SWT.Selection, listener);
	fontSetList.addListener (SWT.Selection, listener);
}

/**
 * Initialize the extended styles list with the extended styles
 * available for the selected font.
 * Downstream lists are initialized as well (style and size).
 */
void initExtStyleList () {
	String oldSelect = getListSelection (extStyleList);
	extStyleList.removeAll ();
	
	String characterSet = getListSelection (charSetList);
	String faceName = getListSelection (faceNameList);
	Hashtable extStyles = getExtStyles (characterSet, faceName);
	setItemsSorted (extStyleList, extStyles);
	
	int selectIndex = extStyleList.indexOf (oldSelect);
	extStyleList.select (selectIndex);
	extStyleList.setData (new Integer (selectIndex));
	centerListIndex (extStyleList, selectIndex);
	initSizeList ();
}

/**
 * Initialize the face name list with all font names 
 * available in the selected character set.
 * Downstream lists are initialized as well (extended style).
 */
void initFaceNameList () {
	String oldSelect = getListSelection (faceNameList);
	faceNameList.removeAll ();
	String charSetText = getListSelection (charSetList);
	if (charSetText.length () == 0) return;
	
	Hashtable faceNames = getFaces (charSetText);
	setItemsSorted (faceNameList, faceNames);
	
	int selectIndex = faceNameList.indexOf (oldSelect);
	selectIndex = Math.max (0, selectIndex);
	faceNameList.select (selectIndex);
	faceNameList.setData (new Integer (selectIndex));
	centerListIndex (faceNameList, selectIndex);
	initExtStyleList ();
}

/**
 * Initialize the widgets of the receiver with the data of 
 * all installed fonts.  If the user specified a default font
 * preselect that font in the lists.
 */
void initFonts () {
	Display display = shell.display;
	// get all fonts available on the current display
	addFonts (display.getFontList (null, false));
	addFonts (display.getFontList (null, true));
	setItemsSorted (charSetList, getFonts ());
	if (fontData != null) {
		// verify that the initial font data is a valid font
		Font font = new Font (display, fontData);
		fontData = font.getFontData ();
		currentFontData = fontData [0];
		font.dispose ();
	} else {
		fontData = display.textFont.getFontData ();
		currentFontData = fontData [0];
	}
}

/**
 * Initialize the size list with the sizes the selected font 
 * is available in.  If the selected font is scalable a selection
 * of preset sizes is used.
 */
void initSizeList () {
	String oldSelect = getListSelection (fontSizeList);
	fontSizeList.removeAll ();
	
	String characterSet = getListSelection (charSetList);
	String faceName = getListSelection (faceNameList);
	String extStyle = getListSelection (extStyleList);
	Hashtable sizes = getSizes (characterSet, faceName, extStyle);
	if (sizes != null) {
		if (sizes.get (SCALABLE_KEY) == null) {
			/*
			 * Font is not scalable so just present the provided sizes.
			 */
			setSizeItemsSorted (sizes.keys ());
		} else {
			/*
			 * Font is scalable so present the provided sizes and scalable
			 * sizes for selection.
			 */
			Vector allSizes = new Vector ();
			/*
			 * Add the scalable sizes.
			 */
			for (int i = 0; i < SCALABLE_SIZES.length; i++) {
				allSizes.addElement (Integer.valueOf (SCALABLE_SIZES [i]));
			}
			/*
			 * Add the provided sizes.
			 */
			Enumeration providedSizes = sizes.keys ();
			while (providedSizes.hasMoreElements ()) {
				Integer size = (Integer) providedSizes.nextElement ();
				if (!size.equals (SCALABLE_KEY) && !allSizes.contains (size)) {
					allSizes.addElement (size);
				}
			}
			setSizeItemsSorted (allSizes.elements ());
		}
	}
	
	int selectIndex = fontSizeList.indexOf (oldSelect);
	if (selectIndex == -1) {
		selectIndex = fontSizeList.indexOf (String.valueOf (DEFAULT_SIZE));
	}
	selectIndex = Math.max (0, selectIndex);
	fontSizeList.select (selectIndex);
	fontSizeList.setData (new Integer (selectIndex));
	centerListIndex (fontSizeList, selectIndex);
	initStyleList ();
}

/**
 * Initialize the styles list with the styles the selected font 
 * is available in.
 */
void initStyleList () {
	String oldSelect = getListSelection (fontStyleList);
	fontStyleList.removeAll ();
	
	String characterSet = getListSelection (charSetList);
	String faceName = getListSelection (faceNameList);
	String extStyle = getListSelection (extStyleList);
	try {
		int size = Integer.valueOf (getListSelection (fontSizeList)).intValue ();
		if (size > 0) {
			Hashtable styles = getStyles (characterSet, faceName, extStyle, size);
			setItemsSorted (fontStyleList, styles);
		}
	} catch (NumberFormatException e) {
		// fall through
	}

	int selectIndex = fontStyleList.indexOf (oldSelect);
	if (selectIndex == -1) {
		selectIndex = fontStyleList.indexOf (String.valueOf (DEFAULT_STYLE));
	}
	selectIndex = Math.max (0, selectIndex);
	fontStyleList.select (selectIndex);
	fontStyleList.setData (new Integer (selectIndex));
	centerListIndex (fontStyleList, selectIndex);
}

/**
 * Makes the dialog visible and brings it to the front
 * of the display.
 *
 * @return a FontData object describing the font that was selected,
 *         or null if the dialog was cancelled or an error occurred
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the dialog has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the dialog</li>
 * </ul>
 */
public FontData open () {
	shell = new Shell (getParent (), getStyle () | SWT.TITLE | SWT.BORDER | SWT.APPLICATION_MODAL);
	shell.setLayout (new GridLayout ());
	createControls (shell);
	
	FontData [] originalFontData = fontData;
	RGB originalRGB = rgb;
	initFonts ();
	openDialog ();
	setFontControls (currentFontData);
	updateSampleFont ();
	updateSampleColor ();
	updateFontList ();
	fontSetList.select (0);
	fontSetList.setData (new Integer (0));
	updateButtonEnablements ();
	hookListeners ();
	Display display = shell.display;
	while (!shell.isDisposed ()) {
		if (!display.readAndDispatch ()) display.sleep ();
	}
	
	FontData result = null;
	if (okSelected) {
		result = fontData [0];
	} else {
		fontData = originalFontData;
		rgb = originalRGB;
	}	
	if (sampleFont != null) sampleFont.dispose ();
	sampleFont = null;
	if (sampleColor != null) sampleColor.dispose ();
	sampleColor = null;
	return result;
}

/**
 * Open the receiver and set its size to the size calculated by 
 * the layout manager.
 */
void openDialog () {
	// Start everything off by setting the shell size to its computed size.
	Point pt = shell.computeSize (SWT.DEFAULT, SWT.DEFAULT, false);
	
	// Ensure that the width of the shell fits the display.
	Display display = shell.display;
	Rectangle displayRect = display.getBounds ();
	int widthLimit = displayRect.width * 7 / 8;
	int heightLimit = displayRect.height * 7 / 8;
	if (pt.x > widthLimit) {
		pt = shell.computeSize (widthLimit, SWT.DEFAULT, 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);
	shell.setBounds (originX, originY, pt.x, pt.y);
	
	String title = getText ();
	if (title.length () == 0) title = SWT.getMessage ("SWT_FontDialog_Title");
	shell.setText (title);
	
	// Open the window.
	shell.open ();
}

/**
 * Initialize the lists with the data of the preselected
 * font specified by the user.
 */
void setFontControls (FontData fontData) {
	ignoreEvents = true;
	String characterSet = getTranslatedCharSet (fontData, true);
	String faceName = getTranslatedFaceName (fontData);
	charSetList.select (new String[] {characterSet});
	int index = charSetList.indexOf (characterSet);
	charSetList.setData (new Integer (index));
	if (index != -1) centerListIndex (charSetList, index);

	initFaceNameList ();
	faceNameList.select (new String[] {faceName});
	index = faceNameList.indexOf (faceName);
	faceNameList.setData (new Integer (index));
	if (index != -1) centerListIndex (faceNameList, index);

	initExtStyleList ();
	extStyleList.select (new String[] {fontData.addStyle});
	index = extStyleList.indexOf (fontData.addStyle);
	extStyleList.setData (new Integer (index));
	if (index != -1) centerListIndex (extStyleList, index);

	initSizeList ();
	String value = String.valueOf (fontData.getHeight ());
	fontSizeList.select (new String[] {value});
	index = fontSizeList.indexOf (value);
	fontSizeList.setData (new Integer (index));
	if (index != -1) centerListIndex (fontSizeList, index);

	initStyleList ();
	fontStyleList.select (new String[] {fontData.weight});
	index = fontStyleList.indexOf (fontData.weight);
	fontStyleList.setData (new Integer (index));
	if (index != -1) centerListIndex (fontStyleList, index);
	ignoreEvents = false;
}

/**
 * Sets a FontData object describing the font to be
 * selected by default in the dialog, or null to let
 * the platform choose one.
 * 
 * @param fontData the FontData to use initially, or null
 * @deprecated use #setFontList (FontData [])
 */
public void setFontData (FontData fontData) {
	if (fontData == null) {
		this.fontData = null;
	} else {
		this.fontData = new FontData [1];
		this.fontData [0] = fontData;
	}
}

/**
 * Sets the set of FontData objects describing the font to
 * be selected by default in the dialog, or null to let
 * the platform choose one.
 * 
 * @param fontData the set of FontData objects to use initially, or null
 *        to let the platform select a default when open() is called
 *
 * @see Font#getFontData
 * 
 * @since 2.1.1
 */
public void setFontList (FontData [] fontData) {
	this.fontData = fontData;
}

/**
 * Set the contents of 'list' to the keys of 'items'.
 * Keys are sorted in ascending order first and have to be Strings.
 */
void setItemsSorted (List list, Hashtable items) {
	if (items == null) return;
	Enumeration itemKeys = items.keys ();
	String [] sortedItems = new String [items.size ()];
	int index = 0;
	while (itemKeys.hasMoreElements ()) {
		String item = (String) itemKeys.nextElement ();
		if (item.length () != 0) sortedItems [index++] = item;
	}
	if (index != sortedItems.length) {
		String [] newItems = new String [index];
		System.arraycopy (sortedItems, 0, newItems, 0, index);
		sortedItems = newItems;
	}
	sort (sortedItems);
	list.setItems (sortedItems);
}

/**
 * Sets the RGB describing the color to be selected by default
 * in the dialog, or null to let the platform choose one.
 *
 * @param rgb the RGB value to use initially, or null to let
 *        the platform select a default when open() is called
 *
 * @see PaletteData#getRGBs
 * 
 * @since 2.1
 */
public void setRGB (RGB rgb) {
	this.rgb = rgb;
}

/**
 * Set the contents of the size list to the keys of 'items'.
 * Keys are sorted in ascending order first and have to be Integers.
 */
void setSizeItemsSorted (Enumeration itemsEnum) {
	Vector items = new Vector ();
	while (itemsEnum.hasMoreElements ()) {
		items.addElement (itemsEnum.nextElement ());
	}
	Integer [] sortedItems = new Integer [items.size ()];
	items.copyInto (sortedItems);
	sort (sortedItems);
	String [] sortedItemStrings = new String [items.size ()];
	for (int i = 0; i < sortedItemStrings.length; i++) {
		sortedItemStrings [i] = String.valueOf (sortedItems [i].intValue ());
	}
	fontSizeList.setItems (sortedItemStrings);
}

/**
 * Sort 'items' in ascending order.
 */
void sort (Integer [] items) {
	/* Shell Sort from K&R, pg 108 */
	int length = items.length;
	for (int gap = length / 2; gap > 0; gap /= 2) {
		for (int i = gap; i < length; i++) {
			for (int j = i - gap; j >= 0; j -= gap) {
		   		if (items [j].intValue () > items [j + gap].intValue ()) {
					Integer swap = items [j];
					items [j] = items [j + gap];
					items [j + gap] = swap;
		   		}
	    	}
	    }
	}
}

/**
 * Sort 'items' in ascending order.
 */
void sort (String items []) {
	/* Shell Sort from K&R, pg 108 */
	int length = items.length;
	for (int gap = length / 2; gap > 0; gap /= 2) {
		for (int i = gap; i < length; i++) {
			for (int j = i - gap; j >= 0; j -= gap) {
		   		if (items [j].compareTo (items [j + gap]) > 0) {
					String swap = items [j];
					items [j] = items [j + gap];
					items [j + gap] = swap;
		   		}
	    	}
	    }
	}
}

void updateButtonEnablements () {
	removeButton.setEnabled (fontSetList.getItemCount () > 1);
	upButton.setEnabled (fontSetList.getSelectionIndex () > 0);
	downButton.setEnabled (fontSetList.getSelectionIndex () < fontSetList.getItemCount () - 1);
}

void updateFontList () {
	int selectionIndex = fontSetList.getSelectionIndex ();
	int topIndex = Math.max (0, fontSetList.getTopIndex ());
	String [] items = new String [fontData.length];
	for (int i = 0; i < fontData.length; i++) {
		StringBuffer buffer = new StringBuffer ();
		buffer.append (i);
		buffer.append (": ");
		buffer.append (getTranslatedCharSet (fontData [i], false));
		buffer.append ("-");
		buffer.append (getTranslatedFaceName (fontData [i]));
		buffer.append ("-");
		if (!fontData [i].addStyle.equals ("")) {
			buffer.append (fontData [i].addStyle);
			buffer.append ("-");
		}
		buffer.append (fontData [i].getHeight ());
		buffer.append ("-");
		buffer.append (fontData [i].weight);
		items [i] = buffer.toString (); 
	}
	fontSetList.setItems (items);
	if (selectionIndex >= items.length) selectionIndex--;
	fontSetList.select (selectionIndex);
	fontSetList.setData (new Integer (selectionIndex));
	fontSetList.setTopIndex (topIndex);
	fontSetList.showSelection ();
}

void updateSampleColor () {
	if (rgb == null) {
		rgb = new RGB (0, 0, 0);
	}
	if (sampleColor != null) {
		if (sampleColor.getRGB ().equals (rgb)) return;
		sampleColor.dispose ();
	}
	sampleColor = new Color (parent.display, rgb);
	sampleLabel.setForeground (sampleColor);
}

/**
 * Set the font of the sample text to the selected font.
 * Display an error in place of the sample text if the selected 
 * font could not be loaded.
 */
void updateSampleFont () {
	FontData selectionFontData = getSelectionFontData ();
	/*
	 * sampleFont may not be the same as the one specified in selectionFontData.
	 * This happens when selectionFontData specifies a font alias.
	 */
	if (sampleFont != null) sampleFont.dispose ();
	int selectionIndex = Math.max (0, fontSetList.getSelectionIndex ());
	fontData [selectionIndex] = selectionFontData;
	sampleFont = new Font (shell.display, selectionFontData);
	sampleLabel.setFont (sampleFont);
}

}
