/*******************************************************************************
 * Copyright (c) 2000, 2015 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.ui.internal.texteditor.quickdiff;

import java.util.List;
import java.util.ListIterator;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.ILineDiffInfo;

import org.eclipse.ui.internal.texteditor.NLSUtility;

import org.eclipse.compare.rangedifferencer.RangeDifference;


/**
 * The local implementation of <code>ILineDiffInfo</code>. As instances are
 * also <code>Annotation</code>s, they can be used in
 * <code>DocumentLineDiffer</code>s <code>IAnnotationModel</code> protocol.
 *
 * @since 3.0
 */
public final class DiffRegion extends Annotation implements ILineDiffInfo {
	private final QuickDiffRangeDifference fDifference;

	private final int fOffset;

	private final List<QuickDiffRangeDifference> fList;

	private final IDocument fDocument;

	/**
	 * Creates a new diff region.
	 *
	 * @param difference the range difference
	 * @param offset the offset
	 * @param differences the list of differences
	 * @param source the document
	 */
	public DiffRegion(QuickDiffRangeDifference difference, int offset, List<QuickDiffRangeDifference> differences, IDocument source) {
		super("org.eclipse.ui.workbench.texteditor.quickdiffChange", false, null); //$NON-NLS-1$
		fOffset= offset;
		fDifference= difference;
		fList= differences;
		fDocument= source;
	}

	@Override
	public String getType() {
		// we return unknown for unchanged regions to avoid
		// them getting displayed.
		switch (getChangeType()) {
			case CHANGED:
				int r= fDifference.rightLength();
				int l= fDifference.leftLength();
				int c= Math.min(r, l);
				if (c == 0 && r - l < 0)
					return "org.eclipse.ui.workbench.texteditor.quickdiffDeletion"; //$NON-NLS-1$
				else
					return "org.eclipse.ui.workbench.texteditor.quickdiffChange"; //$NON-NLS-1$
			case ADDED:
				return "org.eclipse.ui.workbench.texteditor.quickdiffAddition"; //$NON-NLS-1$
			case UNCHANGED:
				return "org.eclipse.ui.workbench.texteditor.quickdiffUnchanged"; //$NON-NLS-1$
			default:
				return TYPE_UNKNOWN;
		}
	}

	@Override
	public int getRemovedLinesBelow() {
		if (fOffset == fDifference.rightLength() - 1) {

			if (getChangeType() != UNCHANGED)
				return Math.max(fDifference.leftLength() - fDifference.rightLength(), 0);

			synchronized (fList) {
				for (ListIterator<QuickDiffRangeDifference> it= fList.listIterator(); it.hasNext();) {
					if (fDifference.equals(it.next())) {
						if (it.hasNext()) {
							QuickDiffRangeDifference next= it.next();
							if (next.rightLength() == 0)
								return Math.max(next.leftLength() - next.rightLength(), 0);
						}
						break;
					}
				}
			}
		}
		return 0;
	}

	@Override
	public int getChangeType() {
		if (fDifference.kind() == RangeDifference.NOCHANGE)
			return UNCHANGED;
		if (fOffset >= fDifference.leftLength())
			return ADDED;
		return CHANGED;
	}

	@Override
	public int getRemovedLinesAbove() {
		if (getChangeType() == UNCHANGED && fOffset == 0) {
			synchronized (fList) {
				for (ListIterator<QuickDiffRangeDifference> it= fList.listIterator(fList.size()); it.hasPrevious();) {
					if (fDifference.equals(it.previous())) {
						if (it.hasPrevious()) {
							QuickDiffRangeDifference previous= it.previous();
							return Math.max(previous.leftLength() - previous.rightLength(), 0);
						}
						break;
					}
				}
			}
		}
		return 0;
	}

	@Override
	public boolean hasChanges() {
		return getChangeType() != UNCHANGED || getRemovedLinesAbove() > 0 || getRemovedLinesBelow() > 0;
	}

	@Override
	public String[] getOriginalText() {
		IDocument doc= fDocument;
		if (doc != null) {
			int startLine= fDifference.leftStart() + fOffset;
			if (startLine >= fDifference.leftEnd())
				return new String[0]; // original text of an added line is
									  // empty

			int endLine= startLine + getRemovedLinesBelow();
			if (getChangeType() == UNCHANGED)
				startLine++;
			String[] ret= new String[endLine - startLine + 1];
			for (int i= 0; i < ret.length; i++) {
				try {
					ret[i]= doc.get(doc.getLineOffset(startLine + i), doc.getLineLength(startLine + i));
				} catch (BadLocationException e) {
					ret[i]= ""; //$NON-NLS-1$
				}
			}
			return ret;
		}

		// in initialization phase?
		return new String[0];
	}

	@Override
	public String getText() {
		int r= fDifference.rightLength();
		int l= fDifference.leftLength();
		int c= Math.min(r, l);
		int a= r - l;
		String changed= c > 0 ? NLSUtility.format(QuickDiffMessages.quickdiff_annotation_changed, new Integer(c)) : null;
		String added;
		if (a > 0)
			added= NLSUtility.format(QuickDiffMessages.quickdiff_annotation_added, new Integer(a));
		else if (a < 0)
			added= NLSUtility.format(QuickDiffMessages.quickdiff_annotation_deleted, new Integer(-a));
		else
			added= null;
		String line= c > 1 || c == 0 && Math.abs(a) > 1 ? QuickDiffMessages.quickdiff_annotation_line_plural : QuickDiffMessages.quickdiff_annotation_line_singular;

		String ret= (changed != null ? changed : "") + (changed != null ? " " + line : "")   //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
				+ (changed != null && added != null ? ", " : " ") + (added != null ? added : "")  //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
				+ (added != null && changed == null ? " " + line : ""); //$NON-NLS-1$//$NON-NLS-2$
		return ret;
	}

	/**
	 * @return Returns the difference.
	 */
	public QuickDiffRangeDifference getDifference() {
		return fDifference;
	}

	/**
	 * @return Returns the offset.
	 */
	public int getOffset() {
		return fOffset;
	}
}
