/*******************************************************************************
 * Copyright (c) 2001, 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.sse.ui.internal.preferences.ui;



import org.eclipse.jface.resource.ColorRegistry;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.wst.sse.ui.internal.Logger;

import com.ibm.icu.util.StringTokenizer;


public class ColorHelper {
	public final static String BACKGROUND = "background";//$NON-NLS-1$
	public final static String BOLD = "bold";//$NON-NLS-1$
	public final static String FOREGROUND = "foreground";//$NON-NLS-1$
	public final static String NAME = "name";//$NON-NLS-1$
	private final static String STYLE_SEPARATOR = "|"; //$NON-NLS-1$ 
	private final static String NULL = "null"; //$NON-NLS-1$

	/**
	 * Return an RGB String given the int r, g, b values
	 */
	public static String getColorString(int r, int g, int b) {
		return "#" + getHexString(r, 2) + getHexString(g, 2) + getHexString(b, 2);//$NON-NLS-1$
	}

	private static String getHexString(int value, int minWidth) {
		String hexString = Integer.toHexString(value);
		for (int i = hexString.length(); i < minWidth; i++) {
			hexString = "0" + hexString;//$NON-NLS-1$
		}
		return hexString;
	}

	/**
	 * Generates a preference string to be placed in preferences from the
	 * given String array.
	 * 
	 * @param stylePrefs
	 *            assumes not null and should be in the form of String[0] =
	 *            Foreground RGB String, String[1] = Background RGB String,
	 *            String[2] = Bold true/false
	 * 
	 * @return String in the form of Foreground RGB String | Background RGB
	 *         String | Bold true/false
	 */
	public static String packStylePreferences(String[] stylePrefs) {
		StringBuffer styleString = new StringBuffer();

		for (int i = 0; i < stylePrefs.length; ++i) {
			String s = stylePrefs[i];
			if (i < 2) {
				if (s != null) {
					styleString.append(s);
				}
				else {
					styleString.append(NULL);
				}
			}
			else {
				styleString.append(Boolean.valueOf(s));
			}

			// add in the separator (except on last iteration)
			if (i < stylePrefs.length - 1) {
				styleString.append(" " + STYLE_SEPARATOR + " "); //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		return styleString.toString();
	}

	/**
	 * @return org.eclipse.swt.graphics.RGB
	 * @param anRGBString
	 *            java.lang.String
	 */
	public static RGB toRGB(String anRGBString) {
		RGB result = null;
		if (anRGBString.length() > 6 && anRGBString.charAt(0) == '#') {
			int r = 0;
			int g = 0;
			int b = 0;
			try {
				r = Integer.valueOf(anRGBString.substring(1, 3), 16).intValue();
				g = Integer.valueOf(anRGBString.substring(3, 5), 16).intValue();
				b = Integer.valueOf(anRGBString.substring(5, 7), 16).intValue();
				result = new RGB(r, g, b);
			} catch (NumberFormatException nfExc) {
				Logger.logException("Could not load highlighting preference for color " + anRGBString, nfExc);//$NON-NLS-1$
			}
		}
		return result;
	}

	/**
	 * @return java.lang.String
	 * @param anRGB
	 *            org.eclipse.swt.graphics.RGB
	 */
	public static String toRGBString(RGB anRGB) {
		if (anRGB == null)
			return "#000000";//$NON-NLS-1$
		String red = Integer.toHexString(anRGB.red);
		while (red.length() < 2)
			red = "0" + red;//$NON-NLS-1$
		String green = Integer.toHexString(anRGB.green);
		while (green.length() < 2)
			green = "0" + green;//$NON-NLS-1$
		String blue = Integer.toHexString(anRGB.blue);
		while (blue.length() < 2)
			blue = "0" + blue;//$NON-NLS-1$
		return "#" + red + green + blue;//$NON-NLS-1$
	}

	/**
	 * Extracts the foreground (RGB String), background (RGB String), bold
	 * (boolean String) from the given preference string.
	 * 
	 * @param preference
	 *            should be in the form of Foreground RGB String | Background
	 *            RGB String | Bold true/false | Italic true/false | Strikethrough true/false | Underline true/false
	 * @return String[] where String[0] = Foreground RGB String, String[1] =
	 *         Background RGB String, String[2] = Bold true/false, 3 = Italic
	 *         true/false, 4 = Strikethrough true/false, 5 = Underline
	 *         true/false; indexes 2-4 may be null if we ran into problems
	 *         extracting
	 */
	public static String[] unpackStylePreferences(String preference) {
		String[] stylePrefs = new String[6];
		if (preference != null) {
			StringTokenizer st = new StringTokenizer(preference, STYLE_SEPARATOR);
			if (st.hasMoreTokens()) {
				String foreground = st.nextToken().trim();
				stylePrefs[0] = foreground;
			}
			else {
				stylePrefs[0] = NULL;
			}
			if (st.hasMoreTokens()) {
				String background = st.nextToken().trim();
				stylePrefs[1] = background;
			}
			else {
				stylePrefs[1] = NULL;
			}

			if (st.hasMoreTokens()) {
				String bold = st.nextToken().trim();
				stylePrefs[2] = Boolean.valueOf(bold).toString();
			}
			else {
				stylePrefs[2] = Boolean.FALSE.toString();
			}
			if (st.hasMoreTokens()) {
				String italic = st.nextToken().trim();
				stylePrefs[3] = Boolean.valueOf(italic).toString();
			}
			else {
				stylePrefs[3] = Boolean.FALSE.toString();
			}
			if (st.hasMoreTokens()) {
				String strikethrough = st.nextToken().trim();
				stylePrefs[4] = Boolean.valueOf(strikethrough).toString();
			}
			else {
				stylePrefs[4] = Boolean.FALSE.toString();
			}
			if (st.hasMoreTokens()) {
				String underline = st.nextToken().trim();
				stylePrefs[5] = Boolean.valueOf(underline).toString();
			}
			else {
				stylePrefs[5] = Boolean.FALSE.toString();
			}
		}

		return stylePrefs;
	}
	
	/**
	 * Attempts to lookup the RGB value for <code>key</code> from the color
	 * registry. If one is not found, the <code>defaultRGB</code> is used.
	 * @param registry The ColorRegistry to search for the RGB value
	 * @param key The key that the RGB value is stored under in the registry
	 * @param defaultRGB The default RGB value to return in the absence of one
	 * from the color registry
	 * 
	 * @return The RGB value from the color registry for a given key, if it exists.
	 * Otherwise, return the default RGB value.
	 */
	public static RGB findRGB(ColorRegistry registry, String key, RGB defaultRGB) {
		if(registry.hasValueFor(key))
			return registry.getRGB(key);
		return defaultRGB;
	}
	
	/**
	 * Attempts to find the RGB string for <code>key</code> from the color registry.
	 * If one is not found, an RGB string is generated from the parameters <code>r,g,b</code>.
	 * 
	 * @param registry The ColorRegistry to search for the RGB value
	 * @param key The key that the RGB value is stored under in the registry
	 * @param r The default red value
	 * @param g The default green value
	 * @param b The default blue value
	 * 
	 * @return The String RGB value from the color registry for a given key, if it exists.
	 * Otherwise, return the string RGB value created from the default r,g,b parameters.
	 * 
	 */
	public static String findRGBString(ColorRegistry registry, String key, int r, int g, int b) {
		if(registry.hasValueFor(key))
			return toRGBString(registry.getRGB(key));
		return getColorString(r, g, b);
	}
	
}
