/**
 * Ext.ux.RowContextActions
 * 
 * This plugin can be instantiated once, and applied to multiple grids.  It looks
 * for an additional set of params specified on the grid (rowContextActions),
 * or for a set of 'contextActions' defined on the plugin itself.
 */

Ext.ux.RowContextActions = function(config) {
    Ext.apply(this,config);
}

Ext.ux.RowContextActions.prototype = {
    init:function(grid) {
        
        grid.rowContextActions = grid.rowContextActions || this.contextActions || [];
    
        grid.menu = new Ext.menu.Menu(this.menuCfg);
        grid.menu.grid = grid;
        
        grid.on('rowcontextmenu',grid.menu.open,grid.menu);
        grid.on('bodyscroll',grid.menu.onScroll,grid.menu);
        grid.menu.on('hide',grid.menu.reset);
    }
    
    /**
     * Everything below here is operated in the context of the menu that gets
     * appended to the grid.
     */
    ,menuCfg:{
         curRowIdx:null
        ,curRecord:null
        ,curEvt:null
        ,grid:null
        ,curRowDom:null
        ,width:200
        ,enableScrolling:false
        ,open:function(grid,ri,e) {
            this.removeAll();
            this.curEvt = e;
            this.curRowIdx = ri;
            this.curRecord = grid.store.getAt(ri);
            this.doLoadItems();

            if (!this.showable) { return this.hide(); }

            this.curRowDom = grid.getView().getRow(ri);
            
            e.stopEvent();
            this.showAt([e.getPoint()[0],Ext.fly(this.curRowDom).getBottom()-1]);
            this.checkPosition();
            this.visible=true;
        }
        ,doLoadItems:function() {
            var g = this.grid,
                ri= this.curRowIdx,
                e = this.curEvt,
                r = this.curRecord;
            this.showable=false;

            Ext.each(this.grid.rowContextActions,function(actn) {
                var newItem={};
                
                if (typeof actn == 'string') {
                    this.add(actn);
                    return true;
                }
                
                Ext.apply(newItem,actn);
                
                if (typeof actn.getText === 'function')
                    newItem.text = actn.getText(g,ri,e,r);
                else
                    newItem.text = actn.text;
                
                if (typeof actn.getDisabled === 'function')
                    newItem.disabled = actn.getDisabled(g,ri,e,r);
                
                newItem.userHandler = actn.handler || actn.userHandler || Ext.emptyFn;
                newItem.handler = function(item,cEvt) {
                    item.userHandler(item,cEvt,r,g,ri);
                }
                
                actn.beforeAdd = actn.beforeAdd || function() {return true;};
                if (actn.beforeAdd(g,ri,e,r) !== false) {
                    this.add(newItem);
                    this.showable=true;
                }
            },this);
        }
        
        ,onScroll:function() {
            if (!this.visible) return;
            
            if (!this.checkRowVisible()) {
                this.hide();
                return;
            }
            this.checkPosition();
        }
        
        ,checkRowVisible:function() {
            return (Ext.fly(this.curRowDom).getBottom() > this.grid.getView().scroller.getTop()
                    &&
                    Ext.fly(this.curRowDom).getTop() < this.grid.getView().scroller.getBottom());
        }
        
        ,checkPosition:function() {
            this.el.setTop(Ext.fly(this.curRowDom).getBottom()-1);
            
            this.curRowDom.style.borderTop = '1px solid #aaa';
            this.curRowDom.style.borderBottom = '1px solid #aaa';
            
            // make both borders are there
            this.el.dom.style.borderTop = '1px solid #aaa';
            this.el.dom.style.borderBottom = '1px solid #aaa';
            
            // remove top border
            this.el.dom.style.borderTop=0;
            this.el.dom.style.backgroundColor = '#eee';
            this.curRowDom.style.backgroundColor = '#eee';
            
            // make sure its over to the left far enough
            var rightConstraint = Ext.fly(this.curRowDom).getRight()-5;
            
            if (rightConstraint > (this.el.getWidth()+5) && this.el.getRight() > rightConstraint) {
                this.el.setLeft(rightConstraint-this.el.getWidth());
            }
            
            this.el.shadow.realign(this.el.getLeft(),this.el.getTop(),this.el.getWidth(),this.el.getHeight());
            
            if (this.el.getBottom() > this.grid.getView().scroller.getBottom()) {
                this.el.setTop(Ext.fly(this.curRowDom).getTop()-this.el.getHeight()+1);
                this.el.dom.style.borderTop='1px solid #aaa';
                this.el.dom.style.borderBottom=0;
                this.el.shadow.realign(this.el.getLeft(),this.el.getTop()-3,this.el.getWidth(),this.el.getHeight());
            }
        }
        
        ,reset:function() {
            if (this.curRowDom) {
                this.curRowDom.style.backgroundColor = '';
                this.curRowDom.style.borderTop = '';
                this.curRowDom.style.borderBottom = '';
            }
            
            this.curRowIdx=null;
            this.curRecord=null;
            this.curEvt=null;
            this.curRowDom=null;
            this.visible=false;
        }
    }
} 