/**
 * This {@link Ext.grid.Grid grid} plugin manages a bottom-docked summary {@link #row row}.
 *
 * By default, the column's {@link Ext.grid.column.Column#cfg!dataIndex dataIndex} is used
 * to read from the {@link Ext.data.Store#getSummaryRecord summary record} as controlled by
 * the model's {@link Ext.data.Model#cfg!summary summary} definition. To use a different
 * field, the {@link Ext.grid.column.Column#cfg!summaryDataIndex summaryDataIndex} can be
 * specified.
 *
 * The {@link Ext.grid.column.Column#cfg!summary summary} config can be used to perform
 * column-specific summarization. The `summary` config uses one of the registered summary
 * types (see below). Custom summary types can be defined, or a column-specific algorithm
 * can be provided with a {@link Ext.grid.column.Column#cfg!summaryRenderer summaryRenderer}.
 *
 * ## Summary Types
 *
 * The `summary` type can be one of the predefined summary types:
 *
 * + {@link Ext.data.summary.Average average}
 * + {@link Ext.data.summary.Count count}
 * + {@link Ext.data.summary.Max max}
 * + {@link Ext.data.summary.Min min}
 * + {@link Ext.data.summary.Sum sum}
 *
 *
 * ```javascript
 * @example({ framework: 'extjs' })
 * var store = Ext.create('Ext.data.Store', {
 *     fields: ['fname', 'lname', 'talent', 'wins'],
 *     data: [
 *         { 'fname': 'Barry',  'lname': 'Allen', 'talent': 'Speedster', 'wins': 150  },
 *         { 'fname': 'Oliver', 'lname': 'Queen', 'talent': 'Archery', 'wins': 27  },
 *         { 'fname': 'Kara',   'lname': 'Zor-El', 'talent': 'All', 'wins': 75  },
 *         { 'fname': 'Helena', 'lname': 'Bertinelli', 'talent': 'Weapons Expert', 'wins': 7  },
 *         { 'fname': 'Hal',    'lname': 'Jordan', 'talent': 'Willpower', 'wins': 198  },
 *     ]
 * });
 *
 * Ext.create('Ext.grid.Grid', {
 *     title: 'DC Personnel',
 *
 *     store: store,
 *     plugins: {
 *         gridsummaryrow: true
 *     },
 *     columns: [
 *         { text: 'First Name', dataIndex: 'fname',  flex: 1 },
 *         { text: 'Last Name',  dataIndex: 'lname',  flex: 1 },
 *         { text: 'Talent',     dataIndex: 'talent', flex: 1 },
 *         { text: 'Wins',       dataIndex: 'wins',   flex: 1,  summary: 'sum' }
 *     ],
 *     fullscreen: true,
 *     height:275
 * });
 * ```
 * ```html
 * @example({framework: 'ext-web-components', packages:['ext-web-components'], tab: 1 })
 * <ext-container width="100%" height="100%">
 *     <ext-grid
 *       shadow="true"
 *       height="275"
 *       plugins='["gridsummaryrow"]'
 *       onready="summaryGrid.onGridReady"
 *       fullscreen="true"
 *       variableHeights="true"
 *     >
 *         <ext-column text="First Name" dataIndex="fname" flex="1"></ext-column>
 *         <ext-column text="Last Name" dataIndex="lname" flex="1"></ext-column>
 *         <ext-column text="Talent" dataIndex="talent" flex="1"></ext-column>
 *         <ext-column text="Wins" dataIndex="wins" flex="1" summary="sum"></ext-column>
 *     </ext-grid>
 * </ext-container>
 * ```
 * ```javascript
 * @example({framework: 'ext-web-components', tab: 2, packages: ['ext-web-components']})
 * import '@sencha/ext-web-components/dist/ext-container.component';
 * import '@sencha/ext-web-components/dist/ext-grid.component';
 * import '@sencha/ext-web-components/dist/ext-column.component';
 * 
 * Ext.require('Ext.grid.plugin.Summary');
 * 
 * export default class SummaryGridComponent {
 *     constructor() {
 *        this.store = new Ext.data.Store({
 *           data: [
 *               {
 *                   'fname': 'Barry',
 *                   'lname': 'Allen',
 *                   'talent': 'Speedster',
 *                   'wins': 150
 *               },
 *               {
 *                   'fname': 'Oliver',
 *                   'lname': 'Queen',
 *                   'talent': 'Archery',
 *                   'wins': 120
 *               },
 *               {
 *                    'fname': 'Kara',
 *                    'lname': 'Zor-El',
 *                    'talent': 'All',
 *                    'wins': 90
 *               },
 *               {
 *                   'fname': 'Helena',
 *                   'lname': 'Bertinelli',
 *                   'talent': 'Weapons Expert',
 *                   'wins': 70
 *               },
 *               {
 *                   'fname': 'Hal',
 *                   'lname': 'Jordan',
 *                   'talent': 'Willpower',
 *                   'wins': 60
 *               }
 *           ]
 *        });
 *     }
 * 
 *     onGridReady(event) {
 *         this.summaryGridCmp = event.detail.cmp;
 *         this.summaryGridCmp.setStore(this.store);
 *     }
 * }
 * 
 * window.summaryGrid = new SummaryGridComponent();
 * ```
 * ```javascript
 * @example({framework: 'ext-react', packages:['ext-react']})
 * import React, { Component } from 'react'
 * import { ExtGrid, ExtColumn } from '@sencha/ext-react';
 * 
 * Ext.require('Ext.grid.plugin.Summary');
 *
 * export default class MyExample extends Component {
 *
 *     store = new Ext.data.Store({
 *         data: [
 *             { 'fname': 'Barry', 'lname': 'Allen', 'talent': 'Speedster', 'wins': 150 },
 *             { 'fname': 'Oliver', 'lname': 'Queen', 'talent': 'Archery', 'wins': 27 },
 *             { 'fname': 'Kara', 'lname': 'Zor-El', 'talent': 'All', 'wins': 75 },
 *             { 'fname': 'Helena', 'lname': 'Bertinelli', 'talent': 'Weapons Expert', 'wins': 7 },
 *             { 'fname': 'Hal', 'lname': 'Jordan', 'talent': 'Willpower', 'wins': 198 }
 *         ]
 *     });
 *      
 *     render() {
 *         return (
 *             <ExtGrid
 *                 height="275"
 *                 store={this.store} 
 *                 plugins={['gridsummaryrow']}
 *             >
 *                 <ExtColumn text="First Name" dataIndex="fname" flex={1} />
 *                 <ExtColumn text="Last Name" dataIndex="lname" flex={1} />
 *                 <ExtColumn text="Talent" dataIndex="talent" flex={1} />
 *                 <ExtColumn text="Wins" dataIndex="wins" flex={1} summary="sum" />
 *             </ExtGrid>
 *         )
 *     }
 * }
 * ```
 * ```javascript
 * @example({framework: 'ext-angular', packages:['ext-angular']})
 * import { Component } from '@angular/core'
 * declare var Ext: any;
 * 
 *  Ext.require('Ext.grid.plugin.Summary');
 *  @Component({
 *      selector: 'app-root-1',
 *      styles: [`
 *              `],
 *      template: `
 *      <ExtContainer layout="fit">
 *          <ExtGrid
 *               [height]="'280px'"
 *               [store]="this.store"
 *               [plugins]="['gridsummaryrow']"
 *           >
 *               <ExtColumn text="First Name" dataIndex="fname" flex="1"></ExtColumn>
 *               <ExtColumn text="Last Name" dataIndex="lname" flex="1"></ExtColumn>
 *               <ExtColumn text="Talent" dataIndex="talent" flex="1"></ExtColumn>
 *               <ExtColumn text="Wins" dataIndex="wins" flex="1" summary="sum"></ExtColumn>
 *           </ExtGrid>
 *       </ExtContainer>
 *      `
 *  })
 *  export class AppComponent {
 *      store = Ext.create('Ext.data.Store', {
 *          data: [
 *              { 'fname': 'Barry', 'lname': 'Allen', 'talent': 'Speedster', 'wins': 150 },
 *              { 'fname': 'Oliver', 'lname': 'Queen', 'talent': 'Archery', 'wins': 27 },
 *              { 'fname': 'Kara', 'lname': 'Zor-El', 'talent': 'All', 'wins': 75 },
 *              { 'fname': 'Helena', 'lname': 'Bertinelli', 'talent': 'Weapons Expert', 'wins': 7 },
 *              { 'fname': 'Hal', 'lname': 'Jordan', 'talent': 'Willpower', 'wins': 198 }
 *          ]
 *      });
 *  }
 * ```
 *
 */
Ext.define('Ext.grid.plugin.Summary', {
    extend: 'Ext.plugin.Abstract',
    alias: [
        'plugin.gridsummary',
        'plugin.summaryrow',
        'plugin.gridsummaryrow'
    ],
    alternateClassName: 'Ext.grid.plugin.SummaryRow',
 
    mixins: [
        'Ext.mixin.Bufferable',
        'Ext.mixin.StoreWatcher'
    ],
 
    requires: [
        'Ext.grid.SummaryRow'
    ],
 
    config: {
        /**
         * @cfg {Ext.grid.SummaryRow/Object} row
         * The configuration object for the docked summary row managed by this plugin.
         * @since 6.5.0
         */
        row: {
            lazy: true,
            $value: {
                xtype: 'gridsummaryrow',
                docked: 'bottom'
            }
        }
    },
 
    inheritUi: true,
 
    storeListeners: {
        add: 'syncSummary',
        clear: 'syncSummary',
        remove: 'syncSummary',
        refresh: 'syncSummary',
        update: 'syncSummary'
    },
 
    bufferableMethods: {
        // buffer updates to reduce re-summarization passes over the entire store.
        syncSummary: 5
    },
 
    init: function(grid) {
        var scrollable = grid.getScrollable(),
            row, rowScroller;
 
        this.setOwner(grid);
        row = this.getRow();
        grid.addCls(Ext.baseCSSPrefix + 'grid-has-summaryrow');
 
        if (scrollable) {
            rowScroller = row.getScrollable();
 
            if (!rowScroller) {
                row.setScrollable({
                    x: false,
                    y: false
                });
                rowScroller = row.getScrollable();
            }
 
            rowScroller.addPartner(scrollable, 'x');
        }
    },
 
    destroy: function() {
        this.setOwner(null);
 
        this.callParent();
    },
 
    createRow: function(config) {
        return Ext.apply({
            viewModel: this.getOwner().getItemConfig().viewModel
        }, config);
    },
 
    applyRow: function(row) {
        if (row) {
            row = this.createRow(row);
            row = this.cmp.add(row);
        }
 
        return row;
    },
 
    updateStore: function(store, oldStore) {
        this.mixins.storewatcher.updateStore.call(this, store, oldStore);
 
        if (store && store.isLoaded()) {
            // if the store is already loaded then we update summaries
            this.syncSummary();
        }
    },
 
    privates: {
        doSyncSummary: function() {
            var row = this.getRow();
 
            if (row) {
                row.syncSummary();
            }
        },
 
        onContainerScroll: function(scr, x) {
            var item = this.getRow(),
                scroller;
 
            if (!(scroller = item.getScrollable())) {
                item.setScrollable({
                    x: false,
                    y: false
                });
 
                scroller = item.getScrollable();
            }
 
            scroller.scrollTo(x, null);
        }
    }
});