/*******************************************************************************
 * Copyright (c) 2004, 2006 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.facesconfig.ui.preference;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.ColorFieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.IntegerFieldEditor;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.resource.ColorRegistry;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jst.jsf.facesconfig.ui.EditorPlugin;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.AccessibleAdapter;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;

/**
 * This class represents a preference page that is contributed to the
 * Preferences dialog. By subclassing <samp>FieldEditorPreferencePage </samp>,
 * we can use the field support built into JFace that allows us to create a page
 * that is small and knows how to save, restore and apply itself.
 * <p>
 * This page is used to modify preferences only. They are stored in the
 * preference store that belongs to the main plug-in class. That way,
 * preferences can be accessed directly via the preference store.
 */

public final class GEMPreferences extends FieldEditorPreferencePage implements
		IWorkbenchPreferencePage {
	// appearance
    /**
     * Key for preference for whether or not the intro editor should be shown
     */
    public final static String SHOW_INTRO_EDITOR = "ShowIntroEditor"; //$NON-NLS-1$
    
	/**
	 * use system colors preference
	 */
	public final static String USE_SYSTEM_COLORS = "UseSystemColors"; //$NON-NLS-1$

	/**
	 * canvas color preference
	 */
	public final static String CANVAS_COLOR = "CanvasColor"; //$NON-NLS-1$

	/**
	 * figure label font
	 */
	public final static String FIGURE_LABEL_FONT = "FigureLabelFont"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String FIGURE_LABEL_FONT_COLOR = "FigureLabelFontColor"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String LABEL_PLACEMENT = "LabelPlacement"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String INPUT_PORT_COLOR = "InputPortColor"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String OUTPUT_PORT_COLOR = "OutputPortColor"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String SHOW_LINE_LABELS = "ShowLineLabels"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String LINE_LABEL_FONT = "LineLabelFont"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String LINE_LABEL_FONT_COLOR = "LineLabelFontColor"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String LINE_LABEL_COLOR = "LineLabelColor"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String LINE_WIDTH = "LineWidth"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String LINE_COLOR = "LineColor"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String LINE_ROUTING = "LineRouting"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String SNAP_TO_GRID = "SnapToGrid"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String SNAP_TO_GEOMETRY = "SnapToGeometry"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String GRID_WIDTH = "GridWidth"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String GRID_HEIGHT = "GridHeight"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String GRID_COLOR = "GridColor"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String LABEL_PLACEMENT_TOP = "Top"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String LABEL_PLACEMENT_BOTTOM = "Bottom"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String LABEL_PLACEMENT_LEFT = "Left"; //$NON-NLS-1$

	/**
	 * 
	 */
	public final static String LABEL_PLACEMENT_RIGHT = "Right"; //$NON-NLS-1$

	// 
	/**
	 * "Direct" routing was intended for connections lines without bendpoints;
	 * this has been removed because it is unnecessary.
	 * public final static String LINE_ROUTING_DIRECT = "Direct";
	 * "Manhattan" line routing creates orthogonal lines
	 */
	public final static String LINE_ROUTING_MANHATTAN = "Manhattan"; //$NON-NLS-1$

	/**
	 * "Manual" routing allows user to create bendpoints
	 */
	public final static String LINE_ROUTING_MANUAL = "Manaul"; //$NON-NLS-1$

	private final static String[][] m_lineRoutingLabels = {
			// display, key
			// { GEMPlugin.getResourceString("CanvasPreferences.LABEL.Direct"),
			// LINE_ROUTING_DIRECT }, //$NON-NLS-1$ //$NON-NLS-2$
			{
				PreferenceMessages.CanvasPreferences_LABEL_Manual, LINE_ROUTING_MANUAL },
			{
					PreferenceMessages.CanvasPreferences_LABEL_Manhattan, LINE_ROUTING_MANHATTAN }
	};

	private final static String[][] m_labelPlacementLabels = {
			{
				PreferenceMessages.CanvasPreferences_LABEL_Top, LABEL_PLACEMENT_TOP },
			{
					PreferenceMessages.CanvasPreferences_LABEL_Bottom, LABEL_PLACEMENT_BOTTOM },
			{
						PreferenceMessages.CanvasPreferences_LABEL_Left, LABEL_PLACEMENT_LEFT },
			{
							PreferenceMessages.CanvasPreferences_LABEL_Right, LABEL_PLACEMENT_RIGHT }
	};

	private Group canvasGroup;

	private Group iconGroup;

	private Group lineGroup;

	private BooleanField useSystemColors;

	private ColorFieldEditor canvasColor;

	private BooleanField snapToGrid;

	private IntegerFieldEditor gridWidth;

	private IntegerFieldEditor gridHeight;

	private ColorFieldEditor gridColor;

	private BooleanField showLineLabels;

	private ColorFieldEditor lineLabelColor;

	private ColorFieldEditor lineColor;

	private ColorFontFieldEditor iconFont;

	private ColorFontFieldEditor lineFont;

	// private ColorFieldEditor inputPortColor;
	//
	// private ColorFieldEditor outputPortColor;

	// CR392586: resource leaks
	// at least keep leaks bounded...
//	private static Hashtable resourceRegistry = new Hashtable();

	private class BooleanField extends BooleanFieldEditor {
		private Composite parent;

		/**
		 * @param name
		 * @param label
		 * @param parent
		 */
		public BooleanField(String name, String label, Composite parent) {
			super(name, label, parent);
			this.parent = parent;
		}

		/**
		 * @return the change control button
		 */
		public Button getButton() {
			return getChangeControl(parent);
		}
	}

	/**
	 * Constructor
	 */
	public GEMPreferences() {
		super(GRID);
		// FIXME: we should be encapsulating what pref store is used for all callers of this class
		setPreferenceStore(EditorPlugin.getDefault().getPreferenceStore());
		setDescription(PreferenceMessages.GEMPreferences_description);
	}

	/**
	 * Sets the default values of the preferences.
	 */
	public static void initializeDefaults() {
		IPreferenceStore store = EditorPlugin.getDefault().getPreferenceStore();
		Font f = JFaceResources.getFontRegistry().get(
				JFaceResources.DEFAULT_FONT);

		store.setDefault(SHOW_INTRO_EDITOR, true);
		store.setDefault(USE_SYSTEM_COLORS, true);
		PreferenceConverter.setDefault(store, CANVAS_COLOR, new RGB(255, 255,
				255));
		PreferenceConverter.setDefault(store, FIGURE_LABEL_FONT, f
				.getFontData());
		store.setDefault(LINE_WIDTH, 1);
		store.setDefault(LINE_ROUTING, getLineRoutingLabels()[0][1]);
		store.setDefault(SHOW_LINE_LABELS, true);
		PreferenceConverter.setDefault(store, LINE_COLOR, new RGB(0, 0, 0));
		PreferenceConverter.setDefault(store, LINE_LABEL_COLOR, new RGB(255,
				255, 255));
		PreferenceConverter.setDefault(store, LINE_LABEL_FONT, f.getFontData());
		store.setDefault(SNAP_TO_GEOMETRY, true);
		store.setDefault(SNAP_TO_GRID, true);
		store.setDefault(GRID_WIDTH, 12);
		store.setDefault(GRID_HEIGHT, 12);
		PreferenceConverter.setDefault(store, GRID_COLOR,
				new RGB(230, 230, 230));
		store.setDefault(LABEL_PLACEMENT, LABEL_PLACEMENT_BOTTOM);
	}

	/**
	 * Creates the field editors. Field editors are abstractions of the common
	 * GUI blocks needed to manipulate various types of preferences. Each field
	 * editor knows how to save and restore itself.
	 */

	public void createFieldEditors() {
	    
	    // note, we aren't saving the reference.  It's assumed that parent
	    // worries about destruction, persistence etc.
	    addBooleanField(
	            SHOW_INTRO_EDITOR,
	            PreferenceMessages.EditorPreferences_LABEL_ShowIntroEditor,
	            getFieldEditorParent());
	            
		useSystemColors = addBooleanField(
				USE_SYSTEM_COLORS,
				PreferenceMessages.CanvasPreferenceTab_LABEL_UseSystemColors,
				getFieldEditorParent());

		canvasGroup = new Group(getFieldEditorParent(), SWT.NULL);
		lineGroup = new Group(getFieldEditorParent(), SWT.NULL);
		iconGroup = new Group(getFieldEditorParent(), SWT.NULL);

		canvasGroup.setText(PreferenceMessages.CanvasPreferenceTab_LABEL_Canvas);
		canvasColor = addColorField(
				CANVAS_COLOR,
				PreferenceMessages.CanvasPreferenceTab_LABEL_BackgroundColor, canvasGroup);
        // Fix for Bug 268443: [hotbug] FacesConfig Editor preferences page needs more info for screen readers
        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=268443
        canvasColor.getColorSelector().getButton().getAccessible().addAccessibleListener(
                new AccessibleAdapter () {         
                    public void getName (final AccessibleEvent e) {
                        e.result = PreferenceMessages.CanvasPreferenceTab_LABEL_BackgroundColor;
                    }
                });

		addBooleanField(
				SNAP_TO_GEOMETRY,
				PreferenceMessages.CanvasPreferenceTab_LABEL_SnapToGeometry, canvasGroup);
		snapToGrid = addBooleanField(
				SNAP_TO_GRID,
				PreferenceMessages.CanvasPreferenceTab_LABEL_SnapToGrid, canvasGroup);
		gridColor = addColorField(
				GRID_COLOR,
				PreferenceMessages.CanvasPreferenceTab_LABEL_GridLineColor, canvasGroup);
        gridColor.getColorSelector().getButton().getAccessible().addAccessibleListener(
                new AccessibleAdapter () {         
                    public void getName (final AccessibleEvent e) {
                        e.result = PreferenceMessages.CanvasPreferenceTab_LABEL_GridLineColor;
                    }
                });
        gridWidth = addIntegerField(
				GRID_WIDTH,
				PreferenceMessages.CanvasPreferenceTab_LABEL_GridWidth, canvasGroup);
		gridHeight = addIntegerField(
				GRID_HEIGHT,
				PreferenceMessages.CanvasPreferenceTab_LABEL_GridHeight, canvasGroup);

		iconGroup.setText(PreferenceMessages.CanvasPreferenceTab_LABEL_IconGroup);
		iconFont = addFontField(
				FIGURE_LABEL_FONT,
				PreferenceMessages.CanvasPreferenceTab_LABEL_IconLabelFont, iconGroup);
        iconFont.getChangeControl(iconGroup).getAccessible().addAccessibleListener(
                new AccessibleAdapter () {         
                    public void getName (final AccessibleEvent e) {
                        e.result = PreferenceMessages.CanvasPreferenceTab_LABEL_IconLabelFont;
                    }
                });
		addComboField(LABEL_PLACEMENT, PreferenceMessages.CanvasPreferenceTab_LABEL_LabelPlacement,
				getLabelPlacementLabels(), iconGroup);
		// inputPortColor = addColorField(
		// INPUT_PORT_COLOR,
		// EditorPlugin
		// .getResourceString("CanvasPreferenceTab.LABEL.InputPortColor"),
		// iconGroup); //$NON-NLS-1$
		// outputPortColor = addColorField(
		// OUTPUT_PORT_COLOR,
		// EditorPlugin
		// .getResourceString("CanvasPreferenceTab.LABEL.OutputPortColor"),
		// iconGroup); //$NON-NLS-1$

		lineGroup.setText(PreferenceMessages.CanvasPreferenceTab_LABEL_LineGroup);
		showLineLabels = addBooleanField(SHOW_LINE_LABELS, PreferenceMessages.CanvasPreferenceTab_LABEL_ShowLineLabels,
				lineGroup);
		lineFont = addFontField(
				LINE_LABEL_FONT,
				 PreferenceMessages.CanvasPreferenceTab_LABEL_LineLabelFont, lineGroup);
        lineFont.getChangeControl(lineGroup).getAccessible().addAccessibleListener(
                new AccessibleAdapter () {         
                    public void getName (final AccessibleEvent e) {
                        e.result = PreferenceMessages.CanvasPreferenceTab_LABEL_LineLabelFont;
                    }
                });
		lineLabelColor = addColorField(
				LINE_LABEL_COLOR,
				 PreferenceMessages.CanvasPreferenceTab_LABEL_LineLabelColor, lineGroup);
        lineLabelColor.getColorSelector().getButton().getAccessible().addAccessibleListener(
                new AccessibleAdapter () {         
                    public void getName (final AccessibleEvent e) {
                        e.result = PreferenceMessages.CanvasPreferenceTab_LABEL_LineLabelColor;
                    }
                });
		
		lineColor = addColorField(
				LINE_COLOR,
				 PreferenceMessages.CanvasPreferenceTab_LABEL_LineColor, lineGroup);
        lineColor.getColorSelector().getButton().getAccessible().addAccessibleListener(
                new AccessibleAdapter () {         
                    public void getName (final AccessibleEvent e) {
                        e.result = PreferenceMessages.CanvasPreferenceTab_LABEL_LineColor;
                    }
                });
		addIntegerField(
				LINE_WIDTH,
				 PreferenceMessages.CanvasPreferenceTab_LABEL_LineWidth, lineGroup);
		addComboField(LINE_ROUTING,  PreferenceMessages.CanvasPreferenceTab_LABEL_LineRouting,
				getLineRoutingLabels(), lineGroup);
	}

	protected void initialize() {
		// Color use: Default canvas colors should pick up system defaults
		// enable or disable all of the color and font selection controls in the
		// preference dialog
		// depending on whether the "Use System Colors" checkbox is selected.
		super.initialize();

		((GridLayout) getFieldEditorParent().getLayout()).numColumns = 2;

		canvasGroup.setLayout(new GridLayout(3, false));
		canvasGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL
				| GridData.VERTICAL_ALIGN_BEGINNING));
		canvasColor.fillIntoGrid(canvasGroup, 3);
		gridColor.fillIntoGrid(canvasGroup, 3);

		iconGroup.setLayout(new GridLayout(3, false));
		iconGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL
				| GridData.VERTICAL_ALIGN_BEGINNING));
		iconFont.fillIntoGrid(iconGroup, 3);

		lineGroup.setLayout(new GridLayout(3, false));
		lineGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL
				| GridData.VERTICAL_ALIGN_BEGINNING));
		lineColor.fillIntoGrid(lineGroup, 3);
		lineLabelColor.fillIntoGrid(lineGroup, 3);
		lineFont.fillIntoGrid(lineGroup, 3);

		boolean userColorsValue = !useSystemColors.getBooleanValue();
		boolean showLineLabelsValue = showLineLabels.getBooleanValue();
		boolean snapToGridValue = snapToGrid.getBooleanValue();
		canvasColor.setEnabled(userColorsValue, canvasGroup);
		gridColor.setEnabled(snapToGridValue && userColorsValue, canvasGroup);
		iconFont.setEnabled(userColorsValue, iconGroup);
		// inputPortColor.setEnabled(userColorsValue, iconGroup);
		// outputPortColor.setEnabled(userColorsValue, iconGroup);
		lineColor.setEnabled(userColorsValue, lineGroup);
		lineLabelColor.setEnabled(showLineLabelsValue && userColorsValue,
				lineGroup);
		lineFont.setEnabled(showLineLabelsValue && userColorsValue, lineGroup);
		gridWidth.setEnabled(snapToGridValue, canvasGroup);
		gridHeight.setEnabled(snapToGridValue, canvasGroup);

		useSystemColors.getButton().addSelectionListener(
				new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						boolean userColorsValue_ = !useSystemColors
								.getBooleanValue();
						boolean showLineLabelsValue_ = showLineLabels
								.getBooleanValue();
						boolean snapToGridValue_ = snapToGrid.getBooleanValue();

						canvasColor.setEnabled(userColorsValue_, canvasGroup);
						gridColor
								.setEnabled(snapToGridValue_ && userColorsValue_,
										canvasGroup);
						iconFont.setEnabled(userColorsValue_, iconGroup);
						// inputPortColor.setEnabled(userColorsValue,
						// iconGroup);
						// outputPortColor.setEnabled(userColorsValue,
						// iconGroup);
						lineColor.setEnabled(userColorsValue_, lineGroup);
						lineLabelColor.setEnabled(showLineLabelsValue_
								&& userColorsValue_, lineGroup);
						lineFont.setEnabled(showLineLabelsValue_
								&& userColorsValue_, lineGroup);
					}
				});

		showLineLabels.getButton().addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				boolean userColorsValue_ = !useSystemColors.getBooleanValue();
				boolean showLineLabelsValue_ = showLineLabels.getBooleanValue();
				lineLabelColor.setEnabled(showLineLabelsValue_
						&& userColorsValue_, lineGroup);
				lineFont.setEnabled(showLineLabelsValue_ && userColorsValue_,
						lineGroup);
			}
		});

		snapToGrid.getButton().addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				boolean userColorsValue_ = !useSystemColors.getBooleanValue();
				boolean snapToGridValue_ = snapToGrid.getBooleanValue();

				gridColor.setEnabled(snapToGridValue_ && userColorsValue_,
						canvasGroup);
				gridWidth.setEnabled(snapToGridValue_, canvasGroup);
				gridHeight.setEnabled(snapToGridValue_, canvasGroup);
			}
		});

	}

	public void init(IWorkbench workbench) {
        // no initialization
	}

	private ColorFieldEditor addColorField(String name, String labelText,
			Composite parent) {
		ColorFieldEditor f = new ColorFieldEditor(name, labelText, parent);
		addField(f);
		return f;
	}

	private ComboFieldEditor addComboField(String name, String labelText,
			String[][] entryNamesAndValues, Composite parent) {
		ComboFieldEditor f = new ComboFieldEditor(name, labelText,
				entryNamesAndValues, parent);
		addField(f);
		return f;
	}

	private IntegerFieldEditor addIntegerField(String name, String labelText,
			Composite parent) {
		IntegerFieldEditor f = new IntegerFieldEditor(name, labelText, parent);
		addField(f);
		return f;
	}

	private BooleanField addBooleanField(String name, String labelText,
			Composite parent) {
		BooleanField f = new BooleanField(name, labelText, parent);
		addField(f);
		return f;
	}

//	private StringFieldEditor addStringField(String name, String labelText,
//			Composite parent) {
//		StringFieldEditor f = new StringFieldEditor(name, labelText, parent);
//		addField(f);
//		return f;
//	}

	// protected NumberField addNumberField(String name, String labelText,
	// Composite parent)
	// {
	// NumberField f = new NumberField(name,labelText,parent);
	// addField(f);
	// return f;
	// }

	private ColorFontFieldEditor addFontField(String name, String labelText,
			Composite parent) {
		ColorFontFieldEditor f = new ColorFontFieldEditor(name, labelText,
				parent);
		addField(f);
		return f;
	}

	private static String[][] getLineRoutingLabels() {
		return m_lineRoutingLabels;
	}

	private static String[][] getLabelPlacementLabels() {
		return m_labelPlacementLabels;
	}

//	private static void propagateProperty(String property, EditPart part) {
//		Iterator iter = part.getChildren().iterator();
//		while (iter.hasNext()) {
//			EditPart child = (EditPart) iter.next();
//			Figure fig = (Figure) ((GraphicalEditPart) child).getFigure();
//			GEMPreferences.propagateProperty(property, fig);
//			propagateProperty(property, child);
//		}
//	}

	/**
	 * @return true if the preference is set to show the introduction
	 * editor.  false otherwise.
	 */
	public static boolean getShowIntroEditor()
	{
	    IPreferenceStore store = EditorPlugin.getDefault().getPreferenceStore();
	    return store.getBoolean(SHOW_INTRO_EDITOR);
	}
	
	/**
	 * @param store
	 * @param property
	 * @return the color property for the key 'property'
	 */
	public static Color getColor(IPreferenceStore store, String property) {
		boolean useSystemColors = store.getBoolean(USE_SYSTEM_COLORS);

		Color c = ColorConstants.black;
		if (useSystemColors) {
			if (GRID_COLOR.equals(property))
				// c = ColorConstants.buttonDarkest;
				c = ColorConstants.button;
			if (LINE_COLOR.equals(property))
				c = ColorConstants.listForeground;
			if (LINE_LABEL_FONT_COLOR.equals(property))
				c = ColorConstants.listForeground;
			if (LINE_LABEL_COLOR.equals(property))
				c = ColorConstants.listBackground;
			if (CANVAS_COLOR.equals(property))
				c = ColorConstants.listBackground;
			if (INPUT_PORT_COLOR.equals(property))
				c = ColorConstants.listForeground;
			if (OUTPUT_PORT_COLOR.equals(property))
				c = ColorConstants.listForeground;
			if (FIGURE_LABEL_FONT_COLOR.equals(property))
				c = ColorConstants.listForeground;
		} else {
			// CR392586: resource leaks
			RGB rgb = PreferenceConverter.getColor(store, property);
			ColorRegistry registry = JFaceResources.getColorRegistry();
			if (registry.get(rgb.toString()) != null)
				return registry.get(rgb.toString());
			registry.put(rgb.toString(), rgb);
			c = registry.get(rgb.toString());
		}
		return c;
	}

//	// CR392586: resource leaks
//	private static Font getFont(IPreferenceStore store, String property) {
//		FontData fd = PreferenceConverter.getFontData(store, property);
//		FontRegistry registry = JFaceResources.getFontRegistry();
//		if (!registry.get(fd.toString()).equals(registry.defaultFont()))
//			return registry.get(fd.toString());
//
//		registry.put(fd.toString(), new FontData[] {fd});
//		return registry.get(fd.toString());
//	}

//	private static void propagateProperty(String property, Figure fig) {
//		IPreferenceStore store = EditorPlugin.getDefault().getPreferenceStore();
//		WindowFigure window = null;
//		IconFigure icon = null;
//		LinkFigure link = null;
//		if (fig instanceof CompoundNodeFigure) {
//			window = ((CompoundNodeFigure) fig).getWindowFigure();
//			icon = ((CompoundNodeFigure) fig).getIconFigure();
//		} else if (fig instanceof WindowFigure)
//			window = (WindowFigure) fig;
//		else if (fig instanceof LinkFigure)
//			link = (LinkFigure) fig;
//
//		if (property != null && property.equals(USE_SYSTEM_COLORS))
//			// reload all properties - it's easiest
//			property = null;
//
//		if (property == null || SNAP_TO_GRID.equals(property)) {
//			boolean b = store.getBoolean(SNAP_TO_GRID);
//			WindowFigure.defaultGridEnabled = b;
//
//			if (window != null)
//				window.getGridLayer().setVisible(b);
//		}
//
//		if (property == null || GRID_WIDTH.equals(property)
//				|| GRID_HEIGHT.equals(property)) {
//			Dimension d = new Dimension(store.getInt(GRID_WIDTH), store
//					.getInt(GRID_HEIGHT));
//			WindowFigure.defaultGridSpacing = d;
//
//			if (window != null)
//				window.getGridLayer().setSpacing(d);
//		}
//
//		if (property == null || GRID_COLOR.equals(property)) {
//			Color c = getColor(store, GRID_COLOR);
//			WindowFigure.defaultGridColor = c;
//
//			if (window != null)
//				window.getGridLayer().setForegroundColor(c);
//		}
//
//		// TODO: since the line router is managed by the EditPart for the
//		// container figure, setting the line routing style in the WindowFigure
//		// does not change the line routing immediately. The editor must be
//		// restarted for line routing to take effect.
//		if (property == null || LINE_ROUTING.equals(property)) {
//			String s = store.getString(LINE_ROUTING);
//			int style;
//			if (LINE_ROUTING_MANHATTAN.equals(s))
//				style = WindowFigure.LINE_ROUTING_MANHATTAN;
//			else
//				style = WindowFigure.LINE_ROUTING_MANUAL;
//
//			WindowFigure.defaultLineRoutingStyle = style;
//			if (window != null)
//				window.setLineRoutingStyle(style);
//		}
//
//		if (property == null || LINE_WIDTH.equals(property)) {
//			int w = store.getInt(LINE_WIDTH);
//			LinkFigure.defaultLineWidth = w;
//
//			if (link != null)
//				link.setLineWidth(w);
//		}
//
//		if (property == null || LINE_COLOR.equals(property)) {
//			Color c = getColor(store, LINE_COLOR);
//			LinkFigure.defaultLineColor = c;
//
//			if (link != null)
//				link.setForegroundColor(c);
//		}
//
//		if (property == null || SHOW_LINE_LABELS.equals(property)) {
//			boolean b = store.getBoolean(SHOW_LINE_LABELS);
//			LinkFigure.defaultLabelVisible = b;
//
//			if (link != null)
//				link.setLabelVisible(b);
//		}
//
//		if (property == null || LINE_LABEL_FONT.equals(property)
//				|| LINE_LABEL_FONT_COLOR.equals(property)) {
//			// CR392586: resource leaks
//			Font f = getFont(store, LINE_LABEL_FONT);
//			Color c = getColor(store, LINE_LABEL_FONT_COLOR);
//			LinkFigure.defaultFont = f;
//			LinkFigure.defaultLabelForeground = c;
//
//			if (link != null) {
//				link.setFont(f);
//				link.setLabelForeground(c);
//			}
//		}
//
//		if (property == null || LINE_LABEL_COLOR.equals(property)) {
//			Color c = getColor(store, LINE_LABEL_COLOR);
//			LinkFigure.defaultLabelBackground = c;
//
//			if (link != null)
//				link.setLabelBackground(c);
//		}
//
//		if (property == null || CANVAS_COLOR.equals(property)) {
//			Color c = getColor(store, CANVAS_COLOR);
//			WindowFigure.defaultBackgroundColor = c;
//
//			if (window != null)
//				window.setBackgroundColor(c);
//			if (icon != null)
//				icon.setBackgroundColor(c);
//		}
//
//		if (property == null || INPUT_PORT_COLOR.equals(property)) {
//			Color c = getColor(store, INPUT_PORT_COLOR);
//			InputPortFigure.defaultForegroundColor = c;
//
//			if (fig instanceof InputPortFigure)
//				fig.setForegroundColor(c);
//		}
//
//		if (property == null || OUTPUT_PORT_COLOR.equals(property)) {
//			Color c = getColor(store, OUTPUT_PORT_COLOR);
//			OutputPortFigure.defaultForegroundColor = c;
//
//			if (fig instanceof OutputPortFigure)
//				fig.setForegroundColor(c);
//		}
//
//		if (property == null || FIGURE_LABEL_FONT.equals(property)
//				|| FIGURE_LABEL_FONT_COLOR.equals(property)) {
//			// CR392586: resource leaks
//			Font f = getFont(store, FIGURE_LABEL_FONT);
//			Color c = getColor(store, FIGURE_LABEL_FONT_COLOR);
//			IconFigure.defaultFont = f;
//			IconFigure.defaultForegroundColor = c;
//			WindowFigure.defaultFont = f;
//			WindowFigure.defaultForegroundColor = c;
//
//			if (window != null) {
//				window.setFont(f);
//				window.setForegroundColor(c);
//			}
//			if (icon != null) {
//				icon.setFont(f);
//				icon.setForegroundColor(c);
//			}
//			if (fig instanceof IconFigure) {
//				fig.setFont(f);
//				fig.setForegroundColor(c);
//			}
//		}
//
//		if (property == null || LABEL_PLACEMENT.equals(property)) {
//			int placement = PositionConstants.SOUTH;
//			String s = store.getString(LABEL_PLACEMENT);
//			if (LABEL_PLACEMENT_TOP.equals(s))
//				placement = PositionConstants.NORTH;
//			if (LABEL_PLACEMENT_BOTTOM.equals(s))
//				placement = PositionConstants.SOUTH;
//			if (LABEL_PLACEMENT_LEFT.equals(s))
//				placement = PositionConstants.WEST;
//			if (LABEL_PLACEMENT_RIGHT.equals(s))
//				placement = PositionConstants.EAST;
//			IconFigure.defaultTextPlacement = placement;
//
//			if (icon != null)
//				icon.setTextPlacement(placement);
//			if (fig instanceof IconFigure)
//				((IconFigure) fig).setTextPlacement(placement);
//		}
//
//		Iterator iter = fig.getChildren().iterator();
//		while (iter.hasNext()) {
//			Figure child = (Figure) iter.next();
//			propagateProperty(property, child);
//		}
//	}
}