FeedPanel = function() {
   
FeedPanel.superclass.constructor.call(this, {
        id
:'feed-tree',
        region
:'west',
        title
:'Feeds',
        split
:true,
        width
: 225,
        minSize
: 175,
        maxSize
: 400,
        collapsible
: true,
        margins
:'0 0 5 5',
        cmargins
:'0 5 5 5',
        rootVisible
:false,
        lines
:false,
        autoScroll
:true,
        root
: new Ext.tree.TreeNode('My Feeds'),
        collapseFirst
:false,
        tbar
: [{
            iconCls
:'add-feed',
            text
:'Add Feed',
            handler
: this.showWindow,
            scope
: this
       
},{
            id
:'delete',
            iconCls
:'delete-icon',
            text
:'Remove',
            handler
: function(){
               
var s = this.getSelectionModel().getSelectedNode();
               
if(s){
                   
this.removeFeed(s.attributes.url);
               
}
           
},
            scope
: this
       
}]
   
});

   
this.feeds = this.root.appendChild(
       
new Ext.tree.TreeNode({
            text
:'My Feeds',
            cls
:'feeds-node',
            expanded
:true
       
})
   
);

   
this.getSelectionModel().on({
       
'beforeselect' : function(sm, node){
             
return node.isLeaf();
       
},
       
'selectionchange' : function(sm, node){
           
if(node){
               
this.fireEvent('feedselect', node.attributes);
           
}
           
this.getTopToolbar().items.get('delete').setDisabled(!node);
       
},
        scope
:this
   
});

   
this.addEvents({feedselect:true});

   
this.on('contextmenu', this.onContextMenu, this);
};

Ext.extend(FeedPanel, Ext.tree.TreePanel, {

    onContextMenu
: function(node, e){
       
if(!this.menu){ // create context menu on first right click
           
this.menu = new Ext.menu.Menu({
                id
:'feeds-ctx',
                items
: [{
                    id
:'load',
                    iconCls
:'load-icon',
                    text
:'Load Feed',
                    scope
: this,
                    handler
:function(){
                       
this.ctxNode.select();
                   
}
               
},{
                    text
:'Remove',
                    iconCls
:'delete-icon',
                    scope
: this,
                    handler
:function(){
                       
this.ctxNode.ui.removeClass('x-node-ctx');
                       
this.removeFeed(this.ctxNode.attributes.url);
                       
this.ctxNode = null;
                   
}
               
},'-',{
                    iconCls
:'add-feed',
                    text
:'Add Feed',
                    handler
: this.showWindow,
                    scope
: this
               
}]
           
});
           
this.menu.on('hide', this.onContextHide, this);
       
}
       
if(this.ctxNode){
           
this.ctxNode.ui.removeClass('x-node-ctx');
           
this.ctxNode = null;
       
}
       
if(node.isLeaf()){
           
this.ctxNode = node;
           
this.ctxNode.ui.addClass('x-node-ctx');
           
this.menu.items.get('load').setDisabled(node.isSelected());
           
this.menu.showAt(e.getXY());
       
}
   
},

    onContextHide
: function(){
       
if(this.ctxNode){
           
this.ctxNode.ui.removeClass('x-node-ctx');
           
this.ctxNode = null;
       
}
   
},

    showWindow
: function(btn){
       
if(!this.win){
           
this.win = new FeedWindow();
           
this.win.on('validfeed', this.addFeed, this);
       
}
       
this.win.show(btn);
   
},

    selectFeed
: function(url){
       
this.getNodeById(url).select();
   
},

    removeFeed
: function(url){
       
var node = this.getNodeById(url);
       
if(node){
            node
.unselect();
           
Ext.fly(node.ui.elNode).ghost('l', {
                callback
: node.remove, scope: node, duration: .4
           
});
       
}
   
},

    addFeed
: function(attrs, inactive, preventAnim){
       
var exists = this.getNodeById(attrs.url);
       
if(exists){
           
if(!inactive){
                exists
.select();
                exists
.ui.highlight();
           
}
           
return;
       
}
       
Ext.apply(attrs, {
            iconCls
: 'feed-icon',
            leaf
:true,
            cls
:'feed',
            id
: attrs.url
       
});
       
var node = new Ext.tree.TreeNode(attrs);
       
this.feeds.appendChild(node);
       
if(!inactive){
           
if(!preventAnim){
               
Ext.fly(node.ui.elNode).slideIn('l', {
                    callback
: node.select, scope: node, duration: .4
               
});
           
}else{
                node
.select();
           
}
       
}
       
return node;
   
},

   
// prevent the default context menu when you miss the node
    afterRender
: function(){
       
FeedPanel.superclass.afterRender.call(this);
       
this.el.on('contextmenu', function(e){
            e
.preventDefault();
       
});
   
}
});

Ext.reg('appfeedpanel', FeedPanel);