define(['angular'], function(angular) {
  var pagination = angular.module('pagination', []);

  pagination.directive('pagination', function() {
    return {
      restrict: 'E',
      scope: {
        actualTotalCount: '=totalCount',
        offset: '=',
        limit: '=',
        showResultsRange: '@'
      },
      templateUrl: new XWiki.Document('Pagination', 'FileManagerCode').getURL('get'),
      link: function(scope, element, attrs) {
        scope.loadPage = function(pageNumber) {
          scope.offset = pageNumber * scope.limit;
        };

        scope.$watch('[actualTotalCount, offset, limit]', function(newValues, oldValues) {
          // Initialize the scope once and then update the values only when the total count is defined.
          // The total count is usually undefined while a new page is loaded and so we use the old value until we
          // receive the new one. This way we reduce the UI flickering.
          if (scope.actualTotalCount === undefined && scope.totalCount) return;

          var totalCount = newValues[0] || 0;
          var offset = newValues[1] || 0;
          var limit = newValues[2] || 15;

          scope.totalCount = totalCount;
          scope.from = offset + 1;
          scope.to = Math.min(offset + limit, totalCount);
          scope.pageNumber = Math.floor(offset / limit);
          scope.pageCount = Math.floor((totalCount + limit - 1) / limit);

          var contextRadius = 4;
          var contextSize = 2 * contextRadius + 1;
          if (scope.pageCount <= contextSize) {
            scope.contextFirstPage = 0;
            scope.contextLastPage = scope.pageCount - 1;
          } else {
            scope.contextFirstPage = Math.min(Math.max(scope.pageNumber - contextRadius, 0), scope.pageCount - contextSize);
            scope.contextLastPage = Math.max(Math.min(scope.pageNumber + contextRadius, scope.pageCount - 1), contextSize - 1);
          }
          scope.pageNumbers = [];
          for (var i = scope.contextFirstPage; i <= scope.contextLastPage; i++) {
            scope.pageNumbers.push(i);
          }
        }, true);
      }
    };
  });

  pagination.directive('pageLink', function() {
    return {
      restrict: 'E',
      scope: true,
      templateUrl: new XWiki.Document('Pagination', 'FileManagerCode').getURL('get', 'template=pageLink'),
      link: function(scope, element, attrs) {
        scope.number = parseInt(attrs.number);
      }
    };
  });
});
