/*=============================================================================#
 # Copyright (c) 2009, 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.internal.ltk.ui.refactoring;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.text.edits.CopyTargetEdit;
import org.eclipse.text.edits.DeleteEdit;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MoveSourceEdit;
import org.eclipse.text.edits.MoveTargetEdit;
import org.eclipse.text.edits.RangeMarker;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.text.edits.TextEditVisitor;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;


/**
 * Class to annotate edits made by a quick fix/assist to be shown via the quick fix pop-up preview.
 * E.g. the added changes are shown in bold.
 */
@NonNullByDefault
public class TextEditAnnotator extends TextEditVisitor {
	
	
	private int writtenToOffset= 0;
	private int chunks;
	
	private final StringBuilder sb;
	
	private final IDocument previewDocument;
	
	
	public TextEditAnnotator(final StringBuilder sb, final IDocument previewDoc) {
		this.sb= sb;
		this.previewDocument= previewDoc;
	}
	
	
	public void unchangedUntil(final int offset) {
		if (offset > this.writtenToOffset) {
			appendContent(this.previewDocument, this.writtenToOffset, offset, true);
			this.writtenToOffset= offset;
		}
	}
	
	
	@Override
	public boolean visit(final MoveTargetEdit edit) {
		return true; //rangeAdded(edit);
	}
	
	@Override
	public boolean visit(final CopyTargetEdit edit) {
		return true; //return rangeAdded(edit);
	}
	
	@Override
	public boolean visit(final InsertEdit edit) {
		return rangeAdded(edit);
	}
	
	@Override
	public boolean visit(final ReplaceEdit edit) {
		if (edit.getLength() > 0) {
			return rangeAdded(edit);
		}
		return rangeRemoved(edit);
	}
	
	@Override
	public boolean visit(final MoveSourceEdit edit) {
		return rangeRemoved(edit);
	}
	
	@Override
	public boolean visit(final DeleteEdit edit) {
		return rangeRemoved(edit);
	}
	
	@Override
	public boolean visit(final RangeMarker edit) {
		unchangedUntil(edit.getOffset());
		return true;
	}
	
	
	protected boolean rangeRemoved(final TextEdit edit) {
		unchangedUntil(edit.getOffset());
		return false;
	}
	
	protected boolean rangeAdded(final TextEdit edit) {
		return annotateEdit(edit, "<b>", "</b>"); //$NON-NLS-1$ //$NON-NLS-2$
	}
	
	protected boolean annotateEdit(final TextEdit edit, final String startTag, final String endTag) {
		unchangedUntil(edit.getOffset());
		this.sb.append(startTag);
		appendContent(this.previewDocument, edit.getOffset(), edit.getExclusiveEnd(), false);
		this.sb.append(endTag);
		this.writtenToOffset= edit.getExclusiveEnd();
		return false;
	}
	
	private void appendContent(final IDocument text, final int startOffset, final int endOffset,
			final boolean surroundLinesOnly) {
		final int surroundLines= 1;
		try {
			final boolean firstChunk= (this.chunks++ == 0);
			int startLine= text.getLineOfOffset(
					(surroundLinesOnly && firstChunk) ? endOffset : startOffset );
			final int endLine= text.getLineOfOffset(endOffset);
			
			boolean dotsAdded= false;
			if (surroundLinesOnly && startOffset == 0) { // no surround lines for the top no-change range
				startLine= endLine;
				dotsAdded= true;
			}
			
			for (int i= startLine; i <= endLine; i++) {
				if (surroundLinesOnly) {
					if ((i - startLine > surroundLines) && (endLine - i > surroundLines)) {
						if (!dotsAdded) {
							this.sb.append("...<br/>"); //$NON-NLS-1$
							dotsAdded= true;
						}
						else if (endOffset == text.getLength()) {
							return; // no surround lines for the bottom no-change range
						}
						continue;
					}
				}
				
				final IRegion lineInfo= text.getLineInformation(i);
				final int start= lineInfo.getOffset();
				final int end= start + lineInfo.getLength();
				
				final int from= Math.max(start, startOffset);
				final int to= Math.min(end, endOffset);
				final String content= text.get(from, to - from);
				if (surroundLinesOnly && (from == start) && content.isEmpty()) {
					continue; // ignore empty lines except when range started in the middle of a line
				}
				for (int k= 0; k < content.length(); k++) {
					final char ch= content.charAt(k);
					switch (ch) {
					case '<':
						this.sb.append("&lt;"); //$NON-NLS-1$
						break;
					case '>':
						this.sb.append("&gt;"); //$NON-NLS-1$
						break;
					default:
						this.sb.append(ch);
						break;
					}
				}
				if (to == end && to != endOffset) { // new line when at the end of the line, and not end of range
					this.sb.append("<br/>"); //$NON-NLS-1$
				}
			}
		}
		catch (final BadLocationException e) {}
	}
	
}
