/*=============================================================================#
 # Copyright (c) 2011, 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.ltk.ui.sourceediting.util;

import static org.eclipse.ui.texteditor.AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND;
import static org.eclipse.ui.texteditor.AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT;
import static org.eclipse.ui.texteditor.AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND;
import static org.eclipse.ui.texteditor.AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT;
import static org.eclipse.ui.texteditor.AbstractTextEditor.PREFERENCE_COLOR_SELECTION_BACKGROUND;
import static org.eclipse.ui.texteditor.AbstractTextEditor.PREFERENCE_COLOR_SELECTION_BACKGROUND_SYSTEM_DEFAULT;
import static org.eclipse.ui.texteditor.AbstractTextEditor.PREFERENCE_COLOR_SELECTION_FOREGROUND;
import static org.eclipse.ui.texteditor.AbstractTextEditor.PREFERENCE_COLOR_SELECTION_FOREGROUND_SYSTEM_DEFAULT;

import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.RGB;

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


@NonNullByDefault
public class SourceViewerEditorPreferenceUpdater {
	
	
	protected final ISourceViewer viewer;
	
	private final boolean manageColors;
	private final boolean manageFont;
	
	protected final IPreferenceStore preferenceStore;
	private @Nullable IPropertyChangeListener preferenceStoreListener;
	
	private @Nullable IPropertyChangeListener fontRegistryListener;
	
	
	public SourceViewerEditorPreferenceUpdater(final SourceViewer viewer,
			final boolean manageColors, final boolean manageFont,
			final IPreferenceStore preferenceStore ) {
		this.viewer= nonNullAssert(viewer);
		
		this.manageColors= manageColors;
		this.manageFont= manageColors;
		
		this.preferenceStore= nonNullAssert(preferenceStore);
		
		final var textWidget= nonNullAssert(viewer.getTextWidget());
		textWidget.addDisposeListener(new DisposeListener() {
			@Override
			public void widgetDisposed(final DisposeEvent e) {
				dispose();
			}
		});
		
		if (this.manageColors) {
			final IPropertyChangeListener listener= new IPropertyChangeListener() {
				@Override
				public void propertyChange(final PropertyChangeEvent event) {
					final String prefKey= event.getProperty();
					final boolean updateColors= (SourceViewerEditorPreferenceUpdater.this.manageColors
							&& (PREFERENCE_COLOR_FOREGROUND.equals(prefKey)
									|| PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT.equals(prefKey)
									|| PREFERENCE_COLOR_BACKGROUND.equals(prefKey)
									|| PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT.equals(prefKey)
									|| PREFERENCE_COLOR_SELECTION_FOREGROUND.equals(prefKey)
									|| PREFERENCE_COLOR_SELECTION_FOREGROUND_SYSTEM_DEFAULT.equals(prefKey)
									|| PREFERENCE_COLOR_SELECTION_BACKGROUND.equals(prefKey)
									|| PREFERENCE_COLOR_SELECTION_BACKGROUND_SYSTEM_DEFAULT.equals(prefKey) ));
					final boolean updateFont= false;
					if (updateColors || updateFont) {
						update(updateColors, updateFont);
					}
				}
			};
			this.preferenceStoreListener= listener;
			this.preferenceStore.addPropertyChangeListener(listener);
		}
		if (this.manageFont) {
			final var listener= new IPropertyChangeListener() {
				@Override
				public void propertyChange(final PropertyChangeEvent event) {
					final String prefKey= event.getProperty();
					final boolean updateFont= (getSymbolicFontName().equals(prefKey));
					if (updateFont) {
						update(false, updateFont);
					}
				}
			};
			this.fontRegistryListener= listener;
			JFaceResources.getFontRegistry().addListener(listener);
		}
		
		update(this.manageColors, this.manageFont);
	}
	
	public SourceViewerEditorPreferenceUpdater(final SourceViewer viewer,
			final IPreferenceStore preferenceStore) {
		this(viewer, true, true, preferenceStore);
	}
	
	
	protected String getSymbolicFontName() {
		return JFaceResources.TEXT_FONT;
	}
	
	
	protected void update(final boolean updateColors, final boolean updateFont) {
		final var viewer= this.viewer;
		final StyledText styledText= viewer.getTextWidget();
		if (styledText != null && !styledText.isDisposed()) {
			if (updateColors) {
				updateColors(viewer, styledText);
			}
			if (updateFont) {
				updateFont(viewer, styledText);
			}
		}
	}
	
	protected void updateColors(final ISourceViewer viewer, final StyledText styledText) {
		{	// foreground color
			final Color color= this.preferenceStore.getBoolean(
					PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT) ? null :
							createColor(this.preferenceStore, PREFERENCE_COLOR_FOREGROUND);
			styledText.setForeground(color);
		}
		{	// background color
			final Color color= this.preferenceStore.getBoolean(
					PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT) ? null :
							createColor(this.preferenceStore, PREFERENCE_COLOR_BACKGROUND);
			styledText.setBackground(color);
		}
		{	// selection foreground color
			final Color color= this.preferenceStore.getBoolean(
					PREFERENCE_COLOR_SELECTION_FOREGROUND_SYSTEM_DEFAULT) ? null :
							createColor(this.preferenceStore, PREFERENCE_COLOR_SELECTION_FOREGROUND);
			styledText.setSelectionForeground(color);
		}
		{	// selection background color
			final Color color= this.preferenceStore.getBoolean(
					PREFERENCE_COLOR_SELECTION_BACKGROUND_SYSTEM_DEFAULT) ? null :
							createColor(this.preferenceStore, PREFERENCE_COLOR_SELECTION_BACKGROUND);
			styledText.setSelectionBackground(color);
		}
	}
	
	protected @Nullable Color createColor(final IPreferenceStore store, final String key) {
		final RGB rgb= PreferenceConverter.getColor(store, key);
		return (rgb != null) ? new Color(rgb) : null;
	}
	
	protected void updateFont(final ISourceViewer viewer, final StyledText styledText) {
		{	final Font font= JFaceResources.getFont(getSymbolicFontName());
			styledText.setFont(font);
		}
	}
	
	
	protected void dispose() {
		{	final var listener= this.preferenceStoreListener;
			if (listener != null) {
				this.preferenceStoreListener= null;
				this.preferenceStore.removePropertyChangeListener(listener);
			}
		}
		{	final var listener= this.fontRegistryListener;
			if (listener != null) {
				this.fontRegistryListener= null;
				JFaceResources.getFontRegistry().removeListener(listener);
			}
		}
		
		final var styledText= this.viewer.getTextWidget();
		if (styledText != null && !styledText.isDisposed()) {
			if (this.manageColors) {
				styledText.setForeground(null);
				styledText.setBackground(null);
				styledText.setSelectionForeground(null);
				styledText.setSelectionBackground(null);
			}
			if (this.manageFont) {
				styledText.setFont(null);
			}
		}
	}
	
}
