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

import java.util.Arrays;
import java.util.StringTokenizer;

import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.StringConverter;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Shell;

/**
 * A utility class for dealing with preferences whose values are
 * common SWT objects (color, points, rectangles, and font data).
 * The static methods on this class handle the conversion between
 * the SWT objects and their string representations.
 * <p>
 * Usage:
 * <pre>
 * IPreferenceStore store = ...;
 * PreferenceConverter.setValue(store, "bg", new RGB(127,127,127));
 * ...
 * RBG bgColor = PreferenceConverter.getValue(store, "bg");
 * </pre>
 * </p>
 * <p>
 * This class contains static methods and fields only and cannot 
 * be instantiated.
 * </p>
 * @issue touching this class has the side effect of creating a display (static initializer).
 */
public class PreferenceConverter {

	/**
	 * The default-default value for point preferences
	 * (the origin, <code>(0,0)</code>).
	 */
	public static final Point POINT_DEFAULT_DEFAULT = new Point(0, 0);
	/**
	 * The default-default value for rectangle preferences
	 * (the empty rectangle <code>(0,0,0,0)</code>).
	 */
	public static final Rectangle RECTANGLE_DEFAULT_DEFAULT =
		new Rectangle(0, 0, 0, 0);
	/**
	 * The default-default value for color preferences 
	 * (black, <code>RGB(0,0,0)</code>).
	 */
	public static final RGB COLOR_DEFAULT_DEFAULT = new RGB(0, 0, 0);

	private static final String ENTRY_SEPARATOR = ";"; //$NON-NLS-1$

	/**
	 * The default-default value for <code>FontData[]</code> preferences.
	 */
	public static final FontData[] FONTDATA_ARRAY_DEFAULT_DEFAULT;
	
	/**
	 * The default-default value for <code>FontData</code> preferences.
	 */
	public static final FontData FONTDATA_DEFAULT_DEFAULT;
	static {
		Shell shell = new Shell();
		FONTDATA_ARRAY_DEFAULT_DEFAULT = shell.getFont().getFontData();
		shell.dispose();
		/**
		 * The default-default value for <code>FontData</code> preferences.
		 * This is left in for compatibility purposes. It is recommended that
		 * FONTDATA_ARRAY_DEFAULT_DEFAULT is actually used.
		 */

		FONTDATA_DEFAULT_DEFAULT = FONTDATA_ARRAY_DEFAULT_DEFAULT[0];
	}

	/* (non-Javadoc)
	 * private constructor to prevent instantiation.
	 */
	private PreferenceConverter() {
	    //no-op
	}
	/**
	 * Helper method to construct a color from the given string.
	 * @param value the indentifier for the color
	 * @return RGB
	 */
	private static RGB basicGetColor(String value) {

		if (IPreferenceStore.STRING_DEFAULT_DEFAULT.equals(value))
			return COLOR_DEFAULT_DEFAULT;

		RGB color = StringConverter.asRGB(value, null);
		if (color == null)
			return COLOR_DEFAULT_DEFAULT;
		return color;
	}
	/**
	 * Helper method to construct a <code>FontData</code> from the given string.
	 * String is in the form FontData;FontData; in order that
	 * multiple FontDatas can be defined.
	 * @param value the identifier for the font
	 * @return FontData[]
	 * 
	 * @since 3.0
	 */
	public static FontData[] basicGetFontData(String value) {
		if (IPreferenceStore.STRING_DEFAULT_DEFAULT.equals(value))
			return FONTDATA_ARRAY_DEFAULT_DEFAULT;

		//Read in all of them to get the value
		StringTokenizer tokenizer = new StringTokenizer(value, ENTRY_SEPARATOR);
		int numTokens = tokenizer.countTokens();
		FontData[] fontData = new FontData[numTokens];

		for (int i = 0; i < numTokens; i++) {
			try {
				fontData[i] = new FontData(tokenizer.nextToken());
			} catch (SWTException error) {
				return FONTDATA_ARRAY_DEFAULT_DEFAULT;
			} catch (IllegalArgumentException error) {
				return FONTDATA_ARRAY_DEFAULT_DEFAULT;
			}
		}
		return fontData;
	}

	/**
	 * Reads the supplied string and returns its corresponding
	 * FontData. If it cannot be read then the default FontData
	 * will be returned.
	 * 
	 * @param fontDataValue the string value for the font data  
	 * @return the font data
	 */
	public static FontData[] readFontData(String fontDataValue) {
		return basicGetFontData(fontDataValue);
	}
	/**
	 * Helper method to construct a point from the given string.
	 * @param value
	 * @return Point
	 */
	private static Point basicGetPoint(String value) {
		Point dp = new Point(POINT_DEFAULT_DEFAULT.x, POINT_DEFAULT_DEFAULT.y);
		if (IPreferenceStore.STRING_DEFAULT_DEFAULT.equals(value))
			return dp;
		return StringConverter.asPoint(value, dp);
	}
	/**
	 *  Helper method to construct a rectangle from the given string.
	 * @param value
	 * @return Rectangle
	 */
	private static Rectangle basicGetRectangle(String value) {
		// We can't just return RECTANGLE_DEFAULT_DEFAULT because
		// a rectangle object doesn't have value semantik.
		Rectangle dr =
			new Rectangle(
				RECTANGLE_DEFAULT_DEFAULT.x,
				RECTANGLE_DEFAULT_DEFAULT.y,
				RECTANGLE_DEFAULT_DEFAULT.width,
				RECTANGLE_DEFAULT_DEFAULT.height);

		if (IPreferenceStore.STRING_DEFAULT_DEFAULT.equals(value))
			return dr;
		return StringConverter.asRectangle(value, dr);
	}
	/**
	 * Returns the current value of the color-valued preference with the
	 * given name in the given preference store.
	 * Returns the default-default value (<code>COLOR_DEFAULT_DEFAULT</code>) 
	 * if there is no preference with the given name, or if the current value 
	 * cannot be treated as a color.
	 *
	 * @param store the preference store
	 * @param name the name of the preference
	 * @return the color-valued preference
	 */
	public static RGB getColor(IPreferenceStore store, String name) {
		return basicGetColor(store.getString(name));
	}
    /**
	 * Returns the default value for the color-valued preference
	 * with the given name in the given preference store.
	 * Returns the default-default value (<code>COLOR_DEFAULT_DEFAULT</code>) 
	 * is no default preference with the given name, or if the default 
	 * value cannot be treated as a color.
	 *
	 * @param store the preference store
	 * @param name the name of the preference
	 * @return the default value of the preference
	 */
	public static RGB getDefaultColor(IPreferenceStore store, String name) {
		return basicGetColor(store.getDefaultString(name));
	}
	/**
	 * Returns the default value array for the font-valued preference
	 * with the given name in the given preference store.
	 * Returns the default-default value (<code>FONTDATA_ARRAY_DEFAULT_DEFAULT</code>) 
	 * is no default preference with the given name, or if the default 
	 * value cannot be treated as font data.
	 *
	 * @param store the preference store
	 * @param name the name of the preference
	 * @return the default value of the preference
	 */
	public static FontData[] getDefaultFontDataArray(
		IPreferenceStore store,
		String name) {
		return basicGetFontData(store.getDefaultString(name));
	}

	/**
	 * Returns a single default value for the font-valued preference
	 * with the given name in the given preference store.
	 * Returns the default-default value (<code>FONTDATA_DEFAULT_DEFAULT</code>) 
	 * is no default preference with the given name, or if the default 
	 * value cannot be treated as font data.
	 * This method is provided for backwards compatibility. It is
	 * recommended that <code>getDefaultFontDataArray</code> is
	 * used instead.
	 *
	 * @param store the preference store
	 * @param name the name of the preference
	 * @return the default value of the preference
	 */
	public static FontData getDefaultFontData(
		IPreferenceStore store,
		String name) {
		return getDefaultFontDataArray(store, name)[0];
	}
	/**
	 * Returns the default value for the point-valued preference
	 * with the given name in the given preference store.
	 * Returns the default-default value (<code>POINT_DEFAULT_DEFAULT</code>) 
	 * is no default preference with the given name, or if the default 
	 * value cannot be treated as a point.
	 *
	 * @param store the preference store
	 * @param name the name of the preference
	 * @return the default value of the preference
	 */
	public static Point getDefaultPoint(IPreferenceStore store, String name) {
		return basicGetPoint(store.getDefaultString(name));
	}
	/**
	 * Returns the default value for the rectangle-valued preference
	 * with the given name in the given preference store.
	 * Returns the default-default value (<code>RECTANGLE_DEFAULT_DEFAULT</code>) 
	 * is no default preference with the given name, or if the default 
	 * value cannot be treated as a rectangle.
	 *
	 * @param store the preference store
	 * @param name the name of the preference
	 * @return the default value of the preference
	 */
	public static Rectangle getDefaultRectangle(
		IPreferenceStore store,
		String name) {
		return basicGetRectangle(store.getDefaultString(name));
	}
	/**
	 * Returns the current value of the font-valued preference with the
	 * given name in the given preference store.
	 * Returns the default-default value (<code>FONTDATA_ARRAY_DEFAULT_DEFAULT</code>) 
	 * if there is no preference with the given name, or if the current value 
	 * cannot be treated as font data.
	 *
	 * @param store the preference store
	 * @param name the name of the preference
	 * @return the font-valued preference
	 */
	public static FontData[] getFontDataArray(
		IPreferenceStore store,
		String name) {
		return basicGetFontData(store.getString(name));
	}

	/**
	 * Returns the current value of the first entry of the
	 * font-valued preference with the
	 * given name in the given preference store.
	 * Returns the default-default value (<code>FONTDATA_ARRAY_DEFAULT_DEFAULT</code>) 
	 * if there is no preference with the given name, or if the current value 
	 * cannot be treated as font data.
	 * This API is provided for backwards compatibility. It is
	 * recommended that <code>getFontDataArray</code> is used instead.
	 *
	 * @param store the preference store
	 * @param name the name of the preference
	 * @return the font-valued preference
	 */
	public static FontData getFontData(IPreferenceStore store, String name) {
		return getFontDataArray(store, name)[0];
	}

	/**
	 * Returns the current value of the point-valued preference with the
	 * given name in the given preference store.
	 * Returns the default-default value (<code>POINT_DEFAULT_DEFAULT</code>) 
	 * if there is no preference with the given name, or if the current value 
	 * cannot be treated as a point.
	 *
	 * @param store the preference store
	 * @param name the name of the preference
	 * @return the point-valued preference
	 */
	public static Point getPoint(IPreferenceStore store, String name) {
		return basicGetPoint(store.getString(name));
	}
	/**
	 * Returns the current value of the rectangle-valued preference with the
	 * given name in the given preference store.
	 * Returns the default-default value (<code>RECTANGLE_DEFAULT_DEFAULT</code>) 
	 * if there is no preference with the given name, or if the current value 
	 * cannot be treated as a rectangle.
	 *
	 * @param store the preference store
	 * @param name the name of the preference
	 * @return the rectangle-valued preference
	 */
	public static Rectangle getRectangle(IPreferenceStore store, String name) {
		return basicGetRectangle(store.getString(name));
	}
	/**
	 * Sets the default value of the preference with the given name
	 * in the given preference store. As FontDatas are stored as 
	 * arrays this method is only provided for backwards compatibility.
	 * Use <code>setDefault(IPreferenceStore, String, FontData[])</code>
	 * instead.
	 *
	 * @param store the preference store
	 * @param name the name of the preference
	 * @param value the new default value of the preference
	 */
	public static void setDefault(
		IPreferenceStore store,
		String name,
		FontData value) {
		FontData[] fontDatas = new FontData[1];
		fontDatas[0] = value;
		setDefault(store, name, fontDatas);
	}

	/**
	 * Sets the default value of the preference with the given name
	 * in the given preference store.
	 *
	 * @param store the preference store
	 * @param name the name of the preference
	 * @param value the new default value of the preference
	 */
	public static void setDefault(
		IPreferenceStore store,
		String name,
		FontData[] value) {
		store.setDefault(name, getStoredRepresentation(value));
	}

	/**
	 * Sets the default value of the preference with the given name
	 * in the given preference store.
	 *
	 * @param store the preference store
	 * @param name the name of the preference
	 * @param value the new default value of the preference
	 */
	public static void setDefault(
		IPreferenceStore store,
		String name,
		Point value) {
		store.setDefault(name, StringConverter.asString(value));
	}
	/**
	 * Sets the default value of the preference with the given name
	 * in the given preference store.
	 *
	 * @param store the preference store
	 * @param name the name of the preference
	 * @param value the new default value of the preference
	 */
	public static void setDefault(
		IPreferenceStore store,
		String name,
		Rectangle value) {
		store.setDefault(name, StringConverter.asString(value));
	}
	/**
	 * Sets the default value of the preference with the given name
	 * in the given preference store.
	 *
	 * @param store the preference store
	 * @param name the name of the preference
	 * @param value the new default value of the preference
	 */
	public static void setDefault(
		IPreferenceStore store,
		String name,
		RGB value) {
		store.setDefault(name, StringConverter.asString(value));
	}
	
	/**
	 * Sets the current value of the preference with the given name
	 * in the given preference store. 
	 * <p>
	 * Included for backwards compatibility.  This method is equivalent to
	 * </code>setValue(store, name, new FontData[]{value})</code>.
	 * </p>
	 * 
	 * @param store the preference store
	 * @param name the name of the preference
	 * @param value the new current value of the preference
	 */
	public static void setValue(
		IPreferenceStore store,
		String name,
		FontData value) {
		setValue(store, name, new FontData[]{value});
	}

	/**
	 * Sets the current value of the preference with the given name
	 * in the given preference store. This method also sets the corresponding
	 * key in the JFace font registry to the value and fires a 
	 * property change event to listeners on the preference store.
	 * 
	 * <p>
	 * Note that this API does not update any other settings that may
	 * be dependant upon it. Only the value in the preference store 
	 * and in the font registry is updated.
	 * </p> 
	 * @param store the preference store
	 * @param name the name of the preference
	 * @param value the new current value of the preference
	 * 
	 * @see #putValue(IPreferenceStore, String, FontData[])
	 */
	public static void setValue(
		IPreferenceStore store,
		String name,
		FontData[] value) {
		FontData[] oldValue = getFontDataArray(store, name);
		// see if the font has changed
		if (!Arrays.equals(oldValue, value)) {
			store.putValue(name, getStoredRepresentation(value));
			JFaceResources.getFontRegistry().put(name, value);
			store.firePropertyChangeEvent(name, oldValue, value);
		}
	}

	/**
	 * Sets the current value of the preference with the given name
	 * in the given preference store. This method does not update
	 * the font registry or fire a property change event.
	 * 
	 * @param store the preference store
	 * @param name the name of the preference
	 * @param value the new current value of the preference
	 * 
	 * @see PreferenceConverter#setValue(IPreferenceStore, String, FontData[])
	 */
	public static void putValue(
		IPreferenceStore store,
		String name,
		FontData[] value) {
		FontData[] oldValue = getFontDataArray(store, name);
		// see if the font has changed
		if (!Arrays.equals(oldValue, value)) {
			store.putValue(name, getStoredRepresentation(value));
		}
	}

	/**
	 * Returns the stored representation of the given array of FontData objects.
	 * The stored representation has the form FontData;FontData;
	 * Only includes the non-null entries.
	 * 
	 * @param fontData the array of FontData objects
	 * @return the stored representation of the FontData objects
	 * @since 3.0
	 */
	public static String getStoredRepresentation(FontData[] fontData) {
		StringBuffer buffer = new StringBuffer();
		for (int i = 0; i < fontData.length; i++) {
			if (fontData[i] != null) {
				buffer.append(fontData[i].toString());
				buffer.append(ENTRY_SEPARATOR);
			}
		}
		return buffer.toString();
	}

	/**
	 * Sets the current value of the preference with the given name
	 * in the given preference store.
	 *
	 * @param store the preference store
	 * @param name the name of the preference
	 * @param value the new current value of the preference
	 */
	public static void setValue(
		IPreferenceStore store,
		String name,
		Point value) {
		Point oldValue = getPoint(store, name);
		if (oldValue == null || !oldValue.equals(value)) {
			store.putValue(name, StringConverter.asString(value));
			store.firePropertyChangeEvent(name, oldValue, value);
		}
	}
	/**
	 * Sets the current value of the preference with the given name
	 * in the given preference store.
	 *
	 * @param store the preference store
	 * @param name the name of the preference
	 * @param value the new current value of the preference
	 */
	public static void setValue(
		IPreferenceStore store,
		String name,
		Rectangle value) {
		Rectangle oldValue = getRectangle(store, name);
		if (oldValue == null || !oldValue.equals(value)) {
			store.putValue(name, StringConverter.asString(value));
			store.firePropertyChangeEvent(name, oldValue, value);
		}
	}
	/**
	 * Sets the current value of the preference with the given name
	 * in the given preference store.
	 *
	 * @param store the preference store
	 * @param name the name of the preference
	 * @param value the new current value of the preference
	 */
	public static void setValue(
		IPreferenceStore store,
		String name,
		RGB value) {
		RGB oldValue = getColor(store, name);
		if (oldValue == null || !oldValue.equals(value)) {
			store.putValue(name, StringConverter.asString(value));
			store.firePropertyChangeEvent(name, oldValue, value);
		}
	}
}
