/*=============================================================================#
 # Copyright (c) 2013, 2019 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;

import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IPositionUpdater;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.JFaceTextUtil;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.information.IInformationPresenter;
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.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;

import org.eclipse.statet.ecommons.text.core.util.NonDeletingPositionUpdater;


public class SourceEditorViewer extends ProjectionViewer {
	
	
	/**
	 * Text operation code for requesting the outline for the current input.
	 */
	public static final int SHOW_SOURCE_OUTLINE=            51;
	
	/**
	 * Text operation code for requesting the outline for the element at the current position.
	 */
	public static final int SHOW_ELEMENT_OUTLINE=           52;
	
	/**
	 * Text operation code for requesting the hierarchy for the current input.
	 */
	public static final int SHOW_ELEMENT_HIERARCHY=         53;
	
	
	public static final int VARIABLE_LINE_HEIGHT= 0b0_0000_0000_0001_0000;
	
	
	private static final int QUICK_PRESENTER_START= SHOW_SOURCE_OUTLINE;
	private static final int QUICK_PRESENTER_END= SHOW_ELEMENT_HIERARCHY;
	
	
	private final int flags;
	
	private int lastSentSelectionOffset;
	private int lastSentSelectionLength;
	
	private IInformationPresenter sourceOutlinePresenter;
	private IInformationPresenter elementOutlinePresenter;
	private IInformationPresenter elementHierarchyPresenter;
	
	
	public SourceEditorViewer(final Composite parent, final IVerticalRuler ruler,
			final IOverviewRuler overviewRuler, final boolean showsAnnotationOverview, final int styles,
			final int flags) {
		super(parent, ruler, overviewRuler, showsAnnotationOverview, styles);
		this.flags= flags;
		
		addPostSelectionChangedListener(new ISelectionChangedListener() {
			/** 
			 * By default source viewers do not caret changes to selection change listeners, only 
			 * to post selection change listeners.  This sents these post selection changes after
			 * validation to the selection change listeners too.
			 */
			@Override
			public void selectionChanged(final SelectionChangedEvent event) {
				final ITextSelection selection= (ITextSelection) event.getSelection();
				if (SourceEditorViewer.this.lastSentSelectionOffset != selection.getOffset()
						|| SourceEditorViewer.this.lastSentSelectionLength != selection.getLength()) {
					final Point currentSelection= getSelectedRange();
					if (currentSelection.x == selection.getOffset() && currentSelection.y == selection.getLength()) {
						fireSelectionChanged(currentSelection.x, currentSelection.y);
					}
				}
			}
		});
	}
	
	
	@Override
	protected void fireSelectionChanged(final SelectionChangedEvent event) {
		final ITextSelection selection= (ITextSelection) event.getSelection();
		this.lastSentSelectionOffset= selection.getOffset();
		this.lastSentSelectionLength= selection.getLength();
		
		super.fireSelectionChanged(event);
	}
	
	
	private IInformationPresenter getPresenter(final int operation) {
		switch (operation) {
		case SHOW_SOURCE_OUTLINE:
			return this.sourceOutlinePresenter;
		case SHOW_ELEMENT_OUTLINE:
			return this.elementOutlinePresenter;
		case SHOW_ELEMENT_HIERARCHY:
			return this.elementHierarchyPresenter;
		default:
			return null;
		}
	}
	
	private void setPresenter(final int operation, final IInformationPresenter presenter) {
		switch (operation) {
		case SHOW_SOURCE_OUTLINE:
			this.sourceOutlinePresenter= presenter;
			return;
		case SHOW_ELEMENT_OUTLINE:
			this.elementOutlinePresenter= presenter;
			return;
		case SHOW_ELEMENT_HIERARCHY:
			this.elementHierarchyPresenter= presenter;
			return;
		default:
			if (presenter != null) {
				presenter.uninstall();
			}
			return;
		}
	}
	
	@Override
	public boolean canDoOperation(final int operation) {
		switch (operation) {
		case SHOW_SOURCE_OUTLINE:
		case SHOW_ELEMENT_OUTLINE:
		case SHOW_ELEMENT_HIERARCHY:
			return (getPresenter(operation) != null);
		default:
			return super.canDoOperation(operation);
		}
	}
	
	@Override
	public void doOperation(final int operation) {
		switch (operation) {
		case SHOW_SOURCE_OUTLINE:
		case SHOW_ELEMENT_OUTLINE:
		case SHOW_ELEMENT_HIERARCHY: {
			final IInformationPresenter presenter= getPresenter(operation);
			if (presenter != null) {
				presenter.showInformation();
			}
			return; }
		default:
			super.doOperation(operation);
			return;
		}
	}
	
	@Override
	public void configure(final SourceViewerConfiguration configuration) {
		super.configure(configuration);
		
		if (configuration instanceof SourceEditorViewerConfiguration) {
			for (int operation= QUICK_PRESENTER_START; operation < QUICK_PRESENTER_END; operation++) {
				final IInformationPresenter presenter= ((SourceEditorViewerConfiguration) configuration).getQuickPresenter(this, operation);
				if (presenter != null) {
					presenter.install(this);
				}
				setPresenter(operation, presenter);
			}
		}
	}
	
	@Override
	public void unconfigure() {
		for (int operation= QUICK_PRESENTER_START; operation < QUICK_PRESENTER_END; operation++) {
			final IInformationPresenter presenter= getPresenter(operation);
			if (presenter != null) {
				presenter.uninstall();
				setPresenter(operation, null);
			}
		}
		
		super.unconfigure();
	}
	
	public String[] getDefaultPrefixes(final String contentType) {
		return (this.fDefaultPrefixChars != null) ?
				(String[]) this.fDefaultPrefixChars.get(contentType) :
				null;
	}
	
	
/*[ Workaround for E-Bug 480312 ]==============================================*/
	
	
	private final class ViewerState {
		
		/** The position tracking the selection. */
		private Position selection;
		
		/** The position tracking the visually stable line. */
		private Position stableLine;
		/** The pixel offset of the stable line measured from the client area. */
		private int stablePixel;
		
		/** The position updater for {@link #selection} and {@link #stableLine}. */
		private IPositionUpdater updater;
		/** The document that the position updater and the positions are registered with. */
		private IDocument updaterDocument;
		/** The position category used by {@link #updater}. */
		private String updaterCategory;
		
		private int topPixel;
		
		
		/**
		 * Creates a new viewer state instance and connects it to the current document.
		 */
		public ViewerState() {
			final IDocument document= getDocument();
			if (document != null) {
				connect(document);
			}
		}
		
		
		public void updateSelection(final int offset, final int length) {
			if (this.selection == null) {
				this.selection= new Position(offset, length);
				if (isConnected()) {
					try {
						this.updaterDocument.addPosition(this.updaterCategory, this.selection);
					}
					catch (final BadLocationException | BadPositionCategoryException e) {}
				}
			}
			else {
				updatePosition(this.selection, offset, length);
			}
		}
		
		/**
		 * Updates the viewport, trying to keep the
		 * {@linkplain StyledText#getLinePixel(int) line pixel} of the caret line stable. If the
		 * selection has been updated while in redraw(false) mode, the new selection is revealed.
		 */
		private void updateViewport() {
			final StyledText textWidget= getTextWidget();
			if (this.selection != null) {
				textWidget.setTopPixel(this.topPixel);
				revealRange(this.selection.getOffset(), this.selection.getLength());
			}
			else if (this.stableLine != null) {
				int stableLine;
				try {
					stableLine= this.updaterDocument.getLineOfOffset(this.stableLine.getOffset());
				}
				catch (final BadLocationException x) {
					// ignore and return silently
					textWidget.setTopPixel(this.topPixel);
					return;
				}
				final int stableWidgetLine= getClosestWidgetLineForModelLine(stableLine);
				if (stableWidgetLine == -1) {
					textWidget.setTopPixel(this.topPixel);
					return;
				}
				final int linePixel= textWidget.getLinePixel(stableWidgetLine);
				final int delta= this.stablePixel - linePixel;
				final int topPixel= textWidget.getTopPixel();
				textWidget.setTopPixel(topPixel - delta);
			}
		}
		
		/**
		 * Remembers the viewer state.
		 *
		 * @param document the document to remember the state of
		 */
		private void connect(final IDocument document) {
			Assert.isLegal(document != null);
			Assert.isLegal(!isConnected());
			this.updaterDocument= document;
			try {
				final StyledText textWidget= getTextWidget();
				this.updaterCategory= "ViewerState-" + hashCode();
				this.updater= new NonDeletingPositionUpdater(this.updaterCategory);
				this.updaterDocument.addPositionCategory(this.updaterCategory);
				this.updaterDocument.addPositionUpdater(this.updater);
				
				final int stableLine= getStableLine();
				final int stableWidgetLine= modelLine2WidgetLine(stableLine);
				this.stablePixel= textWidget.getLinePixel(stableWidgetLine);
				final IRegion stableLineInfo= this.updaterDocument.getLineInformation(stableLine);
				this.stableLine= new Position(stableLineInfo.getOffset(), stableLineInfo.getLength());
				this.updaterDocument.addPosition(this.updaterCategory, this.stableLine);
				
				this.topPixel= textWidget.getTopPixel();
			}
			catch (final BadPositionCategoryException e) {
				// cannot happen
				Assert.isTrue(false);
			}
			catch (final BadLocationException e) {
				// should not happen except on concurrent modification
				// ignore and disconnect
				disconnect();
			}
		}
		
		private void updatePosition(final Position position, final int offset, final int length) {
			position.setOffset(offset);
			position.setLength(length);
			// http://bugs.eclipse.org/bugs/show_bug.cgi?id=32795
			position.isDeleted= false;
		}
		
		/**
		 * Returns the document line to keep visually stable. If the caret line is (partially)
		 * visible, it is returned, otherwise the topmost (partially) visible line is returned.
		 *
		 * @return the visually stable line of this viewer state
		 */
		private int getStableLine() {
			int stableLine; // the model line that we try to keep stable
			final int caretLine= getTextWidget().getLineAtOffset(getTextWidget().getCaretOffset());
			if (caretLine < JFaceTextUtil.getPartialTopIndex(getTextWidget()) || caretLine > JFaceTextUtil.getPartialBottomIndex(getTextWidget())) {
				stableLine= JFaceTextUtil.getPartialTopIndex(SourceEditorViewer.this);
			}
			else {
				stableLine= widgetLine2ModelLine(caretLine);
			}
			return stableLine;
		}
		
		/**
		 * Returns <code>true</code> if the viewer state is being tracked, <code>false</code>
		 * otherwise.
		 *
		 * @return the tracking state
		 */
		private boolean isConnected() {
			return (this.updater != null);
		}
		
		/**
		 * Disconnects from the document.
		 */
		private void disconnect() {
			if (isConnected()) {
				try {
					this.updaterDocument.removePosition(this.updaterCategory, this.stableLine);
					this.updaterDocument.removePositionUpdater(this.updater);
					this.updater= null;
					this.updaterDocument.removePositionCategory(this.updaterCategory);
					this.updaterCategory= null;
				}
				catch (final BadPositionCategoryException x) {
					// cannot happen
					Assert.isTrue(false);
				}
			}
		}
	}
	
	
	private ViewerState viewerState;
	
	
	@Override
	protected void disableRedrawing() {
		if ((this.flags & VARIABLE_LINE_HEIGHT) != 0) {
			this.viewerState= new ViewerState();
		}
		
		super.disableRedrawing();
	}
	
	@Override
	protected void enabledRedrawing(final int topIndex) {
		super.enabledRedrawing(topIndex);
		
		if (this.viewerState != null) {
			this.viewerState.disconnect();
			if (topIndex == -1) {
				this.viewerState.updateViewport();
			}
			this.viewerState= null;
		}
	}
	
	@Override
	public void setSelectedRange(final int selectionOffset, final int selectionLength) {
		if (this.viewerState != null && !redraws()) {
			this.viewerState.updateSelection(selectionOffset, selectionLength);
			return;
		}
		
		super.setSelectedRange(selectionOffset, selectionLength);
	}
	
}
