/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
package org.eclipse.compare.rangedifferencer;

import org.eclipse.jface.*;
import org.eclipse.jface.util.Assert;

/**
 * Description of a change between two or three ranges of comparable entities.
 * <p>
 * <code>RangeDifference</code> objects are the elements of a compare result returned from
 * the <code>RangeDifferencer</code> <code>find* </code> methods.
 * Clients use these objects as they are returned from the differencer.
 * This class is not intended to be instantiated or subclassed.
 * <p>
 * Note: A range in the <code>RangeDifference</code> object is given as a start index
 * and length in terms of comparable entities. However, these entity indices and counts
 * are not necessarily character positions. For example, if an entity represents a line
 * in a document, the start index would be a line number and the count would be in lines.
 * </p>
 *
 * @see RangeDifferencer
 */
public class RangeDifference {

	/** Two-way change constant indicating no change. */
	public final static int NOCHANGE= 0;
	/** Two-way change constant indicating two-way change (same as <code>RIGHT</code>) */
	public final static int CHANGE= 2;

	/** Three-way change constant indicating a change in both right and left. */
	public final static int CONFLICT= 1;
	/** Three-way change constant indicating a change in right. */
	public final static int RIGHT= 2;
	/** Three-way change constant indicating a change in left. */
	public final static int LEFT= 3;
	/**
	 * Three-way change constant indicating the same change in both right and left,
	 * that is only the ancestor is different.
	 */
	public final static int ANCESTOR= 4;
	
	/** Constant indicating an unknown change kind. */
	public final static int ERROR= 5;

	/** the kind of change: NOCHANGE, CHANGE, LEFT, RIGHT, ANCESTOR, CONFLICT, ERROR */
	int fKind;

	int fLeftStart;
	int fLeftLength;
	int fRightStart;
	int fRightLength;
	int lAncestorStart;
	int lAncestorLength;
	
	/**
	 * Creates a new range difference with the given change kind.
	 *
	 * @param changeKind the kind of change
	 */
	/* package */ RangeDifference(int changeKind) {
		fKind= changeKind;
	}

	/**
	 * Creates a new <code>RangeDifference</code> with the given change kind
	 * and left and right ranges.
	 *
	 * @param changeKind the kind of change
	 * @param rightStart start index of entity on right side
	 * @param rightLength number of entities on right side
	 * @param leftStart start index of entity on left side
	 * @param leftLength number of entities on left side
	 */
	/* package */ RangeDifference(int kind, int rightStart, int rightLength, int leftStart, int leftLength) {
		fKind= kind;
		fRightStart= rightStart;
		fRightLength= rightLength;
		fLeftStart= leftStart;
		fLeftLength= leftLength;
	}

	/**
	 * Creates a new <code>RangeDifference</code> with the given change kind
	 * and left, right, and ancestor ranges.
	 *
	 * @param changeKind the kind of change
	 * @param rightStart start index of entity on right side
	 * @param rightLength number of entities on right side
	 * @param leftStart start index of entity on left side
	 * @param leftLength number of entities on left side
	 * @param ancestorStart start index of entity on ancestor side
	 * @param ancestorLength number of entities on ancestor side
	 */
	/* package */ RangeDifference(int kind, int rightStart, int rightLength, int leftStart, int leftLength,
									int ancestorStart, int ancestorLength) {
		this(kind, rightStart, rightLength, leftStart, leftLength);
		lAncestorStart= ancestorStart;
		lAncestorLength= ancestorLength;
	}

	/**
	 * Returns the kind of difference.
	 *
	 * @return the kind of difference, one of
	 * <code>NOCHANGE</code>, <code>CHANGE</code>, <code>LEFT</code>, <code>RIGHT</code>,
	 * <code>ANCESTOR</code>, <code>CONFLICT</code>, <code>ERROR</code>
	 */
	public int kind() {
		return fKind;
	}

	/**
	 * Returns the start index of the entity range on the ancestor side.
	 *
	 * @return the start index of the entity range on the ancestor side
	 */
	public int ancestorStart() {
		return lAncestorStart;
	}

	/**
	 * Returns the number of entities on the ancestor side.
	 *
	 * @return the number of entities on the ancestor side
	 */
	public int ancestorLength() {
		return lAncestorLength;
	}

	/**
	 * Returns the end index of the entity range on the ancestor side.
	 *
	 * @return the end index of the entity range on the ancestor side
	 */
	public int ancestorEnd() {
		return lAncestorStart + lAncestorLength;
	}

	/**
	 * Returns the start index of the entity range on the right side.
	 *
	 * @return the start index of the entity range on the right side
	 */
	public int rightStart() {
		return fRightStart;
	}

	/**
	 * Returns the number of entities on the right side.
	 *
	 * @return the number of entities on the right side
	 */
	public int rightLength() {
		return fRightLength;
	}

	/**
	 * Returns the end index of the entity range on the right side.
	 *
	 * @return the end index of the entity range on the right side
	 */
	public int rightEnd() {
		return fRightStart + fRightLength;
	}

	/**
	 * Returns the start index of the entity range on the left side.
	 *
	 * @return the start index of the entity range on the left side
	 */
	public int leftStart() {
		return fLeftStart;
	}

	/**
	 * Returns the number of entities on the left side.
	 *
	 * @return the number of entities on the left side
	 */
	public int leftLength() {
		return fLeftLength;
	}

	/**
	 * Returns the end index of the entity range on the left side.
	 *
	 * @return the end index of the entity range on the left side
	 */
	public int leftEnd() {
		return fLeftStart + fLeftLength;
	}

	/**
	 * Returns the maximum number of entities in the left, right, and ancestor sides of this range.
	 *
	 * @return the maximum number of entities in the left, right, and ancestor sides of this range
	 */
	public int maxLength() {
		return Math.max(fRightLength, Math.max(fLeftLength, lAncestorLength));
	}
}

