/*******************************************************************************
 * Copyright (c) 2004, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.internal.themes;

import java.util.Objects;
import java.util.ResourceBundle;
import java.util.Set;
import org.eclipse.core.commands.common.EventManager;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.resource.ColorRegistry;
import org.eclipse.jface.resource.DataFormatException;
import org.eclipse.jface.resource.FontRegistry;
import org.eclipse.jface.resource.StringConverter;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.util.PrefUtil;
import org.eclipse.ui.themes.ITheme;
import org.eclipse.ui.themes.IThemeManager;

/**
 * @since 3.0
 */
public class Theme extends EventManager implements ITheme {

	/**
	 * The translation bundle in which to look up internationalized text.
	 */
	private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(Theme.class.getName());

	private CascadingColorRegistry themeColorRegistry;

	private CascadingFontRegistry themeFontRegistry;

	private IThemeDescriptor descriptor;

	private IPropertyChangeListener themeListener;

	private CascadingMap dataMap;

	private ThemeRegistry themeRegistry;

	private IPropertyChangeListener propertyListener;

	/**
	 * @param descriptor
	 */
	public Theme(IThemeDescriptor descriptor) {
		themeRegistry = ((ThemeRegistry) WorkbenchPlugin.getDefault().getThemeRegistry());
		this.descriptor = descriptor;
		IWorkbench workbench = PlatformUI.getWorkbench();
		if (descriptor != null) {
			ITheme defaultTheme = workbench.getThemeManager().getTheme(IThemeManager.DEFAULT_THEME);

			ColorDefinition[] colorDefinitions = this.descriptor.getColors();
			themeColorRegistry = new CascadingColorRegistry(defaultTheme.getColorRegistry());
			if (colorDefinitions.length > 0) {
				ThemeElementHelper.populateRegistry(this, colorDefinitions, PrefUtil.getInternalPreferenceStore());
			}

			FontDefinition[] fontDefinitions = this.descriptor.getFonts();
			themeFontRegistry = new CascadingFontRegistry(defaultTheme.getFontRegistry());
			if (fontDefinitions.length > 0) {
				ThemeElementHelper.populateRegistry(this, fontDefinitions, PrefUtil.getInternalPreferenceStore());
			}

			dataMap = new CascadingMap(((ThemeRegistry) WorkbenchPlugin.getDefault().getThemeRegistry()).getData(),
					descriptor.getData());
		}

		getColorRegistry().addListener(getCascadeListener());
		getColorRegistry().addListener(this::registryColorChangeEvent);
		getFontRegistry().addListener(getCascadeListener());
		PrefUtil.getInternalPreferenceStore().addPropertyChangeListener(getPropertyListener());
	}

	/**
	 * When a color in the registry is updated, update the backing preferences
	 * appropriately.
	 *
	 * @param event the color change event
	 */
	private void registryColorChangeEvent(PropertyChangeEvent event) {
		if (event.getNewValue() instanceof RGB) {
			String key = ThemeElementHelper.createPreferenceKey(this, event.getProperty());
			IPreferenceStore store = PrefUtil.getInternalPreferenceStore();
			if (store.contains(key)) {
				RGB newColor = (RGB) event.getNewValue();
				if (store.isDefault(key)) {
					RGB oldColor = PreferenceConverter.getDefaultColor(store, key);
					if (oldColor == PreferenceConverter.COLOR_DEFAULT_DEFAULT) {
						// If the preference is set to default, but there is no actual default value,
						// then the preference state is inconsistent. Do nothing.
					} else if (!newColor.equals(oldColor))
						PreferenceConverter.setValue(store, key, newColor);
				} else {
					RGB oldColor = PreferenceConverter.getColor(store, key);
					if (!newColor.equals(oldColor)) {
						oldColor = PreferenceConverter.getDefaultColor(store, key);
						if (oldColor != PreferenceConverter.COLOR_DEFAULT_DEFAULT && newColor.equals(oldColor))
							store.setToDefault(key);
						else
							PreferenceConverter.setValue(store, key, newColor);
					}
				}
			}
		}
	}

	/**
	 * Listener that is responsible for responding to preference changes.
	 *
	 * @return the property change listener
	 */
	private IPropertyChangeListener getPropertyListener() {
		if (propertyListener == null) {
			propertyListener = new IPropertyChangeListener() {

				@Override
				public void propertyChange(PropertyChangeEvent event) {
					String[] split = ThemeElementHelper.splitPropertyName(Theme.this, event.getProperty());
					String key = split[1];
					String theme = split[0];
					if (key.equals(IWorkbenchPreferenceConstants.CURRENT_THEME_ID)) {
						return;
					}
					try {
						String thisTheme = getId();

						if (Objects.equals(thisTheme, theme)) {
							if (getFontRegistry().hasValueFor(key)) {
								FontData[] data = event.getNewValue() instanceof String
										? PreferenceConverter.basicGetFontData((String) event.getNewValue())
										: (FontData[]) event.getNewValue();

								getFontRegistry().put(key, data);
								processDefaultsTo(key, data);
							} else if (getColorRegistry().hasValueFor(key)) {
								RGB rgb = event.getNewValue() instanceof String
										? StringConverter.asRGB((String) event.getNewValue())
										: (RGB) event.getNewValue();
								if (!Objects.equals(getColorRegistry().getRGB(key), rgb)) {
									getColorRegistry().put(key, rgb);
									processDefaultsTo(key, rgb);
								}
							}
						}
					} catch (DataFormatException e) {
						// no-op
					}
				}

				/**
				 * Process all fonts that default to the given ID.
				 *
				 * @param key the font ID
				 * @param fd  the new FontData for defaulted fonts
				 */
				private void processDefaultsTo(String key, FontData[] fd) {
					FontDefinition[] defs = WorkbenchPlugin.getDefault().getThemeRegistry().getFontsFor(getId());
					for (FontDefinition fontDefinition : defs) {
						String defaultsTo = fontDefinition.getDefaultsTo();
						if (defaultsTo != null && defaultsTo.equals(key)) {
							IPreferenceStore store = WorkbenchPlugin.getDefault().getPreferenceStore();
							if (store.isDefault(
									ThemeElementHelper.createPreferenceKey(Theme.this, fontDefinition.getId()))) {
								getFontRegistry().put(fontDefinition.getId(), fd);
								processDefaultsTo(fontDefinition.getId(), fd);
							}
						}
					}
				}

				/**
				 * Process all colors that default to the given ID.
				 *
				 * @param key the color ID
				 * @param rgb the new RGB value for defaulted colors
				 */
				private void processDefaultsTo(String key, RGB rgb) {
					ColorDefinition[] defs = WorkbenchPlugin.getDefault().getThemeRegistry().getColorsFor(getId());
					for (ColorDefinition colorDefinition : defs) {
						String defaultsTo = colorDefinition.getDefaultsTo();
						if (defaultsTo != null && defaultsTo.equals(key)) {
							IPreferenceStore store = WorkbenchPlugin.getDefault().getPreferenceStore();
							String prefkey = ThemeElementHelper.createPreferenceKey(Theme.this,
									colorDefinition.getId());
							if (store.isDefault(prefkey)) {
								PreferenceConverter.setDefault(store, prefkey, rgb);
								getColorRegistry().put(colorDefinition.getId(), rgb);
								processDefaultsTo(colorDefinition.getId(), rgb);
							}
						}
					}
				}
			};
		}
		return propertyListener;
	}

	/**
	 * Listener that is responsible for rebroadcasting events fired from the base
	 * font/color registry
	 */
	private IPropertyChangeListener getCascadeListener() {
		if (themeListener == null) {
			themeListener = this::firePropertyChange;
		}
		return themeListener;
	}

	@Override
	public ColorRegistry getColorRegistry() {
		if (themeColorRegistry != null) {
			return themeColorRegistry;
		}

		return WorkbenchThemeManager.getInstance().getDefaultThemeColorRegistry();
	}

	@Override
	public FontRegistry getFontRegistry() {
		if (themeFontRegistry != null) {
			return themeFontRegistry;
		}

		return WorkbenchThemeManager.getInstance().getDefaultThemeFontRegistry();
	}

	@Override
	public void dispose() {
		if (themeColorRegistry != null) {
			themeColorRegistry.removeListener(themeListener);
			themeColorRegistry.removeListener(this::registryColorChangeEvent);
			themeColorRegistry.dispose();
		}
		if (themeFontRegistry != null) {
			themeFontRegistry.removeListener(themeListener);
			themeFontRegistry.dispose();
		}
		PrefUtil.getInternalPreferenceStore().removePropertyChangeListener(getPropertyListener());
	}

	@Override
	public String getId() {
		return descriptor == null ? IThemeManager.DEFAULT_THEME : descriptor.getId();
	}

	@Override
	public void addPropertyChangeListener(IPropertyChangeListener listener) {
		addListenerObject(listener);
	}

	@Override
	public void removePropertyChangeListener(IPropertyChangeListener listener) {
		removeListenerObject(listener);
	}

	private void firePropertyChange(PropertyChangeEvent event) {
		for (Object listener : getListeners()) {
			((IPropertyChangeListener) listener).propertyChange(event);
		}
	}

	@Override
	public String getLabel() {
		return descriptor == null ? RESOURCE_BUNDLE.getString("DefaultTheme.label") : descriptor.getName(); //$NON-NLS-1$
	}

	@Override
	public String getString(String key) {
		if (dataMap != null) {
			return (String) dataMap.get(key);
		}
		return (String) themeRegistry.getData().get(key);
	}

	@Override
	public Set keySet() {
		if (dataMap != null) {
			return dataMap.keySet();
		}

		return themeRegistry.getData().keySet();
	}

	@Override
	public int getInt(String key) {
		String string = getString(key);
		if (string == null) {
			return 0;
		}
		try {
			return Integer.parseInt(string);
		} catch (NumberFormatException e) {
			return 0;
		}
	}

	@Override
	public boolean getBoolean(String key) {
		String string = getString(key);
		if (string == null) {
			return false;
		}

		return Boolean.parseBoolean(getString(key));
	}
}
