/*******************************************************************************
 * Copyright (c) 2000, 2016 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
 *******************************************************************************/
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);
			if (getForegroundColor() != null) {
				getForegroundColor().dispose();
			}
			setForegroundColor(color);

			color= store.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)
				? null
				: createColor(store, AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND, styledText.getDisplay());
			styledText.setBackground(color);
			if (getBackgroundColor() != null) {
				getBackgroundColor().dispose();
			}
			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) {
			getBackgroundColor().dispose();
			setBackgroundColor(null);
		}
		if (getForegroundColor() != null) {
			getForegroundColor().dispose();
			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;
	}

}
