/*******************************************************************************
 * Copyright (c) 2000, 2017 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
 * 			Alex Panchenko <alex@xored.com>
 *******************************************************************************/
package org.eclipse.dltk.internal.ui.editor;

import java.util.ArrayList;

import org.eclipse.core.runtime.Assert;
import org.eclipse.dltk.ui.text.ScriptSourceViewerConfiguration;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextPresentationListener;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.information.IInformationPresenter;
import org.eclipse.jface.text.reconciler.IReconciler;
import org.eclipse.jface.text.source.IOverviewRuler;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
import org.eclipse.ui.texteditor.AbstractTextEditor;

public class ScriptSourceViewer extends ProjectionViewer implements
		IPropertyChangeListener {

	/**
	 * Text operation code for requesting the outline for the current input.
	 */
	public static final int SHOW_OUTLINE = 51;

	/**
	 * Text operation code for requesting the outline for the element at the
	 * current position.
	 */
	public static final int OPEN_STRUCTURE = 52;

	/**
	 * Text operation code for requesting the hierarchy for the current input.
	 */
	public static final int SHOW_HIERARCHY = 53;

	private IInformationPresenter fOutlinePresenter;

	private IInformationPresenter fStructurePresenter;

	private IInformationPresenter fHierarchyPresenter;

	/**
	 * This viewer's foreground color.
	 */
	private Color fForegroundColor;

	/**
	 * The viewer's background color.
	 */
	private Color fBackgroundColor;

	/**
	 * This viewer's selection foreground color.
	 */
	private Color fSelectionForegroundColor;

	/**
	 * The viewer's selection background color.
	 */
	private Color fSelectionBackgroundColor;

	/**
	 * The preference store.
	 */
	private IPreferenceStore fPreferenceStore;

	/**
	 * Is this source viewer configured?
	 */
	private boolean fIsConfigured;

	// /**
	// * The backspace manager of this viewer.
	// *
	// */
	// private SmartBackspaceManager fBackspaceManager;

	/**
	 * Whether to delay setting the visual document until the projection has
	 * been computed.
	 * <p>
	 * Added for performance optimization.
	 * </p>
	 *
	 * @see #prepareDelayedProjection()
	 */
	private boolean fIsSetVisibleDocumentDelayed = false;

	public ScriptSourceViewer(Composite parent, IVerticalRuler verticalRuler,
			IOverviewRuler overviewRuler, boolean showAnnotationsOverview,
			int styles, IPreferenceStore store) {
		super(parent, verticalRuler, overviewRuler, showAnnotationsOverview,
				styles);
		setPreferenceStore(store);
	}

	@Override
	public void doOperation(int operation) {
		if (getTextWidget() == null)
			return;

		switch (operation) {
		case SHOW_OUTLINE:
			if (fOutlinePresenter != null)
				fOutlinePresenter.showInformation();
			return;
		case OPEN_STRUCTURE:
			if (fStructurePresenter != null)
				fStructurePresenter.showInformation();
			return;
		case SHOW_HIERARCHY:
			if (fHierarchyPresenter != null)
				fHierarchyPresenter.showInformation();
			return;
		}

		super.doOperation(operation);
	}

	@Override
	public boolean canDoOperation(int operation) {
		if (operation == SHOW_OUTLINE)
			return fOutlinePresenter != null;
		if (operation == OPEN_STRUCTURE)
			return fStructurePresenter != null;
		if (operation == SHOW_HIERARCHY)
			return fHierarchyPresenter != null;

		return super.canDoOperation(operation);
	}

	@Override
	public void configure(SourceViewerConfiguration configuration) {

		/*
		 * Prevent access to colors disposed in unconfigure(), see:
		 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=53641
		 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=86177
		 */
		StyledText textWidget = getTextWidget();
		if (textWidget != null && !textWidget.isDisposed()) {
			Color foregroundColor = textWidget.getForeground();
			if (foregroundColor != null && foregroundColor.isDisposed())
				textWidget.setForeground(null);
			Color backgroundColor = textWidget.getBackground();
			if (backgroundColor != null && backgroundColor.isDisposed())
				textWidget.setBackground(null);
		}

		super.configure(configuration);
		if (configuration instanceof ScriptSourceViewerConfiguration) {
			ScriptSourceViewerConfiguration dltkSVCconfiguration = (ScriptSourceViewerConfiguration) configuration;
			fOutlinePresenter = dltkSVCconfiguration.getOutlinePresenter(this,
					false);
			if (fOutlinePresenter != null)
				fOutlinePresenter.install(this);

			fStructurePresenter = dltkSVCconfiguration.getOutlinePresenter(
					this, true);
			if (fStructurePresenter != null)
				fStructurePresenter.install(this);

			fHierarchyPresenter = dltkSVCconfiguration.getHierarchyPresenter(
					this, true);
			if (fHierarchyPresenter != null)
				fHierarchyPresenter.install(this);
			if (textWidget != null) {
				textWidget.setFont(JFaceResources.getFont(dltkSVCconfiguration
						.getFontPropertyPreferenceKey()));
			}
		}

		if (fPreferenceStore != null) {
			fPreferenceStore.addPropertyChangeListener(this);
			initializeViewerColors();
		}

		fIsConfigured = true;
	}

	public void initializeViewerColors() {
		if (fPreferenceStore != null) {

			StyledText styledText = getTextWidget();

			// ----------- foreground color --------------------
			Color color = fPreferenceStore
					.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT) ? null
					: createColor(fPreferenceStore,
							AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND,
							styledText.getDisplay());
			styledText.setForeground(color);

			if (fForegroundColor != null)
				fForegroundColor.dispose();

			fForegroundColor = color;

			// ---------- background color ----------------------
			color = fPreferenceStore
					.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT) ? null
					: createColor(fPreferenceStore,
							AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND,
							styledText.getDisplay());
			styledText.setBackground(color);

			if (fBackgroundColor != null)
				fBackgroundColor.dispose();

			fBackgroundColor = color;

			// ----------- selection foreground color --------------------
			color = fPreferenceStore
					.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_DEFAULT_COLOR) ? null
					: createColor(
							fPreferenceStore,
							AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_COLOR,
							styledText.getDisplay());
			styledText.setSelectionForeground(color);

			if (fSelectionForegroundColor != null)
				fSelectionForegroundColor.dispose();

			fSelectionForegroundColor = color;

			// ---------- selection background color ----------------------
			color = fPreferenceStore
					.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_DEFAULT_COLOR) ? null
					: createColor(
							fPreferenceStore,
							AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_COLOR,
							styledText.getDisplay());
			styledText.setSelectionBackground(color);

			if (fSelectionBackgroundColor != null)
				fSelectionBackgroundColor.dispose();

			fSelectionBackgroundColor = color;
		}
	}

	/**
	 * Creates a color from the information stored in the given preference
	 * store. Returns <code>null</code> if there is no such information
	 * available.
	 *
	 * @param store
	 *            the store to read from
	 * @param key
	 *            the key used for the lookup in the preference store
	 * @param display
	 *            the display used create the color
	 * @return the created color according to the specification in the
	 *         preference store
	 */
	private Color createColor(IPreferenceStore store, String key,
			Display display) {

		RGB rgb = null;

		if (store.contains(key)) {

			if (store.isDefault(key))
				rgb = PreferenceConverter.getDefaultColor(store, key);
			else
				rgb = PreferenceConverter.getColor(store, key);

			if (rgb != null)
				return new Color(display, rgb);
		}

		return null;
	}

	@Override
	public void unconfigure() {
		if (fOutlinePresenter != null) {
			fOutlinePresenter.uninstall();
			fOutlinePresenter = null;
		}
		if (fStructurePresenter != null) {
			fStructurePresenter.uninstall();
			fStructurePresenter = null;
		}
		if (fHierarchyPresenter != null) {
			fHierarchyPresenter.uninstall();
			fHierarchyPresenter = null;
		}
		if (fForegroundColor != null) {
			fForegroundColor.dispose();
			fForegroundColor = null;
		}
		if (fBackgroundColor != null) {
			fBackgroundColor.dispose();
			fBackgroundColor = null;
		}

		if (fPreferenceStore != null)
			fPreferenceStore.removePropertyChangeListener(this);

		super.unconfigure();

		fIsConfigured = false;
	}

	@Override
	public Point rememberSelection() {
		return super.rememberSelection();
	}

	@Override
	public void restoreSelection() {
		super.restoreSelection();
	}

	@Override
	public void propertyChange(PropertyChangeEvent event) {
		String property = event.getProperty();
		if (AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND.equals(property)
				|| AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT
						.equals(property)
				|| AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND
						.equals(property)
				|| AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT
						.equals(property)
				|| AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_COLOR
						.equals(property)
				|| AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_DEFAULT_COLOR
						.equals(property)
				|| AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_COLOR
						.equals(property)
				|| AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_DEFAULT_COLOR
						.equals(property)) {
			initializeViewerColors();
		}
	}

	/**
	 * Sets the preference store on this viewer.
	 *
	 * @param store
	 *            the preference store
	 */
	public void setPreferenceStore(IPreferenceStore store) {
		if (fIsConfigured && fPreferenceStore != null)
			fPreferenceStore.removePropertyChangeListener(this);

		fPreferenceStore = store;

		if (fIsConfigured && fPreferenceStore != null) {
			fPreferenceStore.addPropertyChangeListener(this);
			initializeViewerColors();
		}
	}

	@Override
	public void resetVisibleRegion() {
		super.resetVisibleRegion();
		// re-enable folding if ProjectionViewer failed to due so
		// TODO: Add editor folding option here.
		if (fPreferenceStore != null && !isProjectionMode())
			enableProjection();
		/*
		 * && fPreferenceStore.getBoolean(PreferenceConstants.
		 * EDITOR_FOLDING_ENABLED)
		 */
	}

	@Override
	protected void createControl(Composite parent, int styles) {

		// Use LEFT_TO_RIGHT unless otherwise specified.
		if ((styles & SWT.RIGHT_TO_LEFT) == 0
				&& (styles & SWT.LEFT_TO_RIGHT) == 0)
			styles |= SWT.LEFT_TO_RIGHT;

		super.createControl(parent, styles);

		// System.err.println("Add backup manager");
		// fBackspaceManager= new SmartBackspaceManager();
		// fBackspaceManager.install(this);
	}

	@Override
	protected void handleDispose() {
		// if (fBackspaceManager != null) {
		// fBackspaceManager.uninstall();
		// fBackspaceManager = null;
		// }

		super.handleDispose();
	}

	/**
	 * Prepends the text presentation listener at the beginning of the viewer's
	 * list of text presentation listeners. If the listener is already
	 * registered with the viewer this call moves the listener to the beginning
	 * of the list.
	 *
	 * @param listener
	 *            the text presentation listener
	 */
	public void prependTextPresentationListener(
			ITextPresentationListener listener) {

		Assert.isNotNull(listener);

		if (fTextPresentationListeners == null)
			fTextPresentationListeners = new ArrayList();

		fTextPresentationListeners.remove(listener);
		fTextPresentationListeners.add(0, listener);
	}

	/**
	 * Sets the given reconciler.
	 *
	 * @param reconciler
	 *            the reconciler
	 */
	void setReconciler(IReconciler reconciler) {
		fReconciler = reconciler;
	}

	/**
	 * Returns the reconciler.
	 *
	 * @return the reconciler or <code>null</code> if not set
	 */
	IReconciler getReconciler() {
		return fReconciler;
	}

	/**
	 * Delays setting the visual document until after the projection has been
	 * computed. This method must only be called before the document is set on
	 * the viewer.
	 * <p>
	 * This is a performance optimization to reduce the computation of the text
	 * presentation triggered by <code>setVisibleDocument(IDocument)</code>.
	 * </p>
	 *
	 * @see #setVisibleDocument(IDocument)
	 */
	void prepareDelayedProjection() {
		Assert.isTrue(!fIsSetVisibleDocumentDelayed);
		fIsSetVisibleDocumentDelayed = true;
	}

	/**
	 * {@inheritDoc}
	 * <p>
	 * This is a performance optimization to reduce the computation of the text
	 * presentation triggered by {@link #setVisibleDocument(IDocument)}
	 * </p>
	 *
	 * @see #prepareDelayedProjection()
	 */
	@Override
	protected void setVisibleDocument(IDocument document) {
		if (fIsSetVisibleDocumentDelayed) {
			fIsSetVisibleDocumentDelayed = false;
			IDocument previous = getVisibleDocument();
			// will set the visible document if anything is folded
			enableProjection();
			IDocument current = getVisibleDocument();
			// if the visible document was not replaced, continue as usual
			if (current != null && current != previous)
				return;
		}

		super.setVisibleDocument(document);
	}

	/**
	 * {@inheritDoc}
	 * <p>
	 * Performance optimization: since we know at this place that none of the
	 * clients expects the given range to be untouched we reuse the given range
	 * as return value.
	 * </p>
	 */
	@Override
	protected StyleRange modelStyleRange2WidgetStyleRange(StyleRange range) {
		IRegion region = modelRange2WidgetRange(new Region(range.start,
				range.length));
		if (region != null) {
			// don't clone the style range, but simply reuse it.
			range.start = region.getOffset();
			range.length = region.getLength();
			return range;
		}
		return null;
	}
}
