/*---------------------------------------------------------------------------------------------
*  Copyright (c) Microsoft Corporation. All rights reserved.
*  Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var position_1 = require('./position');
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
/**
 * A range in the editor. (startLineNumber,startColumn) is <= (endLineNumber,endColumn)
 */
var Range = (function () {
	function Range(startLineNumber, startColumn, endLineNumber, endColumn) {
		if ((startLineNumber > endLineNumber) || (startLineNumber === endLineNumber && startColumn > endColumn)) {
			this.startLineNumber = endLineNumber;
			this.startColumn = endColumn;
			this.endLineNumber = startLineNumber;
			this.endColumn = startColumn;
		}
		else {
			this.startLineNumber = startLineNumber;
			this.startColumn = startColumn;
			this.endLineNumber = endLineNumber;
			this.endColumn = endColumn;
		}
	}
	/**
	 * Test if this range is empty.
	 */
	Range.prototype.isEmpty = function () {
		return Range.isEmpty(this);
	};
	/**
	 * Test if `range` is empty.
	 */
	Range.isEmpty = function (range) {
		return (range.startLineNumber === range.endLineNumber && range.startColumn === range.endColumn);
	};
	/**
	 * Test if position is in this range. If the position is at the edges, will return true.
	 */
	Range.prototype.containsPosition = function (position) {
		return Range.containsPosition(this, position);
	};
	/**
	 * Test if `position` is in `range`. If the position is at the edges, will return true.
	 */
	Range.containsPosition = function (range, position) {
		if (position.lineNumber < range.startLineNumber || position.lineNumber > range.endLineNumber) {
			return false;
		}
		if (position.lineNumber === range.startLineNumber && position.column < range.startColumn) {
			return false;
		}
		if (position.lineNumber === range.endLineNumber && position.column > range.endColumn) {
			return false;
		}
		return true;
	};
	/**
	 * Test if range is in this range. If the range is equal to this range, will return true.
	 */
	Range.prototype.containsRange = function (range) {
		return Range.containsRange(this, range);
	};
	/**
	 * Test if `otherRange` is in `range`. If the ranges are equal, will return true.
	 */
	Range.containsRange = function (range, otherRange) {
		if (otherRange.startLineNumber < range.startLineNumber || otherRange.endLineNumber < range.startLineNumber) {
			return false;
		}
		if (otherRange.startLineNumber > range.endLineNumber || otherRange.endLineNumber > range.endLineNumber) {
			return false;
		}
		if (otherRange.startLineNumber === range.startLineNumber && otherRange.startColumn < range.startColumn) {
			return false;
		}
		if (otherRange.endLineNumber === range.endLineNumber && otherRange.endColumn > range.endColumn) {
			return false;
		}
		return true;
	};
	/**
	 * A reunion of the two ranges.
	 * The smallest position will be used as the start point, and the largest one as the end point.
	 */
	Range.prototype.plusRange = function (range) {
		return Range.plusRange(this, range);
	};
	/**
	 * A reunion of the two ranges.
	 * The smallest position will be used as the start point, and the largest one as the end point.
	 */
	Range.plusRange = function (a, b) {
		var startLineNumber, startColumn, endLineNumber, endColumn;
		if (b.startLineNumber < a.startLineNumber) {
			startLineNumber = b.startLineNumber;
			startColumn = b.startColumn;
		}
		else if (b.startLineNumber === a.startLineNumber) {
			startLineNumber = b.startLineNumber;
			startColumn = Math.min(b.startColumn, a.startColumn);
		}
		else {
			startLineNumber = a.startLineNumber;
			startColumn = a.startColumn;
		}
		if (b.endLineNumber > a.endLineNumber) {
			endLineNumber = b.endLineNumber;
			endColumn = b.endColumn;
		}
		else if (b.endLineNumber === a.endLineNumber) {
			endLineNumber = b.endLineNumber;
			endColumn = Math.max(b.endColumn, a.endColumn);
		}
		else {
			endLineNumber = a.endLineNumber;
			endColumn = a.endColumn;
		}
		return new Range(startLineNumber, startColumn, endLineNumber, endColumn);
	};
	/**
	 * A intersection of the two ranges.
	 */
	Range.prototype.intersectRanges = function (range) {
		return Range.intersectRanges(this, range);
	};
	/**
	 * A intersection of the two ranges.
	 */
	Range.intersectRanges = function (a, b) {
		var resultStartLineNumber = a.startLineNumber, resultStartColumn = a.startColumn, resultEndLineNumber = a.endLineNumber, resultEndColumn = a.endColumn, otherStartLineNumber = b.startLineNumber, otherStartColumn = b.startColumn, otherEndLineNumber = b.endLineNumber, otherEndColumn = b.endColumn;
		if (resultStartLineNumber < otherStartLineNumber) {
			resultStartLineNumber = otherStartLineNumber;
			resultStartColumn = otherStartColumn;
		}
		else if (resultStartLineNumber === otherStartLineNumber) {
			resultStartColumn = Math.max(resultStartColumn, otherStartColumn);
		}
		if (resultEndLineNumber > otherEndLineNumber) {
			resultEndLineNumber = otherEndLineNumber;
			resultEndColumn = otherEndColumn;
		}
		else if (resultEndLineNumber === otherEndLineNumber) {
			resultEndColumn = Math.min(resultEndColumn, otherEndColumn);
		}
		// Check if selection is now empty
		if (resultStartLineNumber > resultEndLineNumber) {
			return null;
		}
		if (resultStartLineNumber === resultEndLineNumber && resultStartColumn > resultEndColumn) {
			return null;
		}
		return new Range(resultStartLineNumber, resultStartColumn, resultEndLineNumber, resultEndColumn);
	};
	/**
	 * Test if this range equals other.
	 */
	Range.prototype.equalsRange = function (other) {
		return Range.equalsRange(this, other);
	};
	/**
	 * Test if range `a` equals `b`.
	 */
	Range.equalsRange = function (a, b) {
		return (!!a &&
			!!b &&
			a.startLineNumber === b.startLineNumber &&
			a.startColumn === b.startColumn &&
			a.endLineNumber === b.endLineNumber &&
			a.endColumn === b.endColumn);
	};
	/**
	 * Return the end position (which will be after or equal to the start position)
	 */
	Range.prototype.getEndPosition = function () {
		return new position_1.Position(this.endLineNumber, this.endColumn);
	};
	/**
	 * Return the start position (which will be before or equal to the end position)
	 */
	Range.prototype.getStartPosition = function () {
		return new position_1.Position(this.startLineNumber, this.startColumn);
	};
	/**
	 * Clone this range.
	 */
	Range.prototype.cloneRange = function () {
		return new Range(this.startLineNumber, this.startColumn, this.endLineNumber, this.endColumn);
	};
	/**
	 * Transform to a user presentable string representation.
	 */
	Range.prototype.toString = function () {
		return '[' + this.startLineNumber + ',' + this.startColumn + ' -> ' + this.endLineNumber + ',' + this.endColumn + ']';
	};
	/**
	 * Create a new range using this range's start position, and using endLineNumber and endColumn as the end position.
	 */
	Range.prototype.setEndPosition = function (endLineNumber, endColumn) {
		return new Range(this.startLineNumber, this.startColumn, endLineNumber, endColumn);
	};
	/**
	 * Create a new range using this range's end position, and using startLineNumber and startColumn as the start position.
	 */
	Range.prototype.setStartPosition = function (startLineNumber, startColumn) {
		return new Range(startLineNumber, startColumn, this.endLineNumber, this.endColumn);
	};
	/**
	 * Create a new empty range using this range's start position.
	 */
	Range.prototype.collapseToStart = function () {
		return Range.collapseToStart(this);
	};
	/**
	 * Create a new empty range using this range's start position.
	 */
	Range.collapseToStart = function (range) {
		return new Range(range.startLineNumber, range.startColumn, range.startLineNumber, range.startColumn);
	};
	// ---
	/**
	 * Create a `Range` from an `IRange`.
	 */
	Range.lift = function (range) {
		if (!range) {
			return null;
		}
		return new Range(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn);
	};
	/**
	 * Test if `obj` is an `IRange`.
	 */
	Range.isIRange = function (obj) {
		return (obj
			&& (typeof obj.startLineNumber === 'number')
			&& (typeof obj.startColumn === 'number')
			&& (typeof obj.endLineNumber === 'number')
			&& (typeof obj.endColumn === 'number'));
	};
	/**
	 * Test if the two ranges are touching in any way.
	 */
	Range.areIntersectingOrTouching = function (a, b) {
		// Check if `a` is before `b`
		if (a.endLineNumber < b.startLineNumber || (a.endLineNumber === b.startLineNumber && a.endColumn < b.startColumn)) {
			return false;
		}
		// Check if `b` is before `a`
		if (b.endLineNumber < a.startLineNumber || (b.endLineNumber === a.startLineNumber && b.endColumn < a.startColumn)) {
			return false;
		}
		// These ranges must intersect
		return true;
	};
	/**
	 * A function that compares ranges, useful for sorting ranges
	 * It will first compare ranges on the startPosition and then on the endPosition
	 */
	Range.compareRangesUsingStarts = function (a, b) {
		var aStartLineNumber = a.startLineNumber | 0;
		var bStartLineNumber = b.startLineNumber | 0;
		if (aStartLineNumber === bStartLineNumber) {
			var aStartColumn = a.startColumn | 0;
			var bStartColumn = b.startColumn | 0;
			if (aStartColumn === bStartColumn) {
				var aEndLineNumber = a.endLineNumber | 0;
				var bEndLineNumber = b.endLineNumber | 0;
				if (aEndLineNumber === bEndLineNumber) {
					var aEndColumn = a.endColumn | 0;
					var bEndColumn = b.endColumn | 0;
					return aEndColumn - bEndColumn;
				}
				return aEndLineNumber - bEndLineNumber;
			}
			return aStartColumn - bStartColumn;
		}
		return aStartLineNumber - bStartLineNumber;
	};
	/**
	 * A function that compares ranges, useful for sorting ranges
	 * It will first compare ranges on the endPosition and then on the startPosition
	 */
	Range.compareRangesUsingEnds = function (a, b) {
		if (a.endLineNumber === b.endLineNumber) {
			if (a.endColumn === b.endColumn) {
				if (a.startLineNumber === b.startLineNumber) {
					return a.startColumn - b.startColumn;
				}
				return a.startLineNumber - b.startLineNumber;
			}
			return a.endColumn - b.endColumn;
		}
		return a.endLineNumber - b.endLineNumber;
	};
	/**
	 * Test if the range spans multiple lines.
	 */
	Range.spansMultipleLines = function (range) {
		return range.endLineNumber > range.startLineNumber;
	};
	return Range;
}());
exports.Range = Range;
//# sourceMappingURL=range.js.map