EMA.GridPanel = Ext.extend(Ext.grid.GridPanel, {
	remoteSort: true,
	autoRefreshInterval: 0,
	limit: 20,
	dblClickFunction: null,
	autoDblClick: false,
	initLoad: true,
    constructor: function(config) {
		this.store.isLoading = false;
		this.store.remoteSort = this.remoteSort;
		this.store.addListener('beforeload', function(s) {s.isLoading = true;});		
		this.store.addListener('load', this.onStoreLoad.createDelegate(this));	            		
		this.store.addListener('exception', 
			function(s, t, a, o, r) {
				var responseText = '';

				if (r.responseText.substring(0, 23) == '<pre class="cake-debug"' || r.responseText.substring(0, 6) == '<br />') {
					responseText = r.responseText;
					var win = new Ext.Window({
				         width: 800,
				         height: 500,
				         autoScroll: true,
				         title: 'Error',
				         html: responseText
				    });
				    win.show();
				    responseText = '';
				} else if (r.responseText != undefined) {
					var responseText = Ext.decode(r.responseText);
					if (responseText.errorMessage) {
						responseText = responseText.errorMessage
					} else {
						responseText = 'Unknown Error';
					}
				} else {	    				
					responseText = 'Unable to load data!<br/>Error type: ' + t + '<br/>Error action: ' + a;
				}
				
				if (responseText != '') {
					Ext.MessageBox.alert('Error', responseText);
				}
				
				s.isLoading = false;
			}
		);
						
		if (!this.plugins) {
			if (this.filters != undefined) {
				this.plugins = [this.filters];
			} else {
				this.plugins = null;
			}
		}
		
		if (this.filters != undefined) {
			this.pagingPlugins = [this.filters];
		} else {
			this.pagingPlugins = null
		}
		
		Ext.apply(this, {
			border: false,
			stripeRows: true,
			colModel: this.createColModel(this.gridColumns.length),
			loadMask: true,
			plugins: this.plugins,
			selModel: this.sm,
			store: this.store,
			viewConfig: this.viewConfig ? this.viewConfig : {
				emptyText: 'Nothing to display...',
				ignoreAdd: true,
				forceFit:true
			},
	        listeners: {
	            render: {
	                fn: function() {
						if (this.initLoad) {
							// Prevent double click on the nav
							this.disable();
							
							// Defer will allow the loading mask to appear, otherwise it loads too quickly
							this.store.load.defer(20,this.store,[{
								params: {
									start: 0,
									limit: this.limit
								}
							}]);
							
							/*
							 * This is to prevent dbl clicks on the nav items.
							 * First click loads the grid, second click is on the column header
							 * and the result is that the store is loaded twice.
							 */
							(function() {
								this.enable();
							}.defer(20, this));
						}
	                    
	                    this.store.gridPanel = this;
	                }
	            },
	            rowclick: {
	                fn: function(grid, rowIndex, e) { console.log(this);
	                	if (this.rowclickFunction != undefined) {
	            			this.rowclickFunction(grid, rowIndex);
	            		}
	                }
	            },
	            rowdblclick: {
	            	fn: function(grid, rowIndex, e) {
	            		this.onRowdblclick(config, grid, rowIndex, e);
	            	}	            	
	            },
	            keydown: {
	            	fn: function(e) {
	            		if (this.keydownFunction != undefined) {
	            			this.keydownFunction(e.getKey());
	            		} else if (!this.store.isLoading) {
		            		if (e.getKey() == Ext.EventObject.ENTER) {
		            			if (typeof this.dblClickFunction == 'function') {
						    		this.dblClickFunction();
								}
		            		} else if (e.getKey() == Ext.EventObject.DELETE) {
		            			config.ownerPanel.onDelete();
		            		} else if (e.getKey() == Ext.EventObject.INSERT) {
		            			config.ownerPanel.onRecordAdd();
		            		} else if (e.getKey() == Ext.EventObject.R) {
		            			this.getBottomToolbar().doRefresh();
		            		} else if (e.getKey() == Ext.EventObject.LEFT) {
		            			this.getBottomToolbar().movePrevious();
		            		} else if (e.getKey() == Ext.EventObject.RIGHT) {
		            			this.getBottomToolbar().moveNext();
		            		} else if (e.getKey() == Ext.EventObject.HOME) {
		            			this.getBottomToolbar().moveFirst();
		            		} else if (e.getKey() == Ext.EventObject.END) {
		            			this.getBottomToolbar().moveLast();
		            		}
	            		}
	            	}	            	
	            }
	        },
	        bbar: this.createPagingToolbar()
		});

		EMA.GridPanel.superclass.constructor.apply(this, arguments);
	},
	createPagingToolbar: function() {
		var bbar = new Ext.PagingToolbar({
	            store: this.store,
	            pageSize: this.limit,
				displayInfo: true,
				displayMsg: ' Result {0} - {1} of {2}',
				emptyMsg: "Nothing to display",
	            plugins: this.pagingPlugins	            
	        });
	        
		if (this.autoRefreshInterval != 0) {
			bbar.add([
				'->',
				{
					text: 'Auto Refresh: ' + (this.store.autoRefresh ? 'On' : 'Off'),
				    tooltip: 'Toggle Auto Refresh',
				    enableToggle: true,
				    scope: this,
				    pressed: false,
				    handler: function (button, state) {
				    	if (this.store.autoRefresh) {
				    		this.store.stopAutoRefresh();
				    	} else {
				    		this.store.startAutoRefresh(this.autoRefreshInterval);
				    	}
				        var text = 'Auto Refresh: ' + (this.store.autoRefresh ? 'On' : 'Off');
				        button.setText(text);
				    }
				},
				'-']);
		}
		
		bbar.add([
			'->',
			{
			    text: 'Reset Filters',
			    scope: this,
			    handler: function () {
			    	if (this.filters != undefined) {
				 		this.filters.clearFilters();
			    	}
			    }
			}, '-'
		]);
				
		return bbar;
	},
	beforeDestroy: function() {
		// call parent
		EMA.GridPanel.superclass.beforeDestroy.apply(this, arguments);
		
		if (this.store.autoRefresh) {
			this.store.stopAutoRefresh();
		}
	},
	onStoreLoad: function(store) {
		store.isLoading = false; 
		if(this.autoDblClick && store.data.length == 1) {
			this.selModel.selectRow(0);
			if (typeof this.dblClickFunction == 'function') {
	    		this.dblClickFunction();
			} else if (config.ownerPanel.editNamespace != null) {
				config.ownerPanel.onEdit();
			}
		}
	},
	createColModel: function (finish, start) {
        return new Ext.grid.ColumnModel({
		    scope: this,
            columns: this.gridColumns.slice(start || 0, finish),
            defaults: {
                sortable: true
            }
        });
    },
    reconfigureColModel: function () {
    	this.reconfigure(this.store, this.createColModel(this.gridColumns.length));
    },
    onRowdblclick: function(config, grid, rowIndex, e) {console.log(this.dblClickFunction);
    	if (typeof this.dblClickFunction == 'function') {
    		this.dblClickFunction();
		}
	}
});
