// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_BASE_RANGES_H_
#define MEDIA_BASE_RANGES_H_

#include <algorithm>
#include <ostream>
#include <vector>

#include "base/basictypes.h"
#include "base/logging.h"
#include "base/time.h"
#include "media/base/media_export.h"

namespace media {

// Ranges allows holding an ordered list of ranges of [start,end) intervals.
// The canonical example use-case is holding the list of ranges of buffered
// bytes or times in a <video> tag.
template<class T>  // Endpoint type; typically a base::TimeDelta or an int64.
class Ranges {
 public:
  // Allow copy & assign.

  // Add (start,end) to this object, coallescing overlaps as appropriate.
  // Returns the number of stored ranges, post coallescing.
  size_t Add(T start, T end);

  // Return the number of disjoint ranges.
  size_t size() const;

  // Return the "i"'th range's start & end (0-based).
  T start(int i) const;
  T end(int i) const;

  // Clear all ranges.
  void clear();

  // Computes the intersection between this range and |other|.
  Ranges<T> IntersectionWith(const Ranges<T>& other) const;

 private:
  // Wrapper around DCHECK_LT allowing comparisons of operator<<'able T's.
  void DCheckLT(const T& lhs, const T& rhs) const;

  // Disjoint, in increasing order of start.
  std::vector<std::pair<T, T> > ranges_;
};

//////////////////////////////////////////////////////////////////////
// EVERYTHING BELOW HERE IS IMPLEMENTATION DETAIL!!
//////////////////////////////////////////////////////////////////////

template<class T>
size_t Ranges<T>::Add(T start, T end) {
  if (start == end)  // Nothing to be done with empty ranges.
    return ranges_.size();

  DCheckLT(start, end);
  size_t i;
  // Walk along the array of ranges until |start| is no longer larger than the
  // current interval's end.
  for (i = 0; i < ranges_.size() && ranges_[i].second < start; ++i) {
    // Empty body
  }

  // Now we know |start| belongs in the i'th slot.
  // If i is the end of the range, append new range and done.
  if (i == ranges_.size()) {
    ranges_.push_back(std::make_pair(start, end));
    return ranges_.size();
  }

  // If |end| is less than i->first, then [start,end) is a new (non-overlapping)
  // i'th entry pushing everyone else back, and done.
  if (end < ranges_[i].first) {
    ranges_.insert(ranges_.begin() + i, std::make_pair(start, end));
    return ranges_.size();
  }

  // Easy cases done.  Getting here means there is overlap between [start,end)
  // and the existing ranges.

  // Now: start <= i->second && i->first <= end
  if (start < ranges_[i].first)
    ranges_[i].first = start;
  if (ranges_[i].second < end)
    ranges_[i].second = end;

  // Now: [start,end) is contained in the i'th range, and we'd be done, except
  // for the fact that the newly-extended i'th range might now overlap
  // subsequent ranges.  Merge until discontinuities appear.  Note that there's
  // no need to test/merge previous ranges, since needing that would mean the
  // original loop went too far.
  while ((i + 1) < ranges_.size() &&
         ranges_[i + 1].first <= ranges_[i].second) {
    ranges_[i].second = std::max(ranges_[i].second, ranges_[i + 1].second);
    ranges_.erase(ranges_.begin() + i + 1);
  }

  return ranges_.size();
}

template<>
void Ranges<base::TimeDelta>::DCheckLT(const base::TimeDelta& lhs,
                                       const base::TimeDelta& rhs) const;

template<class T>
void Ranges<T>::DCheckLT(const T& lhs, const T& rhs) const {
  DCHECK_LT(lhs, rhs);
}

template<class T>
size_t Ranges<T>::size() const {
  return ranges_.size();
}

template<class T>
T Ranges<T>::start(int i) const {
  return ranges_[static_cast<size_t>(i)].first;
}

template<class T>
T Ranges<T>::end(int i) const {
  return ranges_[static_cast<size_t>(i)].second;
}

template<class T>
void Ranges<T>::clear() {
  ranges_.clear();
}

template<class T>
Ranges<T> Ranges<T>::IntersectionWith(const Ranges<T>& other) const {
  Ranges<T> result;

  size_t i = 0;
  size_t j = 0;

  while (i < size() && j < other.size()) {
    T max_start = std::max(start(i), other.start(j));
    T min_end = std::min(end(i), other.end(j));

    // Add an intersection range to the result if the ranges overlap.
    if (max_start < min_end)
      result.Add(max_start, min_end);

    if (end(i) < other.end(j))
      ++i;
    else
      ++j;
  }

  return result;
}

}  // namespace media

#endif  // MEDIA_BASE_RANGES_H_
