/*******************************************************************************
 * Copyright (c) 2000, 2016 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.jdt.internal.debug.ui;


import org.eclipse.jdt.internal.debug.ui.display.DisplayViewerConfiguration;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.ui.text.IJavaPartitions;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.source.IOverviewRuler;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BidiSegmentEvent;
import org.eclipse.swt.custom.BidiSegmentListener;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
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.AbstractTextEditor;

import com.ibm.icu.text.Bidi;

/**
 * A source viewer configured to display Java source. This
 * viewer obeys the font and color preferences specified in
 * the Java UI plugin.
 */
public class JDISourceViewer extends SourceViewer implements IPropertyChangeListener {

	/**
	 * BIDI delimtiers.
	 *
	 * @since 3.4
	 */
	private static final String BIDI_DELIMITERS= "[ \\p{Punct}&&[^_]]"; //$NON-NLS-1$


	private Font fFont;
	private Color fBackgroundColor;
	private Color fForegroundColor;
	private IPreferenceStore fStore;
	private DisplayViewerConfiguration fConfiguration;


	public JDISourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
		this(parent, ruler, null, false, styles);
	}


	public JDISourceViewer(Composite parent, IVerticalRuler ruler, IOverviewRuler overviewRuler, boolean isOverviewRulerVisible, int styles) {
		super(parent, ruler, overviewRuler, isOverviewRulerVisible, styles);
		StyledText text= this.getTextWidget();
		final int baseLevel= (styles & SWT.RIGHT_TO_LEFT) != 0 ? Bidi.DIRECTION_RIGHT_TO_LEFT : Bidi.DIRECTION_LEFT_TO_RIGHT;
		text.addBidiSegmentListener(new  BidiSegmentListener() {
			@Override
			public void lineGetSegments(BidiSegmentEvent event) {
				try {
					event.segments= getBidiLineSegments(getDocument(), baseLevel, widgetOffset2ModelOffset(event.lineOffset), event.lineText);
				} catch (BadLocationException x) {
					// ignore
				}
			}
		});
	}

	/**
	 * Updates the viewer's font to match the preferences.
	 */
	private void updateViewerFont() {
		IPreferenceStore store= getPreferenceStore();
		if (store != null) {
			FontData data= null;
			if (store.contains(PreferenceConstants.EDITOR_TEXT_FONT) && !store.isDefault(PreferenceConstants.EDITOR_TEXT_FONT)) {
				data= PreferenceConverter.getFontData(store, PreferenceConstants.EDITOR_TEXT_FONT);
			} else {
				data = PreferenceConverter.getDefaultFontData(store, PreferenceConstants.EDITOR_TEXT_FONT);
			}
			if (data != null) {
				Font font= new Font(getTextWidget().getDisplay(), data);
				applyFont(font);
				if (getFont() != null) {
					getFont().dispose();
				}
				setFont(font);
				return;
			}
		}
		// if all the preferences failed
		applyFont(JFaceResources.getTextFont());
	}

	/**
	 * Sets the current font.
	 *
	 * @param font the new font
	 */
	private void setFont(Font font) {
		fFont= font;
	}

	/**
	 * Returns the current font.
	 *
	 * @return the current font
	 */
	private Font getFont() {
		return fFont;
	}

	/**
	 * Sets the font for the given viewer sustaining selection and scroll position.
	 *
	 * @param font the font
	 */
	private void applyFont(Font font) {
		IDocument doc= getDocument();
		if (doc != null && doc.getLength() > 0) {
			Point selection= getSelectedRange();
			int topIndex= getTopIndex();

			StyledText styledText= getTextWidget();
			styledText.setRedraw(false);

			styledText.setFont(font);
			setSelectedRange(selection.x , selection.y);
			setTopIndex(topIndex);

			styledText.setRedraw(true);
		} else {
			getTextWidget().setFont(font);
		}
	}

	/**
	 * Updates the given viewer's colors to match the preferences.
	 */
	public void updateViewerColors() {
		IPreferenceStore store= getPreferenceStore();
		if (store != null) {
			StyledText styledText= getTextWidget();
			Color color= store.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT)
				? null
				: createColor(store, AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND, styledText.getDisplay());
			styledText.setForeground(color);
			setForegroundColor(color);

			color= store.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)
				? null
				: createColor(store, AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND, styledText.getDisplay());
			styledText.setBackground(color);
			setBackgroundColor(color);
		}
	}

	/**
	 * Creates a color from the information stored in the given preference store.
	 * Returns <code>null</code> if there is no such information available.
	 */
	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;
	}

	/**
	 * Returns the current background color.
	 *
	 * @return the current background color
	 */
	protected Color getBackgroundColor() {
		return fBackgroundColor;
	}

	/**
	 * Sets the current background color.
	 *
	 * @param backgroundColor the new background color
	 */
	protected void setBackgroundColor(Color backgroundColor) {
		fBackgroundColor = backgroundColor;
	}

	/**
	 * Returns the current foreground color.
	 *
	 * @return the current foreground color
	 */
	protected Color getForegroundColor() {
		return fForegroundColor;
	}

	/**
	 * Sets the current foreground color.
	 *
	 * @param foregroundColor the new foreground color
	 */
	protected void setForegroundColor(Color foregroundColor) {
		fForegroundColor = foregroundColor;
	}

	/**
	 * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
	 */
	@Override
	public void propertyChange(PropertyChangeEvent event) {
		IContentAssistant assistant= getContentAssistant();
		if (assistant instanceof ContentAssistant) {
			JDIContentAssistPreference.changeConfiguration((ContentAssistant) assistant, event);
		}
		String property= event.getProperty();

		if (PreferenceConstants.EDITOR_TEXT_FONT.equals(property)) {
			updateViewerFont();
		}
		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)) {
			updateViewerColors();
		}
		if (fConfiguration != null) {
			if (fConfiguration.affectsTextPresentation(event)) {
				fConfiguration.handlePropertyChangeEvent(event);
				invalidateTextPresentation();
			}
		}
	}

	/**
	 * Returns the current content assistant.
	 *
	 * @return the current content assistant
	 */
	public IContentAssistant getContentAssistant() {
		return fContentAssistant;
	}

	/**
	 * Disposes the system resources currently in use by this viewer.
	 */
	public void dispose() {
		if (getFont() != null) {
			getFont().dispose();
			setFont(null);
		}
		if (getBackgroundColor() != null) {
			setBackgroundColor(null);
		}
		if (getForegroundColor() != null) {
			setForegroundColor(null);
		}
		if (fStore != null) {
			fStore.removePropertyChangeListener(this);
			fStore = null;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.text.source.SourceViewer#configure(org.eclipse.jface.text.source.SourceViewerConfiguration)
	 */
	@Override
	public void configure(SourceViewerConfiguration configuration) {
		super.configure(configuration);
		if (fStore != null) {
			fStore.removePropertyChangeListener(this);
			fStore = null;
		}
		if (configuration instanceof DisplayViewerConfiguration) {
			fConfiguration = (DisplayViewerConfiguration) configuration;
			fStore = fConfiguration.getTextPreferenceStore();
			fStore.addPropertyChangeListener(this);
		}
		updateViewerFont();
		updateViewerColors();
	}

	/**
	 * Returns the preference store used to configure this source viewer or
	 * <code>null</code> if none;
	 */
	private IPreferenceStore getPreferenceStore() {
		return fStore;
	}

	/**
	 * Returns a segmentation of the line of the given document appropriate for Bidi rendering.
	 *
	 * @param document the document
	 * @param baseLevel the base level of the line
	 * @param lineStart the offset of the line
	 * @param lineText Text of the line to retrieve Bidi segments for
	 * @return the line's Bidi segmentation
	 * @throws BadLocationException in case lineOffset is not valid in document
	 */
	protected static int[] getBidiLineSegments(IDocument document, int baseLevel, int lineStart, String lineText) throws BadLocationException {

		if (lineText == null || document == null) {
			return null;
		}

		int lineLength= lineText.length();
		if (lineLength <= 2) {
			return null;
		}

		// Have ICU compute embedding levels. Consume these levels to reduce
		// the Bidi impact, by creating selective segments (preceding
		// character runs with a level mismatching the base level).
		// XXX: Alternatively, we could apply TextLayout. Pros would be full
		// synchronization with the underlying StyledText's (i.e. native) Bidi
		// implementation. Cons are performance penalty because of
		// unavailability of such methods as isLeftToRight and getLevels.

		Bidi bidi= new Bidi(lineText, baseLevel);
		if (bidi.isLeftToRight()) {
			// Bail out if this is not Bidi text.
			return null;
		}

		IRegion line= document.getLineInformationOfOffset(lineStart);
		ITypedRegion[] linePartitioning= TextUtilities.computePartitioning(document, IJavaPartitions.JAVA_PARTITIONING, lineStart, line.getLength(), false);
		if (linePartitioning == null || linePartitioning.length < 1) {
			return null;
		}

		int segmentIndex= 1;
		int[] segments= new int[lineLength + 1];
		byte[] levels= bidi.getLevels();
		int nPartitions= linePartitioning.length;
		for (int partitionIndex= 0; partitionIndex < nPartitions; partitionIndex++) {

			ITypedRegion partition= linePartitioning[partitionIndex];
			int lineOffset= partition.getOffset() - lineStart;
			//Assert.isTrue(lineOffset >= 0 && lineOffset < lineLength);

			if (lineOffset > 0 && isMismatchingLevel(levels[lineOffset], baseLevel) && isMismatchingLevel(levels[lineOffset - 1], baseLevel)) {
				// Indicate a Bidi segment at the partition start - provided
				// levels of both character at the current offset and its
				// preceding character mismatch the base paragraph level.
				// Partition end will be covered either by the start of the next
				// partition, a delimiter inside a next partition, or end of line.
				segments[segmentIndex++]= lineOffset;
			}
			if (IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())) {
				int partitionEnd= Math.min(lineLength, lineOffset + partition.getLength());
				while (++lineOffset < partitionEnd) {
					if (isMismatchingLevel(levels[lineOffset], baseLevel) && String.valueOf(lineText.charAt(lineOffset)).matches(BIDI_DELIMITERS)) {
						// For default content types, indicate a segment before
						// a delimiting character with a mismatching embedding
						// level.
						segments[segmentIndex++]= lineOffset;
					}
				}
			}
		}
		if (segmentIndex <= 1) {
			return null;
		}

		segments[0]= 0;
		if (segments[segmentIndex - 1] != lineLength) {
			segments[segmentIndex++]= lineLength;
		}

		if (segmentIndex == segments.length) {
			return segments;
		}

		int[] newSegments= new int[segmentIndex];
		System.arraycopy(segments, 0, newSegments, 0, segmentIndex);
		return newSegments;
	}

	/**
	 * Checks if the given embedding level is consistent with the base level.
	 *
	 * @param level Character embedding level to check.
	 * @param baseLevel Base level (direction) of the text.
	 * @return <code>true</code> if the character level is odd and the base level is even OR the character level is even and the base level is odd, and return <code>false</code> otherwise.
	 *
	 * @since 3.4
	 */
	private static boolean isMismatchingLevel(int level, int baseLevel) {
		return ((level ^ baseLevel) & 1) != 0;
	}

}
