text: /**
   * @ngdoc directive
   * @name ionInfiniteScroll
   * @module ionic
   * @parent ionic.directive:ionContent, ionic.directive:ionScroll
   * @restrict E
   *
   * @description
   * The ionInfiniteScroll directive allows you to call a function whenever
   * the user gets to the bottom of the page or near the bottom of the page.
   *
   * The expression you pass in for `on-infinite` is called when the user scrolls
   * greater than `distance` away from the bottom of the content.
   *
   * @param {expression} on-infinite What to call when the scroller reaches the
   * bottom.
   * @param {string=} distance The distance from the bottom that the scroll must
   * reach to trigger the on-infinite expression. Default: 1%.
   * @param {string=} icon The icon to show while loading. Default: 'ion-loading-d'.
   *
   * @usage
   * ```html
   * <ion-content ng-controller="MyController">
   *   <ion-infinite-scroll
   *     on-infinite="loadMore()"
   *     distance="1%">
   *   </ion-infinite-scroll>
   * </ion-content>
   * ```
   * ```js
   * function MyController($scope, $http) {
   *   $scope.items = [];
   *   $scope.loadMore = function() {
   *     $http.get('/more-items').success(function(items) {
   *       useItems(items);
   *       $scope.$broadcast('scroll.infiniteScrollComplete');
   *     });
   *   };
   * 
   *   $scope.$on('stateChangeSuccess', function() {
   *     $scope.loadMore();
   *   });
   * }
   * ```
   *
   * An easy to way to stop infinite scroll once there is no more data to load
   * is to use angular's `ng-if` directive:
   *
   * ```html
   * <ion-infinite-scroll
   *   ng-if="moreDataCanBeLoaded()"
   *   icon="ion-loading-c"
   *   on-infinite="loadMoreData()">
   * </ion-infinite-scroll>
   * ```
   */
  IonicModule
  .directive('ionInfiniteScroll', ['$timeout', function($timeout) {
    function calculateMaxValue(distance, maximum, isPercent) {
      return isPercent ?
        maximum * (1 - parseInt(distance,10) / 100) :
        maximum - parseInt(distance, 10);
    }
    return {
      restrict: 'E',
      require: ['^$ionicScroll', 'ionInfiniteScroll'],
      template:
        '<div class="scroll-infinite">' +
          '<div class="scroll-infinite-content">' +
            '<i class="icon {{icon()}} icon-refreshing"></i>' +
          '</div>' +
        '</div>',
      scope: true,
      controller: ['$scope', '$attrs', function($scope, $attrs) {
        this.isLoading = false;
        this.scrollView = null; //given by link function
        this.getMaxScroll = function() {
          var distance = ($attrs.distance || '1%').trim();
          var isPercent = distance.indexOf('%') !== -1;
          var maxValues = this.scrollView.getScrollMax();
          return {
            left: this.scrollView.options.scrollingX ?
              calculateMaxValue(distance, maxValues.left, isPercent) :
              -1,
            top: this.scrollView.options.scrollingY ?
              calculateMaxValue(distance, maxValues.top, isPercent) :
              -1
          };
        };
      }],
      link: function($scope, $element, $attrs, ctrls) {
        var scrollCtrl = ctrls[0];
        var infiniteScrollCtrl = ctrls[1];
        var scrollView = infiniteScrollCtrl.scrollView = scrollCtrl.scrollView;
  
        $scope.icon = function() {
          return angular.isDefined($attrs.icon) ? $attrs.icon : 'ion-loading-d';
        };
  
        var onInfinite = function() {
          $element[0].classList.add('active');
          infiniteScrollCtrl.isLoading = true;
          $scope.$parent && $scope.$parent.$apply($attrs.onInfinite || '');
        }
  
        var finishInfiniteScroll = function() {
          $element[0].classList.remove('active');
          $timeout(function() {
            scrollView.resize();
          }, 0, false);
          infiniteScrollCtrl.isLoading = false;
        };
  
        $scope.$on('scroll.infiniteScrollComplete', function() {
          finishInfiniteScroll();
        });
  
        $scope.$on('$destroy', function() {
          scrollCtrl.$element.off('scroll', checkBounds);
        });
  
        var checkBounds = ionic.animationFrameThrottle(checkInfiniteBounds);
  
        //Check bounds on start, after scrollView is fully rendered
        setTimeout(checkBounds);
        scrollCtrl.$element.on('scroll', checkBounds);
  
        function checkInfiniteBounds() {
          if (infiniteScrollCtrl.isLoading) return;
  
          var scrollValues = scrollView.getValues();
          var maxScroll = infiniteScrollCtrl.getMaxScroll();
  
          if(maxScroll.top === 0) {
            return;
          }
               
          if ((maxScroll.left !== -1 && scrollValues.left >= maxScroll.left) ||
              (maxScroll.top !== -1 && scrollValues.top >= maxScroll.top)) {
            onInfinite();
          }
        }
      }
    };
  }]);
  