Ext.BLANK_IMAGE_URL = 'resources/s.gif';

var Docs  = {};
var Index = null;
var popup = null;
var mainPanel;
var maxHistory        = 100;


var emptyTitleSearch  = 'Kapitelsuche ...';
var titleTabWelcome   = 'Startseite';
var titleTabSearch    = 'Suchen ...';
var textSearching     = 'Suche gestartet ...';
var msgInvalidSearch1 = 'Invalid Search';
var msgInvalidSearch2 = 'You must enter a minimum of 2 characters to search the API';
var msgEmptySearch    = 'Use the search field above to search the Ext API for classes, properties, config options, methods and events.;'
var textNavBackward   = 'eine Seite zurück';
var textNavForward    = 'eine Seite vor';
var textNavToTop      = 'zum Anfang scrollen';
var textNavPageUp     = 'nach oben scrollen';
var textNavPageDown   = 'nach unten scrollen';
var textNavToBottom   = 'zum Ende scrollen';

function updateHistory(tab)
{
	var Bts    = tab.getTopToolbar().items;
	var BtBack = Bts.get('doc-backward'); 
    var BtFwd  = Bts.get('doc-forward');
    
    BtBack.setDisabled(!((tab.history.length)>1 && (tab.curHistory<tab.history.length-1)));
    BtFwd.setDisabled(!((tab.history.length)>1 && (tab.curHistory>0)));
}

function backwardHistory(tab)
{
    tab.curHistory = tab.curHistory>=tab.history.length-1 ? tab.history.length-1 : tab.curHistory+1;
    var docId      = tab.history[tab.curHistory];
    mainPanel.loadDoc(docId, null, true, false);
    updateHistory(tab);
}

function forwardHistory(tab)
{
    tab.curHistory = tab.curHistory<=0 ? 0 : tab.curHistory-1;
    var docId      = tab.history[tab.curHistory];
    mainPanel.loadDoc(docId, null, true, false);
    updateHistory(tab);
}

function addHistory(tab, docid)
{
	// cut newer entries
	if (tab.curHistory>0) {
        tab.history.splice(0,tab.curHistory);
	}
	
	tab.curHistory   = 0;
	
	tab.history.unshift(docid);
	tab.history.splice(maxHistory,10); // cut on more tahn maxHistorie
	updateHistory(tab);
}

function ShowText(id) {
	
    var parent = Ext.get("A"+id);
	var El     = Ext.get(id);

	var Next = parent.next();
	
	if (!Next) {
		El.position('relative');
	    El.insertAfter(parent);
	}
	
    // show or hide
    El.enableDisplayMode();
    if (El.isDisplayed()) {
        El.slideOut('t',{duration: .2});
    	El.setDisplayed(false);
    } else {
        El.slideIn('t',{duration: .2});
    }
}

function ShowPopup(id) {
    if (!popup) {
    	popup = new Ext.Window({
                id           : 'popuphelp',
                layout       : 'fit',
                width       : 500,
                xheight      : 300,
                closeAction  :'hide',
                plain        : true,
                autoLoad     : {url : 'show_popup.php?doc='+id}
            });

    } else {
        popup.getUpdater().update({url : 'show_popup.php?doc='+id});
    }
    popup.show();
}

IndexPanel = function() {
	IndexPanel.superclass.constructor.call(this, {
        id:'index-tree',
        region:'west',
        split:true,
        width: 280,
        minSize: 175,
        maxSize: 500,
        collapsible: true,
        margins:'0 0 5 5',
        cmargins:'0 0 0 0',
        rootVisible:false,
        lines:false,
        autoScroll:true,
        animCollapse:false,
        animate: false,
        collapseMode:'mini',
        loader: new Ext.tree.TreeLoader({
			preloadChildren: true,
			clearOnLoad: false
		}),
        root: new Ext.tree.AsyncTreeNode({
            text:Docs.title,
            id:'root',
            sid:'root',
            showIt: true,
            expanded:true,
            children:[Docs.classData]
         }),
        collapseFirst:false
    });
    // no longer needed!
    //new Ext.tree.TreeSorter(this, {folderSort:true,leafAttr:'isClass'});

    this.getSelectionModel().on('beforeselect', function(sm, node){
        return node.isLeaf();
    });
};

Ext.extend(IndexPanel, Ext.tree.TreePanel, {
    selectDoc : function(docid) {
        if (docid) {
            var parts = docid.split('.');

            this.selectPath('/root/'+parts.join('/'),'sid');
            //this.selectPath('/root/docs/orbit/intro/'+docid);
        }
    }
});


DocPanel = Ext.extend(Ext.Panel, {
    closable: true,
    autoScroll:true,

    initComponent : function(){
        DocPanel.superclass.initComponent.call(this);
    },

    scrollToMember : function(member){
        var el = Ext.fly(member);
        if(el){
            var top = (el.getOffsetsTo(this.body)[1]) + this.body.dom.scrollTop;
            this.body.scrollTo('top', top-25, {duration:.75, callback: this.hlMember.createDelegate(this, [member])});
        }
    },

	scrollToSection : function(id){
		var el = Ext.getDom(id);
		if(el){
			var top = (Ext.fly(el).getOffsetsTo(this.body)[1]) + this.body.dom.scrollTop;
			this.body.scrollTo('top', top-25, {duration:.5, callback: function(){
                Ext.fly(el).frame();
            }});
        }
	},

    scrollToTop : function(){
        this.body.scrollTo('top', 0, {duration:.5, callback: function(){}});
    },
    
    scrollToBottom : function(){
    	var d         = this.body.dom;
        var scrollTop = d.scrollHeight - d.offsetHeight;
        this.body.scrollTo('top', scrollTop, {duration:.75, callback: function() {}});
    	return;
    },
    scrollPageDown : function(){
        var height = this.body.getComputedHeight()-50;
        this.body.scroll('down', height, {duration:.25}); 
    },
    scrollPageUp : function(){
        var height = this.body.getComputedHeight()-50;
        this.body.scroll('up', height, {duration:.25}); 
    },
    hlMember : function(member){
        var el = Ext.fly(this.docid + '-' + member);
        if(el){
            el.up('tr').highlight('#cadaf9');
        }
    }
});


MainPanel = function(){
	
	this.searchStore = new Ext.data.Store({
        url: 'search_docs.php',
        reader: new Ext.data.JsonReader({
	            root: 'data'
	        }, 
			['cls', 'member', 'type', 'doc']
		),
		baseParams: {},
        listeners: {
            'beforeload' : function(){
                this.baseParams.qt = Ext.getCmp('search-type').getValue();
            }
        }
    }); 
    
	this.findByDocId = function(docid) {
        var found = null;
        this.items.each(function(item) {
            if (item.docId && item.docId === docid) {
                found = item;
                return false;
            }
            return true;
        });
        return found;
    };
    
    MainPanel.superclass.constructor.call(this, {
        id:'doc-body',
        region:'center',
        margins:'0 5 5 0',
        minTabWidth: 135,
        plugins: new Ext.ux.TabCloseMenu(),
        enableTabScroll: true,
        activeTab: 0,

        items: [/*{
            id:'search-panel',
            title: titleTabSearch,
            autoLoad: {url: 'create_doc.php?doc=docs.search', callback: this.initSearch, scope: this},
            iconCls:'icon-home',
            autoScroll: true,
            tbar: [
                'Suchbegriff: ', ' ',
                new Ext.ux.SelectBox({
                    listClass:'x-combo-list-small',
                    width:90,
                    value:'Beginnt mit',
                    id:'search-type',
                    store: new Ext.data.SimpleStore({
                        fields: ['text'],
                        expandData: true,
                        data : ['beginnt mit', 'ended auf', 'beinhaltet']
                    }),
                    displayField: 'text'
                }), ' ',
                new Ext.app.SearchField({
                    width:240,
                    store: this.searchStore,
                    paramName: 'q'
                })
            ]
        },*/{
            closable: false,
            id:'welcome',
            docId: 'docs.welcome',
            title: titleTabWelcome,
            autoLoad: {url: 'create_doc.php?doc=docs.welcome', scope: this},
            iconCls:'icon-home',
            autoScroll: true
        }]
    });
};


Ext.extend(MainPanel, Ext.TabPanel, {

    initEvents : function(){
        MainPanel.superclass.initEvents.call(this);
        this.body.on('click', this.onClick, this);
    },

    onClick: function(e, target){
        if (target = e.getTarget('a:not(.exi)', 3)){
        	// call links within document
            var DocId = Ext.fly(target).getAttributeNS('ext', 'docid');
            // always exec js scripts
            if (target.href.search(/javascript:.+/)!=-1) {
            	return;
            }
            e.stopEvent();
            if(DocId){
                var member = Ext.fly(target).getAttributeNS('ext', 'member');
                this.loadDoc(DocId, member, true, true);
            }else if(target.className == 'inner-link'){
                this.getActiveTab().scrollToSection(target.href.split('#')[1]);
            }else{
            	if (target.href.search(/mailto:.+/)!=-1) {
            	    return;
            	}

                window.open(target.href);
            }
        }else if(target = e.getTarget('.micon', 2)){
            e.stopEvent();
            var tr = Ext.fly(target.parentNode);
            if(tr.hasClass('expandable')){
                tr.toggleClass('expanded');
            }
        }
    },
    findDoc : function(docid, inarr) {
    	var Found = false;
    	Ext.each(inarr, function(item) {//http://localhost/public/orbit/js/docs/index.php?doc=ref_wf_sintro
    		if ((item.docid===docid)||(item.sid.toLowerCase()===docid.toLowerCase())) {
    			Found = item;
    			return false;
    		} else {
    			if (item.children && (item.children instanceof Array) && (item.children.length>0)) {
    				Found = this.findDoc(docid,item.children);
    				if (Found!==false) {
    					return false;
    				}
    			}
    		}
    	}, this);
    	return Found;
    },
    loadDoc : function(docid, member, usetab, addhistory) {
    	// use this doc
    	if (docid=='.') {
    		if (member) {
                tab = this.getActiveTab();
    		    tab.scrollToMember(member);
    		}
    		return;
    	}
    	
        var autoLoad;
        var Doc;
        var isContext = docid.charAt(0)=='#';
        var tab       = this.findByDocId(docid);
        var Member    = member ? "&member="+member : '';

        if (isContext) {
        	Context  = docid.substr(1);
            Doc      = {text: ""};
            autoLoad = {url: 'create_doc.php?context='+Context+Member, scope: this};
        } else {
            Doc   = this.findDoc(docid, Docs.classData);
            if (!Doc) {
                alert("Dokument ("+docid+") wurde nicht gefunden");
                return;
            }
        
            docid    = Doc['docid'];
            autoLoad = {url: 'create_doc.php?doc='+docid+Member, scope: this};
        }
        
        if (usetab) {
        	tab = this.getActiveTab();
            if (tab) {
            	tab.docId = docid;
            	tab.setTitle(Doc['text']);
            	autoLoad.callback = function() {
                    if (member) {
                        tab.scrollToMember(member);
                    }
                }
            	tab.getUpdater().update(autoLoad);
            	
            	Index.selectDoc(tab.docId); 
            	if (addhistory) {
            	    addHistory(tab, tab.docId);
            	}
            }
        }
        
        if (tab) {
            this.setActiveTab(tab);
            autoLoad.callback = function(){
                if (member) {
                    tab.scrollToMember(member);
                }
            }
            tab.getUpdater().update(autoLoad);
        } else {
        	autoLoad.callback = function(el, success, response, options){
                el.dom.innerHTML = response.responseText; // compile document
                var hTab         = this.getActiveTab();
                var RegDocTitle  = /doctitle\((.*?)\)/;
                var RegDocId     = /docid\((.*?)\)/;
                
                RegDocTitle.exec(response.responseText);
                if (RegExp.$1!="") {
                    hTab.setTitle(RegExp.$1);
                }
                RegDocId.exec(response.responseText);
                if (RegExp.$1!="") {
                    Index.selectDoc(RegExp.$1);
                }

                if (member) {
                	hTab.scrollToMember(member);
                }
            }
            var p = this.add(new DocPanel({
                // id is autogenerated!
                title      : Doc['text'],
                docId      : docid,
                history    : [docid],
                curHistory : 0,
                autoLoad   : autoLoad,
                iconCls    : Docs.icons[docid],
                tbar       : [{
                        id     : 'doc-backward',
                        iconCls: 'icon-doc-backward',
                        disabled : true,
                        tooltip: textNavBackward,
                        handler: function(){ backwardHistory(p); }
                    },{
                        id     : 'doc-forward',
                        iconCls: 'icon-doc-forward',
                        disabled : true,
                        tooltip: textNavForward,
                        handler: function(){ forwardHistory(p); }
                    },'->', {
                    	id     : 'doc-top',
                        iconCls: 'icon-doc-top',
                        tooltip: textNavToTop,
                        handler: function(){ p.scrollToTop(); }
                    }, {
                        id     : 'doc-up',
                        iconCls: 'icon-doc-up',
                        tooltip: textNavPageUp,
                        handler: function(){ p.scrollPageUp(); }
                    }, {
                        id     : 'doc-down',
                        iconCls: 'icon-doc-down',
                        tooltip: textNavPageDown,
                        handler: function(){ p.scrollPageDown(); }
                    }, {
                        id     : 'doc-bottom',
                        iconCls: 'icon-doc-bottom',
                        tooltip: textNavToBottom,
                        handler: function(){ p.scrollToBottom(); }
                    }
                ],
                retainFocus : function() {
                    if (this.focusEl) {
                        this.doRetainFocus.defer(50, this);
                    }
                },
                // private
                doRetainFocus : function() {
                    this.focusEl.focus();
                }
            }));
            this.setActiveTab(p);
        }
    },
	
	initSearch : function(){
		// Custom rendering Template for the View
	    var resultTpl = new Ext.XTemplate(
	        '<tpl for=".">',
	        '<div class="search-item">',
	            '<a class="member" ext:cls="{cls}" ext:member="{member}" href="output/{cls}.html">',
				'<img src="resources/s.gif" class="item-icon icon-{type}"/>{member}',
				'</a> ',
				'<a class="cls" ext:cls="{cls}" href="output/{cls}.html">{cls}</a>',
	            '<p>{doc}</p>',
	        '</div></tpl>'
	    );
		
		var p = new Ext.DataView({
            applyTo       : 'search',
			tpl           : resultTpl,
			loadingText   : textSearching,
            store         : this.searchStore,
            itemSelector  : 'div.search-item',
			emptyText     : '<h3>'+msgEmptySearch+'</h3>'
        });
	},
	
	doSearch : function(e){
		var k = e.getKey();
		if(!e.isSpecialKey()){
			var text = e.target.value;
			if(!text){
				this.searchStore.baseParams.q = '';
				this.searchStore.removeAll();
			}else{
				this.searchStore.baseParams.q = text;
				this.searchStore.reload();
			}
		}
	}
});


Ext.onReady(function(){

    Ext.QuickTips.init();

    Index     = new IndexPanel();
    mainPanel = new MainPanel();

    Index.on('click', function(node, e){
         if(node.isLeaf()){
            e.stopEvent();
            mainPanel.loadDoc(node.attributes.docid, null, false, false);
         }
    });

    mainPanel.on('tabchange', function(tp, tab){
    	Index.selectDoc(tab.docId); 
    });

    var hd = new Ext.Panel({
        border: false,
        layout:'anchor',
        region:'north',
        cls: 'docs-header',
        height:90,
        items: [{
            xtype:'box',
            el:'header',
            border:false,
            anchor: 'none -25'
        },
        new Ext.Toolbar({
            cls:'top-toolbar',
            items:[ ' ',
			new Ext.form.TextField({
				width: 200,
				emptyText: emptyTitleSearch,
				listeners:{
					render: function(f){
						f.el.on('keydown', filterTree, f, {buffer: 350});
					}
				}
			}), ' ', ' ',
			{
                iconCls: 'icon-expand-all',
				tooltip: 'Alles aufklappen',
                handler: function(){ Index.root.expand(true); }
            }, '-', {
                iconCls: 'icon-collapse-all',
                tooltip: 'Alles zuklappen',
                handler: function(){ Index.root.collapse(true); }
            }]
        })]
    })

    var viewport = new Ext.Viewport({
        layout:'border',
        items:[ hd, Index, mainPanel ]
    });

    Index.expandPath('/root/docs','sid');

    // allow for link in
    var page = window.location.href.split('?')[1];
    if( page) {
        var ps  = Ext.urlDecode(page);
        if (ps['doc']) {
            mainPanel.loadDoc(ps['doc'], ps['member'], false, false);
        } else {
        	//mainPanel.loadDoc('docs.welcome', null, false, false);
        }
    } else {
    	//mainPanel.loadDoc('docs.welcome', null, false, false);
    }
    
    viewport.doLayout();
	
	setTimeout(function(){
        Ext.get('loading').remove();
        Ext.get('loading-mask').fadeOut({remove:true});
    }, 250);
	
	var filter = new Ext.tree.TreeFilter(Index, {
		clearBlank: true,
		autoClear: true
	});
	var hiddenPkgs = [];
	
	function bubbleDoc(n) {
		n.bubble(function (n) {
			if (n.attributes.showIt && (n.attributes.docid!=this.attributes.docid)) {
				return false;
			}
			n.attributes.showIt = true;
			return true;
		});
	}
	
	function filterTree(e){
		var text = e.target.value;
		Ext.each(hiddenPkgs, function(n){
			n.ui.show();
		});
		if(!text){
			filter.clear();
			return;
		}
		Index.expandAll();
		
		// no search text?
		if (text==emptyTitleSearch) {
			return;
		}
		var re = new RegExp(Ext.escapeRe(text), 'i');
		
		filter.filterBy(function(n){
			var showIt          = re.test(n.text);
            n.attributes.showIt = showIt || n.attributes.sid == 'docs';
            
			if (n.attributes.isDoc) {
				if (showIt) {
					bubbleDoc(n);
				}
				return showIt;
			} else {
				n.attributes.showIt = false;
				return true;
			}
		});
		
		// hide empty packages that weren't filtered
		hiddenPkgs = [];
		Index.root.cascade(function(n){
			if(!n.attributes.isDoc && (!n.attributes.showIt)) { //n.ui.ctNode.offsetHeight < 3){
				n.ui.hide();
				hiddenPkgs.push(n);
			}
		});
	}
	
	var nav = new Ext.KeyNav(document, {
        "pageDown" : function(e){
        	var Tab = mainPanel.getActiveTab();
            if (Tab && Tab.scrollPageDown) {
                Tab.scrollPageDown();
            }
        },
        "pageUp" : function(e){
            var Tab = mainPanel.getActiveTab();
            if (Tab && Tab.scrollPageDown) {
                Tab.scrollPageUp();
            }
        },
        "home" : function(e){
            var Tab = mainPanel.getActiveTab();
            if (Tab && Tab.scrollPageDown) {
                Tab.scrollToTop();
            }
        },
        "end" : function(e){
            var Tab = mainPanel.getActiveTab();
            if (Tab && Tab.scrollPageDown) {
                Tab.scrollToBottom();
            }
        },
        scope : this
    });
});


Ext.app.SearchField = Ext.extend(Ext.form.TwinTriggerField, {
    initComponent : function(){
        if(!this.store.baseParams){
			this.store.baseParams = {};
		}
		Ext.app.SearchField.superclass.initComponent.call(this);
		this.on('specialkey', function(f, e){
            if(e.getKey() == e.ENTER){
                this.onTrigger2Click();
            }
        }, this);
    },

    validationEvent:false,
    validateOnBlur:false,
    trigger1Class:'x-form-clear-trigger',
    trigger2Class:'x-form-search-trigger',
    hideTrigger1:true,
    width:180,
    hasSearch : false,
    paramName : 'query',

    onTrigger1Click : function(){
        if(this.hasSearch){
            this.store.baseParams[this.paramName] = '';
			this.store.removeAll();
			this.el.dom.value = '';
            this.triggers[0].hide();
            this.hasSearch = false;
			this.focus();
			Ext.fly('content').show();
        }
    },

    onTrigger2Click : function(){
        var v = this.getRawValue();
        if(v.length < 1){
            this.onTrigger1Click();
            return;
        }
		if(v.length < 2){
			Ext.Msg.alert(msgInvalidSearch1, msgInvalidSearch2);
			return;
		}
        Ext.fly('content').hide();
		this.store.baseParams[this.paramName] = v;
        var o = {start: 0};
        this.store.reload({params:o});
        this.hasSearch = true;
        this.triggers[0].show();
		this.focus();
    }
});


/**
 * Makes a ComboBox more closely mimic an HTML SELECT.  Supports clicking and dragging
 * through the list, with item selection occurring when the mouse button is released.
 * When used will automatically set {@link #editable} to false and call {@link Ext.Element#unselectable}
 * on inner elements.  Re-enabling editable after calling this will NOT work.
 *
 * @author Corey Gilmore
 * http://extjs.com/forum/showthread.php?t=6392
 *
 * @history 2007-07-08 jvs
 * Slight mods for Ext 2.0
 */
Ext.ux.SelectBox = function(config){
	this.searchResetDelay = 1000;
	config = config || {};
	config = Ext.apply(config || {}, {
		editable: false,
		forceSelection: true,
		rowHeight: false,
		lastSearchTerm: false,
        triggerAction: 'all',
        mode: 'local'
    });

	Ext.ux.SelectBox.superclass.constructor.apply(this, arguments);

	this.lastSelectedIndex = this.selectedIndex || 0;
};

Ext.extend(Ext.ux.SelectBox, Ext.form.ComboBox, {
    lazyInit: false,
	initEvents : function(){
		Ext.ux.SelectBox.superclass.initEvents.apply(this, arguments);
		// you need to use keypress to capture upper/lower case and shift+key, but it doesn't work in IE
		this.el.on('keydown', this.keySearch, this, true);
		this.cshTask = new Ext.util.DelayedTask(this.clearSearchHistory, this);
	},

	keySearch : function(e, target, options) {
		var raw = e.getKey();
		var key = String.fromCharCode(raw);
		var startIndex = 0;

		if( !this.store.getCount() ) {
			return;
		}

		switch(raw) {
			case Ext.EventObject.HOME:
				e.stopEvent();
				this.selectFirst();
				return;

			case Ext.EventObject.END:
				e.stopEvent();
				this.selectLast();
				return;

			case Ext.EventObject.PAGEDOWN:
				this.selectNextPage();
				e.stopEvent();
				return;

			case Ext.EventObject.PAGEUP:
				this.selectPrevPage();
				e.stopEvent();
				return;
		}

		// skip special keys other than the shift key
		if( (e.hasModifier() && !e.shiftKey) || e.isNavKeyPress() || e.isSpecialKey() ) {
			return;
		}
		if( this.lastSearchTerm == key ) {
			startIndex = this.lastSelectedIndex;
		}
		this.search(this.displayField, key, startIndex);
		this.cshTask.delay(this.searchResetDelay);
	},

	onRender : function(ct, position) {
		this.store.on('load', this.calcRowsPerPage, this);
		Ext.ux.SelectBox.superclass.onRender.apply(this, arguments);
		if( this.mode == 'local' ) {
			this.calcRowsPerPage();
		}
	},

	onSelect : function(record, index, skipCollapse){
		if(this.fireEvent('beforeselect', this, record, index) !== false){
			this.setValue(record.data[this.valueField || this.displayField]);
			if( !skipCollapse ) {
				this.collapse();
			}
			this.lastSelectedIndex = index + 1;
			this.fireEvent('select', this, record, index);
		}
	},

	render : function(ct) {
		Ext.ux.SelectBox.superclass.render.apply(this, arguments);
		if( Ext.isSafari ) {
			this.el.swallowEvent('mousedown', true);
		}
		this.el.unselectable();
		this.innerList.unselectable();
		this.trigger.unselectable();
		this.innerList.on('mouseup', function(e, target, options) {
			if( target.id && target.id == this.innerList.id ) {
				return;
			}
			this.onViewClick();
		}, this);

		this.innerList.on('mouseover', function(e, target, options) {
			if( target.id && target.id == this.innerList.id ) {
				return;
			}
			this.lastSelectedIndex = this.view.getSelectedIndexes()[0] + 1;
			this.cshTask.delay(this.searchResetDelay);
		}, this);

		this.trigger.un('click', this.onTriggerClick, this);
		this.trigger.on('mousedown', function(e, target, options) {
			e.preventDefault();
			this.onTriggerClick();
		}, this);

		this.on('collapse', function(e, target, options) {
			Ext.getDoc().un('mouseup', this.collapseIf, this);
		}, this, true);

		this.on('expand', function(e, target, options) {
			Ext.getDoc().on('mouseup', this.collapseIf, this);
		}, this, true);
	},

	clearSearchHistory : function() {
		this.lastSelectedIndex = 0;
		this.lastSearchTerm = false;
	},

	selectFirst : function() {
		this.focusAndSelect(this.store.data.first());
	},

	selectLast : function() {
		this.focusAndSelect(this.store.data.last());
	},

	selectPrevPage : function() {
		if( !this.rowHeight ) {
			return;
		}
		var index = Math.max(this.selectedIndex-this.rowsPerPage, 0);
		this.focusAndSelect(this.store.getAt(index));
	},

	selectNextPage : function() {
		if( !this.rowHeight ) {
			return;
		}
		var index = Math.min(this.selectedIndex+this.rowsPerPage, this.store.getCount() - 1);
		this.focusAndSelect(this.store.getAt(index));
	},

	search : function(field, value, startIndex) {
		field = field || this.displayField;
		this.lastSearchTerm = value;
		var index = this.store.find.apply(this.store, arguments);
		if( index !== -1 ) {
			this.focusAndSelect(index);
		}
	},

	focusAndSelect : function(record) {
		var index = typeof record === 'number' ? record : this.store.indexOf(record);
		this.select(index, this.isExpanded());
		this.onSelect(this.store.getAt(record), index, this.isExpanded());
	},

	calcRowsPerPage : function() {
		if( this.store.getCount() ) {
			this.rowHeight = Ext.fly(this.view.getNode(0)).getHeight();
			this.rowsPerPage = this.maxHeight / this.rowHeight;
		} else {
			this.rowHeight = false;
		}
	}

});

