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

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPartitioningException;
import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
import org.eclipse.jface.text.DocumentCommand;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.ui.texteditor.ITextEditorExtension3;

import org.eclipse.statet.jcommons.text.core.BasicTextRegion;
import org.eclipse.statet.jcommons.text.core.TextRegion;

import org.eclipse.statet.ecommons.text.BasicHeuristicTokenScanner;
import org.eclipse.statet.ecommons.text.IIndentSettings;
import org.eclipse.statet.ecommons.text.ITokenScanner;
import org.eclipse.statet.ecommons.text.IndentUtil;
import org.eclipse.statet.ecommons.text.core.sections.DocContentSections;
import org.eclipse.statet.ecommons.text.core.treepartitioner.TreePartition;
import org.eclipse.statet.ecommons.ui.util.UIAccess;

import org.eclipse.statet.internal.ltk.ui.LTKUIPlugin;
import org.eclipse.statet.ltk.core.SourceContent;


/**
 * Auto edit strategy for Wikitext markup
 */
public abstract class AbstractAutoEditStrategy extends DefaultIndentLineAutoEditStrategy
		implements SourceEditorAddon, VerifyKeyListener {
	
	
	private final SourceEditor editor;
	private final ITextEditorExtension3 editor3;
	private final DocContentSections documentContentInfo;
	private final SourceViewer viewer;
	
	private AbstractDocument document;
	private TextRegion validRange;
	
	private boolean ignoreCommands= false;
	
	
	public AbstractAutoEditStrategy(final SourceEditor editor) {
		assert (editor != null);
		
		this.editor= editor;
		this.documentContentInfo= this.editor.getDocumentContentInfo();
		
		this.viewer= this.editor.getViewer();
		this.editor3= (editor instanceof SourceEditor1) ? (SourceEditor1) editor : null;
	}
	
	
	public final SourceEditor getEditor() {
		return this.editor;
	}
	
	protected final ITextEditorExtension3 getEditor3() {
		return this.editor3;
	}
	
	public final DocContentSections getDocumentContentInfo() {
		return this.documentContentInfo;
	}
	
	protected final SourceViewer getViewer() {
		return this.viewer;
	}
	
	protected abstract SmartInsertSettings getSettings();
	
	protected abstract IIndentSettings getCodeStyleSettings();
	
	
	@Override
	public void install(final SourceEditor editor) {
		assert (editor.getViewer() == this.viewer);
		this.viewer.prependVerifyKeyListener(this);
	}
	
	@Override
	public void uninstall() {
		this.viewer.removeVerifyKeyListener(this);
	}
	
	
	protected TreePartition initCustomization(final int offset, final int ch)
			throws BadLocationException, BadPartitioningException {
		assert(this.document != null);
		
		final TreePartition partition= (TreePartition) this.document.getPartition(
				this.documentContentInfo.getPartitioning(), offset, true );
		this.validRange= computeValidRange(offset, partition, ch);
		return (this.validRange != null) ? partition : null;
	}
	
	protected TextRegion computeValidRange(final int offset, final TreePartition partition, final int c) {
		return new BasicTextRegion(0, this.document.getLength());
	}
	
	protected final AbstractDocument getDocument() {
		return this.document;
	}
	
	protected final TextRegion getValidRange() {
		return this.validRange;
	}
	
	protected abstract BasicHeuristicTokenScanner getScanner();
	
	protected IndentUtil createIndentUtil(final AbstractDocument doc) {
		return new IndentUtil(doc, getCodeStyleSettings());
	}
	
	protected void quitCustomization() {
		this.document= null;
	}
	
	
	private final boolean isSmartInsertEnabled() {
		return ((this.editor3 != null) ?
				(this.editor3.getInsertMode() == ITextEditorExtension3.SMART_INSERT) :
				getSettings().isSmartInsertEnabledByDefault());
	}
	
	private final boolean isBlockSelection() {
		final StyledText textWidget= this.viewer.getTextWidget();
		return (textWidget.getBlockSelection() && textWidget.getSelectionRanges().length > 2);
	}
	
	
	/**
	 * Second main entry method for real single key presses.
	 */
	@Override
	public final void verifyKey(final VerifyEvent event) {
		final char ch;
		if (!event.doit || (ch= isCustomizeKey(event)) == 0
				|| !isSmartInsertEnabled()
				|| !UIAccess.isOkToUse(this.viewer) || isBlockSelection() ) {
			return;
		}
		try {
			this.document= (AbstractDocument) this.viewer.getDocument();
			final ITextSelection selection= (ITextSelection) this.viewer.getSelection();
			final TreePartition partition= initCustomization(selection.getOffset(), ch);
			if (partition == null) {
				return;
			}
			this.ignoreCommands= true;
			
			final DocumentCommand command= new DocumentCommand() {};
			command.offset= selection.getOffset();
			command.length= selection.getLength();
			command.doit= true;
			command.shiftsCaret= true;
			command.caretOffset= -1;
			
			doCustomizeKeyCommand(ch, command, partition);
			event.doit= command.doit;
		}
		catch (final Exception e) {
			StatusManager.getManager().handle(new Status(IStatus.ERROR, LTKUIPlugin.BUNDLE_ID, -1,
					"An error occurred when customizing action for pressed key in auto edit strategy.", //$NON-NLS-1$
					e ));
		}
		finally {
			this.ignoreCommands= false;
			quitCustomization();
		}
	}
	
	@Override
	public final void customizeDocumentCommand(final IDocument d, final DocumentCommand command) {
		if (this.ignoreCommands || command.doit == false || command.text == null) {
			return;
		}
		if (!isSmartInsertEnabled() || isBlockSelection()) {
			super.customizeDocumentCommand(d, command);
			return;
		}
		
		try {
			this.document= (AbstractDocument) d;
			final TreePartition partition= initCustomization(command.offset, -1);
			if (partition == null) {
				return;
			}
			
			doCustomizeOtherCommand(command, partition);
		}
		catch (final Exception e) {
			StatusManager.getManager().handle(new Status(IStatus.ERROR, LTKUIPlugin.BUNDLE_ID, -1,
					"An error occurred when customizing action for document command in auto edit strategy.", e )); //$NON-NLS-1$
		}
		finally {
			if (!command.doit) {
				command.text= null;
				command.length= 0;
			}
			
			quitCustomization();
		}
	}
	
	
	
	protected abstract char isCustomizeKey(KeyEvent event);
	
	protected abstract void doCustomizeKeyCommand(char ch, DocumentCommand command,
			TreePartition partition) throws Exception;
	
	protected abstract void doCustomizeOtherCommand(DocumentCommand command,
			TreePartition partition) throws Exception;
	
	
	
	protected final int getChar(final int offset) throws BadLocationException {
		final TextRegion validRange= getValidRange();
		return (offset >= validRange.getStartOffset() && offset < validRange.getEndOffset()) ?
				getDocument().getChar(offset) : -1;
	}
	
	protected final boolean isRegularTabCommand(final DocumentCommand command) throws BadLocationException {
		return (command.length == 0 
				|| this.document.getLineOfOffset(command.offset) == this.document.getLineOfOffset(command.offset + command.length) );
	}
	
	protected final void customizeCommandDefault(final DocumentCommand command) {
		super.customizeDocumentCommand(getDocument(), command);
	}
	
	protected final void applyCommand(final DocumentCommand command) throws BadLocationException {
		this.document.replace(command.offset, command.length, command.text);
		command.doit= false;
	}
	
	protected final void updateSelection(final DocumentCommand command) {
		if (command.caretOffset == -1) {
			command.caretOffset= command.offset + command.text.length();
		}
		final TextSelection textSelection= new TextSelection(this.document, command.caretOffset, 0);
		this.viewer.setSelection(textSelection, true);
		command.shiftsCaret= false;
	}
	
	
	protected final boolean endsWithNewLine(final String text) {
		for (int idx= text.length() - 1; idx >= 0; idx--) {
			final char c= text.charAt(idx);
			switch (c) {
			case '\n':
				return true;
			case ' ':
			case '\t':
				continue;
			default:
				break;
			}
		}
		return false;
	}
	
	protected final int indexOfNewLine(final String text) {
		for (int idx= 0; idx < text.length(); idx++) {
			final char c= text.charAt(idx);
			switch (c) {
			case '\r':
				if (idx + 1 < text.length() && text.charAt(idx + 1) == '\n') {
					return idx;
				}
				continue;
			case '\n':
				return idx;
			default:
				continue;
			}
		}
		return -1;
	}
	
	protected final boolean containsControl(final String text) {
		for (int idx= 0; idx < text.length(); idx++) {
			if (text.charAt(idx) < 0x20) {
				return true;
			}
		}
		return false;
	}
	
	protected final SourceContent createSourceContent(final AbstractDocument document,
			final TextRegion region, final DocumentCommand command) throws BadLocationException {
		final StringBuilder sb= new StringBuilder(region.getLength() - command.length + command.text.length());
		sb.append(document.get(region.getStartOffset(), command.offset - region.getStartOffset()));
		sb.append(command.text);
		sb.append(document.get(command.offset + command.length, region.getEndOffset() - (command.offset + command.length)));
		return new SourceContent(region.getStartOffset(), sb.toString());
	}
	
	
	protected void smartInsertOnTab(final DocumentCommand command, boolean indent)
			throws Exception {
		final AbstractDocument doc= getDocument();
		final IndentUtil indentUtil= createIndentUtil(doc);
		final int lineNum= doc.getLineOfOffset(command.offset);
		final int column= indentUtil.getColumn(lineNum, command.offset);
		
		if (indent) {
			final BasicHeuristicTokenScanner scanner= getScanner();
			scanner.configure(doc);
			if (scanner.findAnyNonBlankBackward(command.offset, doc.getLineOffset(lineNum) - 1, false) != ITokenScanner.NOT_FOUND) {
				indent= false;
			}
		}
		if (!indent) {
			if (getCodeStyleSettings().getReplaceOtherTabsWithSpaces()) {
				command.text= indentUtil.createTabSpacesCompletionString(column);
			}
			return;
		}
		
		switch (getSettings().getSmartInsertTabAction()) {
		case INSERT_TAB_CHAR:
			return;
		case INSERT_TAB_LEVEL:
			command.text= indentUtil.createTabCompletionString(column);
			return;
		case INSERT_INDENT_LEVEL:
			command.text= indentUtil.createIndentCompletionString(column);
			return;
		case CORRECT_INDENT:
			command.text= indentUtil.createIndentCompletionString(column);
			correctIndent(command, column + 1, indentUtil);
			return;
		default:
			throw new UnsupportedOperationException();
		}
	}
	
	protected void correctIndent(final DocumentCommand command, final int minColumn,
			final IndentUtil indentUtil) throws Exception {
		throw new UnsupportedOperationException();
	}
	
}
