text: /**
   * Licensed to the Apache Software Foundation (ASF) under one
   * or more contributor license agreements.  See the NOTICE file
   * distributed with this work for additional information
   * regarding copyright ownership.  The ASF licenses this file
   * to you under the Apache License, Version 2.0 (the
   * "License"); you may not use this file except in compliance
   * with the License.  You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  var App = require('app');
  
  /**
   * Mixin should be used for Em.View of table that uses server to filter, sort, paginate content
   */
  App.TableServerViewMixin = Em.Mixin.create({
    filteringComplete: true,
    timeOut: null,
    /**
     * filter delay time, used to combine filters change into one content update
     */
    filterWaitingTime: 500,
  
    /**
     * count of filtered items
     */
    filteredCount: function () {
      return this.get('controller.filteredCount');
    }.property('controller.filteredCount'),
    /**
     * total count of items
     */
    totalCount: function () {
      return this.get('controller.totalCount');
    }.property('controller.totalCount'),
    /**
     * data requested from server
     */
    content: function () {
      return this.get('controller.content');
    }.property('controller.content'),
    /**
     * content already filtered on server-side
     */
    filteredContent: function () {
      return this.get('content');
    }.property('content'),
    /**
     * sort and slice recieved content by pagination parameters
     */
    pageContent: function () {
      var content = this.get('filteredContent');
      if (content.length > ((this.get('endIndex') - this.get('startIndex')) + 1)) {
        content = content.slice(0, (this.get('endIndex') - this.get('startIndex')) + 1);
      }
      return content.sort(function (a, b) {
        return a.get('index') - b.get('index');
      });
    }.property('filteredContent'),
  
    /**
     * compute applied filter and run content update from server
     * @param iColumn
     * @param value
     * @param type
     */
    updateFilter: function (iColumn, value, type) {
      var self = this;
      this.set('controller.resetStartIndex', false);
      this.saveFilterConditions(iColumn, value, type, false);
      if (!this.get('filteringComplete')) {
        clearTimeout(this.get('timeOut'));
        this.set('timeOut', setTimeout(function () {
          self.updateFilter(iColumn, value, type);
        }, this.get('filterWaitingTime')));
      } else {
        clearTimeout(this.get('timeOut'));
        this.set('controller.resetStartIndex', true);
        this.refresh();
      }
    },
  
    /**
     * success callback for updater request
     */
    updaterSuccessCb: function () {
      clearTimeout(this.get('timeOut'));
      this.set('filteringComplete', true);
      this.propertyDidChange('pageContent');
    },
  
    /**
     * error callback for updater request
     */
    updaterErrorCb: function () {
      this.set('requestError', arguments);
    },
  
    /**
     * synchronize properties of view with controller to generate query parameters
     */
    updatePagination: function (key) {
      if (!Em.isNone(this.get('displayLength'))) {
        App.db.setDisplayLength(this.get('controller.name'), this.get('displayLength'));
        this.get('controller.paginationProps').findProperty('name', 'displayLength').value = this.get('displayLength');
      }
      if (!Em.isNone(this.get('startIndex'))) {
        App.db.setStartIndex(this.get('controller.name'), this.get('startIndex'));
        this.get('controller.paginationProps').findProperty('name', 'startIndex').value = this.get('startIndex');
      }
  
      if (key !== 'SKIP_REFRESH') {
        this.refresh();
      }
    },
    /**
     * when new filter applied page index should be reset to first page
     */
    resetStartIndex: function () {
      if (this.get('controller.resetStartIndex') && this.get('filteredCount') > 0) {
        this.set('startIndex', 1);
      }
    }.observes('controller.resetStartIndex')
  });
  