/*=============================================================================#
 # Copyright (c) 2007, 2021 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ecommons.text.ui.settings;

import java.util.Map;
import java.util.Set;

import org.eclipse.jface.preference.IPreferenceStore;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;

import org.eclipse.statet.ecommons.preferences.SettingsChangeNotifier.ManageListener;
import org.eclipse.statet.ecommons.text.ui.presentation.BasicTextStyleManager;
import org.eclipse.statet.ecommons.text.ui.presentation.ITextPresentationConstants;
import org.eclipse.statet.ecommons.ui.util.UIAccess;


/**
 * Manages text style tokens for a highlighting scanner.
 */
@NonNullByDefault
public abstract class PreferenceStoreTextStyleManager<TAttributes> extends BasicTextStyleManager<TAttributes>
		implements ManageListener {
	
	
	protected final IPreferenceStore preferenceStore;
	
	private final String stylesGroupId;
	
	
	public PreferenceStoreTextStyleManager(final IPreferenceStore preferenceStore,
			final String stylesGroupId) {
		this.preferenceStore= preferenceStore;
		this.stylesGroupId= stylesGroupId;
	}
	
	
	protected String resolveUsedKey(final String key) {
		String use= key;
		while (true) {
			final String test= this.preferenceStore.getString(use+ITextPresentationConstants.TEXTSTYLE_USE_SUFFIX);
			if (test == null || test.equals("") || test.equals(use)) { //$NON-NLS-1$
				return use;
			}
			use= test;
		}
	}
	
	/**
	 * Create a text attribute based on the given color, bold, italic, strikethrough and underline preference keys.
	 * 
	 * @param key the key
	 * @return the created text attribute
	 * @since 3.0
	 */
	@Override
	protected abstract TAttributes createTextAttributes(String key);
	
	
	public boolean affectsTextPresentation(final Set<String> groupIds) {
		return (groupIds.contains(this.stylesGroupId));
	}
	
	public void handleSettingsChanged(final Set<String> groupIds, final Map<String, Object> options) {
		if (affectsTextPresentation(groupIds)) {
			updateTextStyles();
			if (options != null) {
				options.put(ITextPresentationConstants.SETTINGSCHANGE_AFFECTSPRESENTATION_KEY, Boolean.TRUE);
			}
		}
	}
	
	
	@Override
	public void beforeSettingsChangeNotification(final Set<String> groupIds) {
		if (affectsTextPresentation(groupIds)) {
			UIAccess.getDisplay().syncExec(new Runnable() {
				@Override
				public void run() {
					handleSettingsChanged(groupIds, null);
				}
			});
		}
	}
	
	@Override
	public void afterSettingsChangeNotification(final Set<String> groupIds) {
	}
	
}
