import 'dart:math' as math;

/// Represents a slice of indices within a sprite list for animation states,
/// with the ability to skip specific frames.
class SpriteFrameRange {
  final int start;
  final int end;
  final Set<int> excluded;

  const SpriteFrameRange(
    this.start,
    this.end, {
    this.excluded = const {},
  });

  /// Total number of frames in this animation range, excluding skipped indices.
  int get length {
    final baseLength = end - start + 1;
    // Count how many excluded indices actually fall within the start/end bounds
    final exclusionsInRange = excluded
        .where((i) => i >= start && i <= end)
        .length;
    return baseLength - exclusionsInRange;
  }

  /// Checks if a specific sprite [index] is part of this range and not excluded.
  bool contains(int index) {
    return index >= start && index <= end && !excluded.contains(index);
  }

  /// Checks if this range shares any valid (non-excluded) frames with [other].
  bool overlaps(SpriteFrameRange other) {
    // Find the overlapping boundary
    final overlapStart = math.max(start, other.start);
    final overlapEnd = math.min(end, other.end);

    // If bounds don't intersect at all, they don't overlap
    if (overlapStart > overlapEnd) return false;

    // If they intersect, verify the overlapping frames aren't excluded
    for (int i = overlapStart; i <= overlapEnd; i++) {
      if (!excluded.contains(i) && !other.excluded.contains(i)) {
        return true; // Found a frame that belongs to both!
      }
    }

    return false;
  }
}
