/*=============================================================================#
 # 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.actions;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.link.LinkedModeModel;
import org.eclipse.jface.text.link.LinkedPosition;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ST;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Event;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.texteditor.AbstractTextEditor;

import org.eclipse.statet.ecommons.text.DocumentCodepointIterator;
import org.eclipse.statet.ecommons.text.ICodepointIterator;
import org.eclipse.statet.ecommons.text.TextUtil;
import org.eclipse.statet.ecommons.ui.util.DNDUtils;

import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditor;


public abstract class SourceEditorTextHandler extends AbstractHandler {
	// TODO Add CamelCase support
	
	
	private static int W_INIT= -1;
	private static int W_WORD= 0;
	private static int W_SEP= 1;
	private static int W_WS= 2;
	
	
	protected static class ExecData {
		
		private final ISourceEditor editor;
		private final SourceViewer viewer;
		private final StyledText widget;
		
		private final AbstractDocument document;
		
		private final int caretWidgetOffset;
		private final int caretDocOffset;
		
		private int caretDocLine= Integer.MIN_VALUE;
		private IRegion caretDocLineInfo;
		
		private LinkedModeModel linkedModel;
		
		
		public ExecData(final ISourceEditor editor) throws BadLocationException {
			this.editor= editor;
			this.viewer= editor.getViewer();
			this.widget= getViewer().getTextWidget();
			this.document= (AbstractDocument) getViewer().getDocument();
			this.caretWidgetOffset= getWidget().getCaretOffset();
			this.caretDocOffset= getViewer().widgetOffset2ModelOffset(getCaretWidgetOffset());
			if (this.caretDocOffset < 0) {
				throw new BadLocationException();
			}
		}
		
		
		public boolean isSmartHomeBeginEndEnabled() {
			final IPreferenceStore store= EditorsUI.getPreferenceStore();
			return (store != null
					&& store.getBoolean(AbstractTextEditor.PREFERENCE_NAVIGATION_SMART_HOME_END) );
		}
		
		public ISourceEditor getEditor() {
			return this.editor;
		}
		
		public SourceViewer getViewer() {
			return this.viewer;
		}
		
		public StyledText getWidget() {
			return this.widget;
		}
		
		
		public AbstractDocument getDocument() {
			return this.document;
		}
		
		public int toWidgetOffset(final int docOffset) {
			return this.viewer.modelOffset2WidgetOffset(docOffset);
		}
		
		public int toDocOffset(final int widgetOffset) {
			return this.viewer.widgetOffset2ModelOffset(widgetOffset);
		}
		
		public int getCaretWidgetOffset() {
			return this.caretWidgetOffset;
		}
		
		public int getCaretDocOffset() {
			return this.caretDocOffset;
		}
		
		public int getCaretDocLine() throws BadLocationException {
			if (this.caretDocLine == Integer.MIN_VALUE) {
				this.caretDocLine= getDocument().getLineOfOffset(getCaretDocOffset());
			}
			return this.caretDocLine;
		}
		
		public IRegion getCaretDocLineInformation() throws BadLocationException {
			if (this.caretDocLineInfo == null) {
				this.caretDocLineInfo= getDocument().getLineInformation(getCaretDocLine());
			}
			return this.caretDocLineInfo;
		}
		
		public int getCaretDocLineStartOffset() throws BadLocationException {
			return getCaretDocLineInformation().getOffset();
		}
		
		public int getCaretDocLineEndOffset() throws BadLocationException {
			final IRegion region= getCaretDocLineInformation();
			return region.getOffset() + region.getLength();
		}
		
		public int getCaretColumn() throws BadLocationException {
			return getCaretDocOffset() - getCaretDocLineStartOffset();
		}
		
		public LinkedModeModel getLinkedModel() {
			if (this.linkedModel == null) {
				this.linkedModel= LinkedModeModel.getModel(getDocument(), getCaretDocOffset());
			}
			return this.linkedModel;
		}
		
	}
	
	
	private final ISourceEditor editor;
	
	
	public SourceEditorTextHandler(final ISourceEditor editor) {
		this.editor= editor;
	}
	
	
	private ISourceEditor getEditor(final Object context) {
		return this.editor;
	}
	
	protected int getTextActionId() {
		return 0;
	}
	
	protected boolean isEditAction() {
		switch (getTextActionId()) {
		case ST.DELETE_PREVIOUS:
		case ST.DELETE_NEXT:
		case ST.DELETE_WORD_PREVIOUS:
		case ST.DELETE_WORD_NEXT:
			return true;
		default:
			return false;
		}
	}
	
	@Override
	public void setEnabled(final Object evaluationContext) {
		final ISourceEditor editor= getEditor(evaluationContext);
		setBaseEnabled(editor != null
				&& (!isEditAction() || editor.isEditable(false)) );
	}
	
	@Override
	public Object execute(final ExecutionEvent event) throws ExecutionException {
		final ISourceEditor editor= getEditor(event.getApplicationContext());
		if (editor == null) {
			return null;
		}
		if (isEditAction() && !editor.isEditable(true)) {
			return null;
		}
		try {
			final ExecData data= new ExecData(editor);
			final Point oldSelection= data.getWidget().getSelection();
			
			try {
				exec(data);
			}
			finally {
				data.getWidget().showSelection();
				final Point newSelection= data.getWidget().getSelection();
				if (!newSelection.equals(oldSelection)) {
					fireSelectionChanged(data, newSelection);
				}
			}
		}
		catch (final BadLocationException e) {
			throw new ExecutionException("An error occurred when executing the text viewer command.", e);
		}
		return null;
	}
	
	private void fireSelectionChanged(final ExecData data, final Point newSelection) {
		final Event event= new Event();
		event.x= newSelection.x;
		event.y= newSelection.y;
		data.getWidget().notifyListeners(SWT.Selection, event);
	}
	
	protected void exec(final ExecData data) throws BadLocationException {
		final int textActionId= getTextActionId();
		if (textActionId != 0) {
			data.getWidget().invokeAction(textActionId);
		}
	}
	
	protected int findPreviousWordOffset(final ExecData data, final int offset,
			final boolean sameLine) throws BadLocationException {
		int bound= 0;
		if (data.getLinkedModel() != null) {
			final LinkedPosition linkedPosition= data.getLinkedModel().findPosition(
					new LinkedPosition(data.getDocument(), offset, 0) );
			if (linkedPosition != null) {
				final int begin= linkedPosition.getOffset();
				if (begin < offset) {
					bound= begin;
				}
			}
		}
		
		int previousOffset= offset;
		if (offset == data.getCaretDocLineStartOffset()) {
			if (!sameLine && data.getCaretDocLine() > 0) {
				final IRegion nextLine= data.getDocument().getLineInformation(data.getCaretDocLine()-1);
				previousOffset= nextLine.getOffset() + nextLine.getLength();
			}
			else {
				previousOffset= offset;
			}
		}
		else {
			if (bound < data.getCaretDocLineStartOffset()) {
				bound= data.getCaretDocLineStartOffset();
			}
			if (offset <= bound) {
				return offset;
			}
			final ICodepointIterator iterator= DocumentCodepointIterator.create(data.getDocument(),
					bound, offset );
			iterator.setIndex(offset, ICodepointIterator.PREPARE_BACKWARD);
			int mode= W_INIT;
			int cp= iterator.previous();
			while (cp != -1) {
				final int newMode= getMode(cp);
				if (mode != W_INIT && mode != W_WS && newMode != mode) {
					break;
				}
				
				mode= newMode;
				previousOffset= iterator.getCurrentIndex();
				cp= iterator.previous();
			}
		}
		if (previousOffset < bound) {
			previousOffset= bound;
		}
		return previousOffset;
	}
	
	
	
	protected int findNextWordOffset(final ExecData data, final int offset,
			final boolean sameLine) throws BadLocationException {
		int bound= data.getDocument().getLength();
		if (data.getLinkedModel() != null) {
			final LinkedPosition linkedPosition= data.getLinkedModel().findPosition(
					new LinkedPosition(data.getDocument(), offset, 0) );
			if (linkedPosition != null) {
				final int end= linkedPosition.getOffset() + linkedPosition.getLength();
				if (end > offset) {
					bound= end;
				}
			}
		}
		
		int nextOffset= offset;
		if (data.getCaretDocLineEndOffset() <= offset) {
			if (!sameLine) {
				nextOffset= data.getCaretDocLineStartOffset() + data.getDocument().getLineLength(data.getCaretDocLine());
			}
			else {
				nextOffset= offset;
			}
		}
		else {
			if (bound > data.getCaretDocLineEndOffset()) {
				bound= data.getCaretDocLineEndOffset();
			}
			
			final ICodepointIterator iterator= DocumentCodepointIterator.create(data.getDocument(),
					offset, bound );
			iterator.setIndex(offset, ICodepointIterator.PREPARE_FORWARD);
			int mode= W_INIT;
			int cp= iterator.current();
			while (cp != -1) {
				final int newMode= getMode(cp);
				if (mode != W_INIT && newMode != W_WS && newMode != mode) {
					break;
				}
				
				mode= newMode;
				nextOffset= iterator.getCurrentIndex() + iterator.getCurrentLength();
				cp= iterator.next();
			}
		}
		if (nextOffset > bound) {
			nextOffset= bound;
		}
		return nextOffset;
	}
	
	private int getMode(final int cp) {
		if (Character.isLetterOrDigit(cp)) {
			return W_WORD;
		}
		else if (cp == ' ' || cp == '\t') {
			return W_WS;
		}
		else {
			return W_SEP;
		}
	}
	
	public int getCaretSmartLineStartOffset(final ExecData data) throws BadLocationException {
		if (data.isSmartHomeBeginEndEnabled()) {
			final LinkedModeModel linkedModel= data.getLinkedModel();
			if (linkedModel != null) {
				final LinkedPosition position= linkedModel.findPosition(
						new LinkedPosition(data.getDocument(), data.getCaretDocOffset(), 0) );
				if (position != null) {
					if (data.getCaretDocOffset() > position.getOffset()) {
						return position.getOffset();
					}
				}
			}
		}
		return data.getCaretDocLineStartOffset();
	}
	
	public int getCaretSmartLineEndOffset(final ExecData data) throws BadLocationException {
		if (data.isSmartHomeBeginEndEnabled()) {
			final LinkedModeModel linkedModel= data.getLinkedModel();
			if (linkedModel != null) {
				final LinkedPosition position= linkedModel.findPosition(
						new LinkedPosition(data.getDocument(), data.getCaretDocOffset(), 0) );
				if (position != null) {
					if (data.getCaretDocOffset() < position.getOffset() + position.getLength()) {
						return position.getOffset() + position.getLength();
					}
				}
			}
		}
		return data.getCaretDocLineEndOffset();
	}
	
	protected IRegion getWholeLinesRegion(final ExecData data) throws BadLocationException {
		final Point selectedRange= data.getViewer().getSelectedRange();
		return TextUtil.getBlock(data.getDocument(), selectedRange.x, selectedRange.y);
	}
	
	protected IRegion getToLineBeginRegion(final ExecData data) throws BadLocationException {
		final int startOffset= getCaretSmartLineStartOffset(data);
		return new Region(startOffset, data.getCaretDocOffset() - startOffset);
	}
	
	protected IRegion getToLineEndRegion(final ExecData data) throws BadLocationException {
		final int endOffset= getCaretSmartLineEndOffset(data);
		return new Region(data.getCaretDocOffset(), endOffset - data.getCaretDocOffset());
	}
	
	protected void expandBlockSelection(final ExecData data, final int newWidgetOffset) {
		if (newWidgetOffset > data.getCaretWidgetOffset()) {
			while (data.getWidget().getCaretOffset() < newWidgetOffset) {
				data.getWidget().invokeAction(ST.SELECT_COLUMN_NEXT);
			}
		}
		else {
			while (data.getWidget().getCaretOffset() > newWidgetOffset) {
				data.getWidget().invokeAction(ST.SELECT_COLUMN_PREVIOUS);
			}
		}
	}
	
	protected void expandDocSelection(final ExecData data, final int newDocOffset) {
		int otherDocOffset;
		{	final Point widgetSelection= data.getWidget().getSelection();
			otherDocOffset= data.toDocOffset((data.getCaretWidgetOffset() == widgetSelection.x) ?
					widgetSelection.y : widgetSelection.x);
		}
		if (data.toWidgetOffset(newDocOffset) < 0 && data.getViewer() instanceof ProjectionViewer) {
			((ProjectionViewer) data.getViewer()).exposeModelRange(new Region(newDocOffset, 0));
		}
		selectAndReveal(data, otherDocOffset, newDocOffset - otherDocOffset);
	}
	
	protected void copyToClipboard(final ExecData data, final IRegion docRegion)
			throws BadLocationException {
		final String text= data.getDocument().get(docRegion.getOffset(), docRegion.getLength());
		final Clipboard clipboard= new Clipboard(data.getWidget().getDisplay());
		try {
			DNDUtils.setContent(clipboard,
					new String[] { text },
					new Transfer[] { TextTransfer.getInstance() } );
		}
		finally {
			clipboard.dispose();
		}
	}
	
	protected void delete(final ExecData data, final IRegion docRegion)
			throws BadLocationException {
		if (data.getViewer() instanceof ProjectionViewer) {
			((ProjectionViewer) data.getViewer()).exposeModelRange(docRegion);
		}
		data.getViewer().setSelectedRange(docRegion.getOffset(), 0);
		if (docRegion.getLength() > 0) {
			data.getDocument().replace(docRegion.getOffset(), docRegion.getLength(), ""); //$NON-NLS-1$
		}
		data.getViewer().revealRange(data.getViewer().getSelectedRange().x, 0);
	}
	
	protected void selectAndReveal(final ExecData data, final int docOffset, final int length) {
		data.getViewer().setSelectedRange(docOffset, length);
		data.getViewer().revealRange(docOffset, length);
	}
	
}
