// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import "dart:math" as math;

/**
 * A source range defines a range of characters within source code.
 */
class SourceRange {
  /**
   * An empty source range (a range with offset `0` and length `0`).
   */
  static const SourceRange EMPTY = const SourceRange(0, 0);

  /**
   * The 0-based index of the first character of the source range.
   */
  final int offset;

  /**
   * The number of characters in the source range.
   */
  final int length;

  /**
   * Initialize a newly created source range using the given [offset] and
   * [length].
   */
  const SourceRange(this.offset, this.length);

  /**
   * Return the 0-based index of the character immediately after this source
   * range.
   */
  int get end => offset + length;

  @override
  int get hashCode => 31 * offset + length;

  @override
  bool operator ==(Object other) {
    return other is SourceRange &&
        other.offset == offset &&
        other.length == length;
  }

  /**
   * Return `true` if [x] is in the interval `[offset, offset + length)`.
   */
  bool contains(int x) => offset <= x && x < offset + length;

  /**
   * Return `true` if [x] is in the interval `(offset, offset + length)`.
   */
  bool containsExclusive(int x) => offset < x && x < offset + length;

  /**
   * Return `true` if the [otherRange] covers this source range.
   */
  bool coveredBy(SourceRange otherRange) => otherRange.covers(this);

  /**
   * Return `true` if this source range covers the [otherRange].
   */
  bool covers(SourceRange otherRange) =>
      offset <= otherRange.offset && otherRange.end <= end;

  /**
   * Return `true` if this source range ends inside the [otherRange].
   */
  bool endsIn(SourceRange otherRange) {
    int thisEnd = end;
    return otherRange.contains(thisEnd);
  }

  /**
   * Return a source range covering [delta] characters before the start of this
   * source range and [delta] characters after the end of this source range.
   */
  SourceRange getExpanded(int delta) =>
      new SourceRange(offset - delta, delta + length + delta);

  /**
   * Return a source range with the same offset as this source range but whose
   * length is [delta] characters longer than this source range.
   */
  SourceRange getMoveEnd(int delta) => new SourceRange(offset, length + delta);

  /**
   * Return a source range with the same length as this source range but whose
   * offset is [delta] characters after the offset of this source range.
   */
  SourceRange getTranslated(int delta) =>
      new SourceRange(offset + delta, length);

  /**
   * Return the minimal source range that covers both this and the [otherRange].
   */
  SourceRange getUnion(SourceRange otherRange) {
    int newOffset = math.min(offset, otherRange.offset);
    int newEnd =
        math.max(offset + length, otherRange.offset + otherRange.length);
    return new SourceRange(newOffset, newEnd - newOffset);
  }

  /**
   * Return `true` if this source range intersects the [otherRange].
   */
  bool intersects(SourceRange otherRange) {
    if (otherRange == null) {
      return false;
    }
    if (end <= otherRange.offset) {
      return false;
    }
    if (offset >= otherRange.end) {
      return false;
    }
    return true;
  }

  /**
   * Return `true` if this source range starts in the [otherRange].
   */
  bool startsIn(SourceRange otherRange) => otherRange.contains(offset);

  @override
  String toString() => '[offset=$offset, length=$length]';
}
