/*
This file is part of Ext JS 3.4

Copyright (c) 2011-2013 Sencha Inc

Contact:  http://www.sencha.com/contact

GNU General Public License Usage
This file may be used under the terms of the GNU General Public License version 3.0 as
published by the Free Software Foundation and appearing in the file LICENSE included in the
packaging of this file.

Please review the following information to ensure the GNU General Public License version 3.0
requirements will be met: http://www.gnu.org/copyleft/gpl.html.

If you are unsure which license is appropriate for your use, please contact the sales department
at http://www.sencha.com/contact.

Build date: 2013-04-03 15:07:25
*/
Ext.onReady(function() {
    // create the data store
    var store = new Ext.data.ArrayStore({
        fields: [
           {name: 'rating', type: 'int'},
           {name: 'salary', type: 'float'},
           {name: 'name'}
        ]
    });

    // manually load local fake data
    store.loadData(createFakeData(25));
    
    var reorderer = new Ext.ux.ToolbarReorderer();
    var droppable = new Ext.ux.ToolbarDroppable({
        /**
         * Creates the new toolbar item from the drop event
         */
        createItem: function(data) {
            var column = this.getColumnFromDragDrop(data);
            
            return createSorterButton({
                text    : column.header,
                sortData: {
                    field: column.dataIndex,
                    direction: "ASC"
                }
            });
        },

        /**
         * Custom canDrop implementation which returns true if a column can be added to the toolbar
         * @param {Object} data Arbitrary data from the drag source
         * @return {Boolean} True if the drop is allowed
         */
        canDrop: function(dragSource, event, data) {
            var sorters = getSorters(),
                column  = this.getColumnFromDragDrop(data);

            for (var i=0; i < sorters.length; i++) {
                if (sorters[i].field == column.dataIndex) return false;
            }

            return true;
        },
        
        afterLayout: doSort,

        /**
         * Helper function used to find the column that was dragged
         * @param {Object} data Arbitrary data from
         */
        getColumnFromDragDrop: function(data) {
            var index    = data.header.cellIndex,
                colModel = grid.colModel,
                column   = colModel.getColumnById(colModel.getColumnId(index));

            return column;
        }
    });
    
    //create the toolbar with the 2 plugins
    var tbar = new Ext.Toolbar({
        items  : ['Sorting order:', '-'],
        plugins: [reorderer, droppable],
        listeners: {
            scope    : this,
            reordered: function(button) {
                changeSortDirection(button, false);
            }
        }
    });
    
    // create the Grid
    var grid = new Ext.grid.GridPanel({
        tbar : tbar,
        store: store,
        
        columns: [
            {header: 'Name',   width: 160, sortable: false, dataIndex: 'name',   id:'company'},
            {header: 'Rating', width: 125, sortable: false, dataIndex: 'rating'},
            {header: 'Salary', width: 125, sortable: false, dataIndex: 'salary', renderer: 'usMoney'}
        ],
        autoExpandColumn: 'company',
        stripeRows: true,
        
        height: 350,
        width : 600,
        title : 'Array Grid',
        
        listeners: {
            scope: this,
            
            //here we tell the toolbar's droppable plugin that it can accept items from the columns' dragdrop group
            render: function() {
                var dragProxy = grid.getView().columnDrag,
                    ddGroup   = dragProxy.ddGroup;
                
                droppable.addDDGroup(ddGroup);
            }
        }
    });
    
    tbar.add(createSorterButton({
        text: 'Rating',
        sortData: {
            field: 'rating',
            direction: 'DESC'
        }
    }));
    
    tbar.add(createSorterButton({
        text: 'Salary',
        sortData: {
            field: 'salary',
            direction: 'ASC'
        }
    }));
    
    // render the grid to the specified div in the page
    grid.render('grid-example');
    doSort();
    
    //The following functions are used to get the sorting data from the toolbar and apply it to the store
    
    /**
     * Tells the store to sort itself according to our sort data
     */
    function doSort() {
        store.sort(getSorters(), "ASC");
    };
    
    /**
     * Callback handler used when a sorter button is clicked or reordered
     * @param {Ext.Button} button The button that was clicked
     * @param {Boolean} changeDirection True to change direction (default). Set to false for reorder
     * operations as we wish to preserve ordering there
     */
    function changeSortDirection(button, changeDirection) {
        var sortData = button.sortData,
            iconCls  = button.iconCls;
        
        if (sortData != undefined) {
            if (changeDirection !== false) {
                button.sortData.direction = button.sortData.direction.toggle("ASC", "DESC");
                button.setIconClass(iconCls.toggle("sort-asc", "sort-desc"));
            }
            
            store.clearFilter();
            doSort();
        }
    };
    
    /**
     * Returns an array of sortData from the sorter buttons
     * @return {Array} Ordered sort data from each of the sorter buttons
     */
    function getSorters() {
        var sorters = [];
        
        Ext.each(tbar.findByType('button'), function(button) {
            sorters.push(button.sortData);
        }, this);
        
        return sorters;
    }
    
    /**
     * Convenience function for creating Toolbar Buttons that are tied to sorters
     * @param {Object} config Optional config object
     * @return {Ext.Button} The new Button object
     */
    function createSorterButton(config) {
        config = config || {};
              
        Ext.applyIf(config, {
            listeners: {
                click: function(button, e) {
                    changeSortDirection(button, true);                    
                }
            },
            iconCls: 'sort-' + config.sortData.direction.toLowerCase(),
            reorderable: true
        });
        
        return new Ext.Button(config);
    };
    
    /**
     * Returns an array of fake data
     * @param {Number} count The number of fake rows to create data for
     * @return {Array} The fake record data, suitable for usage with an ArrayReader
     */
    function createFakeData(count) {
        var firstNames   = ['Ed', 'Tommy', 'Aaron', 'Abe', 'Jamie', 'Adam', 'Dave', 'David', 'Jay'],
            lastNames    = ['Spencer', 'Maintz', 'Conran', 'Elias', 'Avins', 'Mishcon', 'Kaneda', 'Davis', 'Robinson'],
            ratings      = [1, 2, 3, 4, 5],
            salaries     = [100, 400, 900, 1500, 1000000];

        var data = [];
        for (var i=0; i < (count || 25); i++) {
            var ratingId    = Math.floor(Math.random() * ratings.length),
                salaryId    = Math.floor(Math.random() * salaries.length),
                firstNameId = Math.floor(Math.random() * firstNames.length),
                lastNameId  = Math.floor(Math.random() * lastNames.length),

                rating      = ratings[ratingId],
                salary      = salaries[salaryId],
                name        = String.format("{0} {1}", firstNames[firstNameId], lastNames[lastNameId]);

            data.push([rating, salary, name]);
        }
        
        return data;
    }
});