/**
 * Adds custom behavior for left/right keyboard navigation for use with a tree.
 * Depends on the view having an expand and collapse method which accepts a
 * record. This selection model is created by default for {@link Ext.tree.Panel}.
 */
Ext.define('Ext.selection.TreeModel', {
    extend: 'Ext.selection.RowModel',
    alias: 'selection.treemodel',

    /**
     * @cfg {Boolean} pruneRemoved @hide
     */

    constructor: function(config) {
        this.callParent(arguments);

        // If pruneRemoved is required, we must listen to the *TreeStore* to know when nodes
        // are added and removed
        if (this.pruneRemoved) {
            this.pruneRemoved = false;
            this.pruneRemovedNodes = true;
        }
    },

    // binds the store to the selModel.
    bindStore: function(store, initial) {
        var me = this;
        me.callParent(arguments);

        // TreePanel should have injected a reference to the TreeStore so that we can
        // listen for node removal.
        if (me.pruneRemovedNodes) {
            me.view.mon(me.treeStore, {
                remove: me.onNodeRemove,
                scope: me
            });
        }
    },

    onNodeRemove: function(parent, node, isMove) {
        // deselection of deleted records done in base Model class
        if (!isMove) {
            this.deselectDeletedRecords([node]);
        }
    },

    onKeyRight: function(e, t) {
        this.navExpand(e, t);
    },
    
    navExpand: function(e, t) {
        var focused = this.getLastFocused(),
            view    = this.view;

        if (focused) {
            // tree node is already expanded, go down instead
            // this handles both the case where we navigate to firstChild and if
            // there are no children to the nextSibling
            if (focused.isExpanded()) {
                this.onKeyDown(e, t);
            // if its not a leaf node, expand it
            } else if (focused.isExpandable()) {
                // If we are the normal side of a locking pair, only the tree view can do expanding
                if (!view.isTreeView) {
                    view = view.lockingPartner;
                }

                view.expand(focused);
            }
        }
    },

    onKeyLeft: function(e, t) {
        this.navCollapse(e, t);
    },
    
    navCollapse: function(e, t) {
        var me = this,
            focused = this.getLastFocused(),
            view    = this.view,
            parentNode;

        if (focused) {
            parentNode = focused.parentNode;
            // if focused node is already expanded, collapse it
            if (focused.isExpanded()) {
                // If we are the normal side of a locking pair, only the tree view can do collapsing
                if (!view.isTreeView) {
                    view = view.lockingPartner;
                }

                view.collapse(focused);
            // has a parentNode and its not root
            // TODO: this needs to cover the case where the root isVisible
            } else if (parentNode && !parentNode.isRoot()) {
                // Select a range of records when doing multiple selection.
                if (e.shiftKey) {
                    me.selectRange(parentNode, focused, e.ctrlKey, 'up');
                    me.setLastFocused(parentNode);
                // just move focus, not selection
                } else if (e.ctrlKey) {
                    me.setLastFocused(parentNode);
                // select it
                } else {
                    me.select(parentNode);
                }
            }
        }
    },

    onKeySpace: function(e, t) {
        if (e.record.data.checked != null) {
            this.toggleCheck(e);
        } else {
            this.callParent(arguments);
        }
    },

    onKeyEnter: function(e, t) {
        if (e.record.data.checked != null) {
            this.toggleCheck(e);
        } else {
            this.callParent(arguments);
        }
    },

    toggleCheck: function(e) {
        var view = this.view,
            selected = this.getLastSelected();

        e.stopEvent();
        if (selected) {
            // If we are the normal side of a locking pair, only the tree view can do on heckChange
            if (!view.isTreeView) {
                view = view.lockingPartner;
            }

            view.onCheckChange(selected);
        }
    }
});