// Generated by CoffeeScript 1.5.0
(function() {
  var DateRange, moment;

  moment = typeof require !== "undefined" && require !== null ? require("moment") : this.moment;

  /**
    * DateRange class to store ranges and query dates.
    * @typedef {!Object}
  *
  */


  DateRange = (function() {
    /**
      * DateRange instance.
      * @param {(Moment|Date)} start Start of interval.
      * @param {(Moment|Date)} end   End of interval.
      * @constructor
    *
    */

    function DateRange(start, end) {
      this.start = start;
      this.end = end;
    }

    /**
      * Determine if the current interval contains a given moment/date.
      * @param {(Moment|Date)} moment Date to check.
      * @return {!boolean}
    *
    */


    DateRange.prototype.contains = function(moment) {
      return (this.start <= moment && moment <= this.end);
    };

    DateRange.prototype._by_string = function(interval, hollaback) {
      var current, _results;
      current = moment(this.start);
      _results = [];
      while (this.contains(current)) {
        hollaback.call(this, current.clone());
        _results.push(current.add(interval, 1));
      }
      return _results;
    };

    DateRange.prototype._by_range = function(range_interval, hollaback) {
      var i, l, _i, _results;
      l = Math.round(this / range_interval);
      if (l === Infinity) {
        return this;
      }
      _results = [];
      for (i = _i = 0; 0 <= l ? _i <= l : _i >= l; i = 0 <= l ? ++_i : --_i) {
        _results.push(hollaback.call(this, moment(this.start.valueOf() + range_interval.valueOf() * i)));
      }
      return _results;
    };

    /**
      * Determine if the current date range overlaps a given date range.
      * @param {DateRange} range Date range to check.
      * @return {!boolean}
    *
    */


    DateRange.prototype.overlaps = function(range) {
      return this.start < range.end && this.end > range.start;
    };

    /**
      * Iterate over the date range by a given date range, executing a function
      * for each sub-range.
      * @param {!DateRange|String}        range     Date range to be used for iteration or shorthand string (shorthands: http://momentjs.com/docs/#/manipulating/add/)
      * @param {!function(Moment)} hollaback Function to execute for each sub-range.
      * @return {!boolean}
    *
    */


    DateRange.prototype.by = function(range, hollaback) {
      if (typeof range === 'string') {
        this._by_string(range, hollaback);
      } else {
        this._by_range(range, hollaback);
      }
      return this;
    };

    /**
      * Date range in milliseconds. Allows basic coercion math of date ranges.
      * @return {!number}
    *
    */


    DateRange.prototype.valueOf = function() {
      return this.end - this.start;
    };

    return DateRange;

  })();

  /**
    * Build a date range.
    * @param {(Moment|Date)} start Start of range.
    * @param {(Moment|Date)} end   End of range.
    * @this {Moment}
    * @return {!DateRange}
  *
  */


  moment.fn.range = function(start, end) {
    return new DateRange(start, end);
  };

  /**
    * Check if the current moment is within a given date range.
    * @param {!DateRange} range Date range to check.
    * @this {Moment}
    * @return {!boolean}
  *
  */


  moment.fn.within = function(range) {
    return range.contains(this._d);
  };

  if ((typeof module !== "undefined" && module !== null ? module.exports : void 0) != null) {
    module.exports = moment;
  }

}).call(this);
