/**
 * Copyright (c) 2008-2011 The Open Planning Project
 * 
 * Published under the BSD license.
 * See https://github.com/opengeo/gxp/raw/master/license.txt for the full text
 * of the license.
 */

/**
 * @requires plugins/Tool.js
 */

/** api: (define)
 *  module = gxp.plugins
 *  class = GridWmsFeatureInfo
 */

/** api: (extends)
 *  plugins/Tool.js
 */
Ext.namespace("gxp.plugins");

/** api: constructor
 *  .. class:: GridWmsFeatureInfo(config)
 *
 *    This plugins provides an action which, when active, will issue a
 *    GetFeatureInfo request to the WMS of all layers on the map. The output
 *    will be displayed in a popup.
 */  

GPOpenLayers.Control.Click = GPOpenLayers.Class(GPOpenLayers.Control, {                
	defaultHandlerOptions: {
		'single': true,
		'double': false,
		'pixelTolerance': 0,
		'stopSingle': false,
		'stopDouble': false
	},

	initialize: function(options) {
		this.handlerOptions = GPOpenLayers.Util.extend(
			{}, this.defaultHandlerOptions
		);
		GPOpenLayers.Control.prototype.initialize.apply(
			this, arguments
		); 
		this.handler = new GPOpenLayers.Handler.Click(
			this, {
				'click': this.trigger
			}, this.handlerOptions
		);
	}, 

	trigger: function(e) {
		var lonlat = this.map.getLonLatFromPixel(e.xy);
		lonlat.transform(this.map.projection, "EPSG:4326");
		if ((lonlat.lon)&&(lonlat.lat)){
			$('#dialog-monitor').remove();
			var title = 'Метеоусловия в указанной точке';
			$('body').append('<div id="dialog-monitor" title="'+title+'" style="padding:10px;"></div>');
			var positionX = pageX-670;
			if (pageX < $(window).width()*0.4)
				positionX = pageX+10;
			if (positionX<0)
				positionX = 0;
			var positionY=pageY-255;
			if (positionY<0)
				positionY = 0;
			$('#dialog-monitor').dialog({
				minWidth:650,		
				minHeight: 240,
				position: [positionX,positionY],
				modal:false,
				resizable:false,
				draggable:true,
				open: function(){
					$('#dialog-monitor').html('<div id="dialog-monitor-display" style="width:100%; max-height:600px; overflow:auto;"><div class="portlet-font portlet-icon icon-loading-bar-small" style="width:100px;height:15px;margin:0 auto;">Загрузка информации об объекте</div></div>');
					$('#dialog-monitor-display').makeMonitor({
					  'resourceId':'RU_RIHMI-WDC_1172',												
					  'm4311':lonlat.lat,
					  'm4312':lonlat.lon,
					  'name':title
					});
				}
			});
		}
	}

}); 
 
gxp.plugins.WeatherInfo = Ext.extend(gxp.plugins.Tool, {
	ptype: "gxp_gridwmsgetweatherinfo",
	outputTarget: "map",
	popupCache: null,
    constructor: function(config) {
        gxp.plugins.Measure.superclass.constructor.apply(this, arguments);
    },
    destroy: function() {
        this.button = null;
        gxp.plugins.Measure.superclass.destroy.apply(this, arguments);
    },
    createWeatherControl: function(handlerType) {
        var weatherControl = new GPOpenLayers.Control.Click ();
		return weatherControl;
    },
	
	addActions: function() {
		this.activeIndex = 0;
        this.button = new GeoExt.Action({
			id: "weatherInfoButton",
			iconCls: "icon-weather-maptool",
			tooltip: locale.tips.weatherTool,							
			toggleGroup: this.toggleGroup,
			group: this.toggleGroup,
			map: this.target.mapPanel.map,
			control: this.createWeatherControl(
				GPOpenLayers.Handler.Path
			)
		});

        return gxp.plugins.WeatherInfo.superclass.addActions.apply(this, [this.button]);
	
		/*this.button = new Ext.Button({
            iconCls: "icon-weather-maptool",
			id: "weatherInfoButton",
            tooltip: locale.tips.weatherTool,
            enableToggle: true,
            toggleGroup: this.toggleGroup,
            allowDepress: true,
            toggleHandler: function(button, pressed) {
			  for (var i = 0, len = info.controls.length; i < len; i++){
				  if (pressed) {
					 info.controls[i].activate() 
				  } else {
					 info.controls[i].deactivate() 
				  }
			  }
			  if (pressed) { this.activate() } else { this.deactivate() }
			}
        });		
		
		return gxp.plugins.WeatherInfo.superclass.addActions.apply(this, [this.button]);*/
	}	
});

Ext.preg(gxp.plugins.WeatherInfo.prototype.ptype, gxp.plugins.WeatherInfo); 
 
var globalFeatureSelectedStorage = {};
/*var codesForAnalyticsPlace = ['m4200','m4311','m4312'];
var codesForAnalyticsTime = ['m4400'];
var resourcesWithStationsArray = {'ru_rihmi-wdc_1172':'ru_rihmi-wdc_2667'};*/

gxp.plugins.GridWmsFeatureInfo = Ext.extend(gxp.plugins.WMSGetFeatureInfo, {
    
    /** api: ptype = gxp_gridwmsgetfeatureinfo */
    ptype: "gxp_gridwmsgetfeatureinfo",
    
    /** api: config[outputTarget]
     *  ``String`` Popups created by this tool are added to the map by default.
     */
    outputTarget: "map",

    /** private: property[popupCache]
     *  ``Object``
     */
    popupCache: null,
	
	
    /** api: config[vendorParams]
     *  ``Object``
     *  Optional object with properties to be serialized as vendor specific
     *  parameters in the requests (e.g. {buffer: 10}).
     */
    
    /** api: config[paramsFromLayer]
     *  ``Array`` List of param names that should be taken from the layer and
     *  added to the GetFeatureInfo request (e.g. ["CQL_FILTER"]).
     */

    addPointerToMap: function(){
      var el = this.target.mapPanel.map.div
      var classes = el.getAttribute('class').split(' ')
      classes.push('helpPointer')
      el.setAttribute('class',classes.join(' '))
    },

    removePointerFromMap: function(){
      var el = this.target.mapPanel.map.div
      var classes = el.getAttribute('class').split(' ')
      var index = classes.indexOf('helpPointer')
      classes.splice(index,1)
      el.setAttribute('class',classes.join(' '))
    },

    rssTooltipOn: function(){
      //remove nasty global var
      rssVar.show = 1
    },

    rssTooltipOff: function(){
      //remove nasty global var
      rssVar.show = 0
    },

    /** api: method[addActions]
     */
    addActions: function() {
		this.popupCache = {};

		 this.on('activate', this.addPointerToMap, this)
		 this.on('deactivate', this.removePointerFromMap, this)

		 this.on('activate', this.rssTooltipOn, this)
		 this.on('deactivate', this.rssTooltipOff, this)
		
					var actions = gxp.plugins.Tool.prototype.addActions.call(this, [{
						text: "",
						tooltip: locale.tips.infoTool,
						iconCls: "gxp-icon-getfeatureinfo",
						toggleGroup: this.toggleGroup,
						enableToggle: true,
						allowDepress: true,
						scope:this,
						toggleHandler: function(button, pressed) {
						  for (var i = 0, len = info.controls.length; i < len; i++){
							  if (pressed) {
								 info.controls[i].activate() 
							  } else {
								 info.controls[i].deactivate() 
							  }
						  }
						  if (pressed) { this.activate() } else { this.deactivate() }
						}

					}]);
					var infoButton = this.actions[0].items[0];

					var info = {controls: []};
					var updateInfo = function() {
						var queryableLayers = this.target.mapPanel.layers.queryBy(function(x){
							return x.get("queryable");
						});
			
						var map = this.target.mapPanel.map;
						var control;
						for (var i = 0, len = info.controls.length; i < len; i++){
							control = info.controls[i];
							control.deactivate();  // TODO: remove when http://trac.GPOpenLayers.org/ticket/2130 is closed
							control.destroy();
						}

						info.controls = [];
						queryableLayers.each(function(x){
							var layer = x.getLayer();

							var vendorParams = Ext.apply({}, this.vendorParams), param;
							if (this.layerParams) {
								for (var i=this.layerParams.length-1; i>=0; --i) {
									param = this.layerParams[i].toUpperCase();
									vendorParams[param] = layer.params[param];
								}
							}
							var control = new GPOpenLayers.Control.WMSGetFeatureInfo({
								url: layer.url,
								queryVisible: true,
								layers: [layer],
								infoFormat: "text/plain",
								vendorParams: vendorParams,
								eventListeners: {
									getfeatureinfo: function(evt) {
										var match = evt.text.match(/<body[^>]*>([\s\S]*)<\/body>/);
										if (match && !match[1].match(/^\s*$/)) {

											this.displayPopup(
												evt, (x.get("title") || x.get("name")), match[1], false
											);
										} else {
											if(evt.text.match(/no.*features.*found/)){
												return;
										}
										
										var lines = evt.text.split("\n");
										var ret = "";
										var dataArray = [];
										var j = 0;
										var group = 0;
										var wasGroup = false;
										var superGroup = "";
										var needPlusick = false;
										
										for(i=0;i<lines.length;i++){
											var keyVal = lines[i].match(/([^=]+)=(.*)/);
											if(keyVal){
												keyVal[1] = keyVal[1].replace(/^\s+/g, "").replace(/\s+$/g, "");
												keyVal[2] = keyVal[2].replace(/^\s+/g, "").replace(/\s+$/g, "");
												dataArray[j] = [keyVal[1], keyVal[2], superGroup, group];
												maxGroup = group;
												j++;
												ret = ret + "key: " + lines[i][0] + ", val: " + lines[i][1] + "\n";
												wasGroup = false;
												if(group>1){
													needPlusick = true;
												}
											} else {
												if(!wasGroup){
													wasGroup = true;
													group++;
												}
												var supGrTry = lines[i].match(/FeatureType\s+[\"\']?([^\"\']+)[\"\']?/);
												if(supGrTry){
													if(superGroup != supGrTry[1]){
														group=1;
														if(superGroup!="")
															needPlusick = true;
													}
													superGroup = supGrTry[1];
												}
											}
										}
                                
                                // translate data
                                var layerNames = [];
                                var fieldNames = [];
                                for(var i=0;i<dataArray.length;i++){
                                    dataArray[i][2] = dataArray[i][2].toUpperCase();
                                    dataArray[i][0] = dataArray[i][0].toUpperCase();
                                    layerNames[i] = dataArray[i][2];
                                    fieldNames[i] = dataArray[i][0];
                                }
                                var translatedLayerNames = Gispro.Utils.translateSymbols("layer", layerNames);
                                var metadataFieldNames = Gispro.Utils.getMetaData("field", fieldNames);
                                // transform two last columns to one for grouping
                                
                                for(i=0;i<dataArray.length;i++){
                                    dataArray[i] = [
                                        metadataFieldNames[dataArray[i][0]]["Заголовок элемента"]?
                                            metadataFieldNames[dataArray[i][0]]["Заголовок элемента"]:
                                            dataArray[i][0], 
                                        (dataArray[i][1]!="null"?dataArray[i][1]:""), 
                                        dataArray[i][0],
                                        translatedLayerNames[dataArray[i][2]],
                                        dataArray[i][3],
                                        translatedLayerNames[dataArray[i][2]] + " grouping " + dataArray[i][3],
                                        metadataFieldNames[dataArray[i][0]]
                                    ];
                                };
								
								var globalFeatureSelected = {
									resourceId:'',
									lat:'',
									lon:'',
									layername: '',
									data:[]
								};

								try{
									globalFeatureSelected.resourceId = layer.url;
									globalFeatureSelected.resourceId = globalFeatureSelected.resourceId.substring(globalFeatureSelected.resourceId.indexOf('RU_'));
									globalFeatureSelected.resourceId = globalFeatureSelected.resourceId.substring(0,globalFeatureSelected.resourceId.indexOf('/'));
									globalFeatureSelected.layername = layer.name;
									for (var i = 0; i<dataArray.length; i++){
										//if ((dataArray[i][2].toLowerCase().indexOf('m') == 0)||(dataArray[i][2].toLowerCase().indexOf('p') == 0))
											globalFeatureSelected.data[dataArray[i][2].toLowerCase()] = dataArray[i][1];
										/*var found = false;
										for (var j in codesForAnalyticsPlace)
											if (dataArray[i][2].toLowerCase() == codesForAnalyticsPlace[j]){
												globalFeatureSelected.data[codesForAnalyticsPlace[j]] = dataArray[i][1];
												found = true;
											}	
										if (!(found))
											for (var j in codesForAnalyticsTime)
												if (dataArray[i][2].toLowerCase() == codesForAnalyticsTime[j]){
													globalFeatureSelected.data[codesForAnalyticsTime[j]] = dataArray[i][1];
													found = true;
												}		
										if (!(found)){
											if (dataArray[i][2].toLowerCase().indexOf('p') == 0){
												globalFeatureSelected.data[dataArray[i][2].toLowerCase()] = dataArray[i][1];
												found = true;
											}	
										}*/											
									}
									var tmp = $('.mousePos.olControlNoSelect').text();
									globalFeatureSelected.lon = tmp.substring(tmp.indexOf('X: ')+3,tmp.indexOf(', Y:'));
									globalFeatureSelected.lat = tmp.substring(tmp.indexOf(', Y:')+4);
									globalFeatureSelected.data['m4311'] = globalFeatureSelected.lat;
									globalFeatureSelected.data['m4312'] = globalFeatureSelected.lon;
								}catch(e){
									console.log(e.message);
								}
                                
                                // ext grid
                                var myReader = new Ext.data.ArrayReader({}, [
                                    {name: 'FieldTranslated'},
                                    {name: 'Value'},
                                    {name: 'Field'},
                                    {name: 'LayerTranslated'},
                                    {name: 'NumOfLayerEntry'},
                                    {name: 'GroupingField'},
                                    {name: 'MetaData'}
                                ]);       
                                
                                var metaDataTemplate = "";
                                if(dataArray[0] && (!(typeof metadataFieldNames[dataArray[0][2]] == "string"))){
                                    //alert(typeof metadataFieldNames[dataArray[0][2]]);
                                    for(var metaFlds in metadataFieldNames[dataArray[0][2]]){
                                        metaDataTemplate = metaDataTemplate +
                                            "<b>"+metaFlds+"</b>" + ": {[values.MetaData['"+metaFlds+"']]}<br/>";
                                    }
                                }
                                
                                var expander;
                                if(metaDataTemplate==""){
                                //if(false){
                                    expander = null;
                                }else{
                                    expander = new Ext.grid.RowExpander({
                                        //tpl: new Ext.XTemplate("Layer: {[values.MetaData['Дата создания']]}")
                                        tpl: new Ext.XTemplate(metaDataTemplate)
                                        //,disabled: (metaDataTemplate=="")
                                    });
                                }

                                var store = needPlusick?
                                    new Ext.data.GroupingStore({
                                        data: dataArray,
                                        reader: myReader,
                                        groupField: 'GroupingField'
                                    })
                                    :
                                    new Ext.data.GroupingStore({
                                        data: dataArray,
                                        reader: myReader
                                    });

                                store.filterBy(function(record){
                                  var includeInqueryableFields = x.get('queryableFields') ? x.get('queryableFields').indexOf(record.get("Field")) != -1 : true
                                  return record.get("Field")!="THE_GEOM" && includeInqueryableFields
                                });

                                var groupingView = new Ext.grid.GroupingView({
                                        forceFit:true,
                                        groupTextTpl: "{[values.rs[values.rs.length-1].data.LayerTranslated]}"+
                                            " {[values.rs[values.rs.length-1].data.NumOfLayerEntry]}"
                                    });

                                var columns = [
                                    {
                                        header: locale.labels.featureInfo.field, 
                                        sortable: true, 
                                        dataIndex: 'FieldTranslated',
                                        groupable: false
                                    },
                                    {
                                        header: locale.labels.featureInfo.value, 
                                        sortable: true,
                                        dataIndex: 'Value',
                                        groupable: false
                                    },
                                    {
                                        header: locale.labels.featureInfo.fieldCode, 
                                        sortable: true, 
                                        dataIndex: 'Field',
                                        groupable: false,
                                        hidden: true
                                    },
                                    {
                                        header: locale.labels.featureInfo.layer, 
                                        sortable: true,
                                        dataIndex: 'LayerTranslated',
                                        groupable: false,
                                        hidden: true,
                                        hideable: false
                                    },
                                    {
                                        header: locale.labels.featureInfo.numberInLayer, 
                                        sortable: true,
                                        dataIndex: 'NumOfLayerEntry',
                                        groupable: false,
                                        hidden: true,
                                        hideable: false
                                    },
                                    {
                                        header: locale.labels.featureInfo.group, 
                                        sortable: true,
                                        dataIndex: 'GroupingField',
                                        groupable: false,
                                        hidden: true,
                                        hideable: false
                                    },
                                    {
                                        header: locale.labels.featureInfo.metadata, 
                                        sortable: true,
                                        dataIndex: 'MetaData',
                                        groupable: false,
                                        hidden: true,
                                        hideable: false
                                    }
                                    ];

                                var plugins;

                                if(expander){
                                    columns.unshift(expander);
                                    plugins = [expander];
                                }else{
                                    plugins = [];
                                }

                                /*var grid = new Ext.grid.GridPanel({
                                    plugins: plugins,                                    
                                    store: store,
                                    view: groupingView,
                                    columns: columns,					
									listeners: {
										scope: this,				
										afterrender: function(){ 
											var menu = grid.getView().hmenu.items;				
											for (var i in menu.items) {
												if (menu.items[i].itemId=="asc") menu.items[i].text = locale.labels.featureInfo.ascText;
												else if (menu.items[i].itemId=="desc") menu.items[i].text = locale.labels.featureInfo.descText;
												else if (menu.items[i].itemId=="columns") menu.items[i].text = locale.labels.featureInfo.colText;
												else if (menu.items[i].itemId=="groupBy") menu.items[i].text = locale.labels.featureInfo.groupByText;
												else if (menu.items[i].itemId=="showGroups") menu.items[i].text = locale.labels.featureInfo.showGroupsText;
											}
											try{
												var id = 'id'+(new Date()).getTime();
												globalFeatureSelectedStorage[id] = globalFeatureSelected;
												var featureSelected = globalFeatureSelectedStorage[id]; 
												
												var filter = [];
												var tablestr = '';
												var datestr = '';
												var paramstr = '';
												for (var i in codesForAnalyticsPlace)
													if (featureSelected.data[codesForAnalyticsPlace[i]] != undefined){
														filter.push("("+codesForAnalyticsPlace[i]+"='"+featureSelected.data[codesForAnalyticsPlace[i]]+"')");
														tablestr += ','+codesForAnalyticsPlace[i];
													}													
												tablestr = tablestr.replace(',','');
												
												for (var i in codesForAnalyticsTime)
													if (featureSelected.data[codesForAnalyticsTime[i]] != undefined)
														datestr += ','+codesForAnalyticsTime[i];
												datestr = datestr.replace(',','');
												
												for (var p in featureSelected.data)
													if (p.indexOf('p') == 0)
														paramstr += ','+p;
												paramstr = paramstr.replace(',','');
												
												//console.log(globalFeatureSelected.resourceId);
												if((globalFeatureSelected.resourceId != '')&&(globalFeatureSelected.resourceId != undefined))
												if(globalFeatureSelected.resourceId.toLowerCase().indexOf('ru_') != -1)
												if(globalFeatureSelected.resourceId.toLowerCase().indexOf('morsvjazsputnik') == -1)
												if((globalFeatureSelected.resourceId.toLowerCase().indexOf('nfr') == -1)&&(globalFeatureSelected.resourceId.toLowerCase().indexOf('morsvjazsputnik') == -1)&&((globalFeatureSelected.resourceId.toLowerCase().indexOf('hydrometcentre_42') == -1)||(globalFeatureSelected.resourceId.toLowerCase().indexOf('hydrometcentre_42_') != -1)))
												if(paramstr != '')
												if(filter.length > 0){
														$("span:contains('Информация'):not(:contains(' о '))").not('.button-added').each(function(){
																//$(this).parent().parent().parent().parent().parent().css('z-index','500 !important');
																$(this).addClass('button-added').append('<input id="'+id+'-data" class="portlet-form-button portlet-icon icon-chart temp-button-map" style="float:right; margin-right:2px; padding-top:1px;padding-bottom:1px;" type="button" value="Данные"/>');
														});
														$('#'+id+'-data').die().live('click',function(){
																$(this).analyticsResourcePopup({
																				'resourceId': globalFeatureSelected.resourceId,
																				'filter': filter,
																				'filtercolumns':[], 
																				'table':{
																						'columns':getResourceCodes(globalFeatureSelected.resourceId, tablestr+','+paramstr).split(",")
																				},
																				'tableinfo': false,
																				'chart':{
																						'axisX': datestr,
																						'axisY': getResourceCodes(globalFeatureSelected.resourceId, paramstr+',pp'),
																						'type': 'spline',
																						'prebuilt': true,
																						'sameY': false
																				},
																				'chartSaving': true,
																				'dateColumn': datestr
																});
														});
												}
												
												if ((globalFeatureSelected.resourceId != '')&&(globalFeatureSelected.resourceId != undefined))
												if (resourcesWithStationsArray[globalFeatureSelected.resourceId.toLowerCase()] != undefined)
												if(filter.length > 0){
													$("span:contains('Информация'):not(:contains(' о '))").not('.info-added').each(function(){
																//$(this).parent().parent().parent().parent().parent().css('z-index','500 !important');
																$(this).addClass('info-added').append('<input id="'+id+'-info" class="portlet-form-button portlet-icon icon-info-white temp-button-map clickable-resourcerecord-metadata" style="float:right; margin-right:2px; padding-top:1px;padding-bottom:1px;" data-resource="'+resourcesWithStationsArray[globalFeatureSelected.resourceId.toLowerCase()]+'" data-filter="'+filter.join('AND')+'" type="button" value="О станции"/>');
													});
												}
											}catch(e){
												console.log(e.message);
											}
										}
									}
                                });*/
                                /*this.displayPopup(
                                    evt, x.get("title") || x.get("name"), grid, true
                                );*/
								try{
									this.addMarker(evt.xy);
									var dataObj = { iTotalRecords: 1, iTotalDisplayRecords: 1, aoData: {}, warning: false };
									var id = 'id'+(new Date()).getTime();
									globalFeatureSelectedStorage[id] = globalFeatureSelected;
									var featureSelected = globalFeatureSelectedStorage[id];
									for (var tmp in featureSelected.data)
											dataObj.aoData[tmp] = featureSelected.data[tmp];
									$('#dialog-monitor').remove();
									var title = 'Информация об объекте';
									if (featureSelected.layername)
										title = featureSelected.layername;
									$('body').append('<div id="dialog-monitor" title="'+title+'" style="padding:10px;"></div>');
									var positionX = pageX-670;
									if (pageX < $(window).width()*0.4)
										positionX = pageX+10;
									if (positionX<0)
										positionX = 0;
									var positionY=pageY-255;
									if (positionY<0)
										positionY = 0;
									$('#dialog-monitor').dialog({
										minWidth:650,		
										minHeight: 240,
										position: [positionX,positionY],
										modal:false,
										resizable:false,
										draggable:true,
										open: function(){
											if (featureSelected.lat)
											if (featureSelected.lon){	
												$('#dialog-monitor').html('<div id="dialog-monitor-display" style="width:100%; max-height:600px; overflow:auto;"><div class="portlet-font portlet-icon icon-loading-bar-small" style="width:100px;height:15px;margin:0 auto;">Загрузка информации об объекте</div></div>');
												$('#dialog-monitor-display').makeMonitor({
												  'resourceId':featureSelected.resourceId,												
												  'm4311':featureSelected.lat,
												  'm4312':featureSelected.lon,
												  'dataObj': dataObj,
												  'name':title
												});
											}
										}
									});										
								}catch(e){
									console.log(e.message);
								}
                            }
                        },
                        scope: this
                    }
                });

				if (control)
				{
					map.addControl(control);
					info.controls.push(control);
					if(infoButton.pressed) {
						control.activate();
					}
				}
            }, this);
        };
       
        this.target.mapPanel.layers.on("update", updateInfo, this);
        this.target.mapPanel.layers.on("add"   , updateInfo, this);
        this.target.mapPanel.layers.on("remove", updateInfo, this);
        
        return actions;
    },

    /** private: method[displayPopup]
     * :arg evt: the event object from a 
     *     :class:`GPOpenLayers.Control.GetFeatureInfo` control
     * :arg title: a String to use for the title of the results section 
     *     reporting the info to the user
     * :arg text: ``String`` Body text.
     */
    displayPopup: function(evt, title, toShow, isGrid) {
        this.addMarker(evt.xy)
						var popup;
						var popupKey = evt.xy.x + "." + evt.xy.y;
						if (!(popupKey in this.popupCache)) {
							popup = this.addOutput({
								xtype: "gx_popup",
								title: locale.labels.featureInfo.popupTitle,
								layout: "accordion",
								location: evt.xy,
								map: this.target.mapPanel,
								width: 350,
								height: 300,
								listeners: {
									close: (function(key) {
										return function(panel){
											delete this.popupCache[key];
										};
									})(popupKey),
									scope: this
								}
							});
							this.popupCache[popupKey] = popup;
							
						} else {
							popup = this.popupCache[popupKey];
						}
						// extract just the body content
						if(isGrid){
							popup.add({
//								title: title + " (xy:" + evt.xy.x + "," + evt.xy.y + ")",
								title: title,
								layout: "fit",
								autoScroll: true,
								autoWidth: true,
								collapsible: true,
								items: [toShow]
							});							
						} else {
							popup.add({
								title: title,
								layout: "fit",
								html: toShow,
								autoScroll: true,
								autoWidth: true,
								collapsible: true
							});
						}
						popup.doLayout();
    }


});

Ext.preg(gxp.plugins.GridWmsFeatureInfo.prototype.ptype, gxp.plugins.GridWmsFeatureInfo);
