(function($, undefined) {

	$.widget("gcTool.toolTip", $.ui.gcTool, {

		widgetEventPrefix: "toolTip",

		options: {
			label: OpenLayers.i18n('Tooltip'), // TODO: use as default value OpenLayers.i18n...
			icons: {
				primary: 'tooltip' // TODO: choose better name
			},
			text: false,
			gisclient: null,
			tooltipWidth: 200,
			delayBeforeToolTipRequest: 1000, // in milliseconds
			control: null,
			queryLayers: {}, // int obj to store the queryable layers data
			cols: {}, // int obj to store the columns model of the selected layer
			keepPopups: true
		},
		
		_create: function() {
			var self = this;
			
			$.ui.gcTool.prototype._create.apply(self, arguments);
			
		},
		
		_click: function(event) {
			var self = event.data.self;
			
			// create a custom control
			self.options.control = new OpenLayers.Control();
			OpenLayers.Util.extend(self.options.control, {
				EVENT_TYPES: ['mousestopped'],
				handler: null,
				handlerOptions: {hover:{delay:self.options.delayBeforeToolTipRequest}},
				initialize: function() {
					OpenLayers.Control.prototype.initialize.apply(this, arguments);
					this.EVENT_TYPES = OpenLayers.Control.prototype.EVENT_TYPES.concat(
						OpenLayers.Control.prototype.EVENT_TYPES
					);
					this.handler = new OpenLayers.Handler.Hover(
						this, {
							'move': this.cancelHover,
							'pause': this.getInfoForHover
						},
						this.handlerOptions.hover
					);
				},
				activate: function () {
					if (!this.active) {
						this.handler.activate();
					}
					return OpenLayers.Control.prototype.activate.apply(
						this, arguments
					);
				},
				deactivate: function() {
					if(this.active) {
						this.handler.deactivate();
					}
					return OpenLayers.Control.prototype.deactivate.apply(
						this, arguments
					);
				},
				getInfoForHover: function(evt) {
					var lonLat = this.map.getLonLatFromPixel(evt.xy);
					this.events.triggerEvent("mousestopped", {lonLat: lonLat});
				},
				cancelHover: function() {
					if (this.hoverRequest) {
						this.hoverRequest.abort();
						this.hoverRequest = null;
					}
				},
				CLASS_NAME: 'OpenLayers.Control.toolTip'
			});
			self.options.control.initialize(); // PERCHE DEVO CHIAMARLA A MANO?!?!?!?!?!?
			
			self.options.control.events.register("mousestopped", self, self._requestToolTip);
			
			gisclient.map.addControl(self.options.control);
			
			// build html for the tooltip dialog
			var checked = (self.options.keepPopups) ? 'checked' : '';
			var html = '<div id="tooltip_settings" style="display:none;"><input type="checkbox" name="keep_popups" value="yes" checked="'+checked+'"> '+OpenLayers.i18n('Keep tooltips opened')+'<br />'+OpenLayers.i18n('Tooltip layer')+'<br /><select id="tooltip_layer"><option value="0">'+OpenLayers.i18n('Select')+'</option>';
			self.options.queryLayers = gisclient.componentObjects.gcLayersManager.getQueryableLayers();
			$.each(self.options.queryLayers, function(featureId, layer) {
				html += '<option value="'+featureId+'">'+layer.title+'</option>';
			});
			html += '</select><br /><br /><a href="#" id="tooltip_unselectall">'+OpenLayers.i18n('Unselect all')+'</a>';
			
			$('body').append(html);
			
			var dialogOptions = $.extend(gisclient.options.dialogDefaultPosition, {draggable:true,title:OpenLayers.i18n('Tooltip options'),autoOpen:false});
			dialogOptions.close = function(event, self) {
				var self  = gisclient.toolObjects.toolTip;
				self._deactivate();
			}
			$('#tooltip_settings').dialog(dialogOptions);
			
			$('#tooltip_unselectall').click(function(event) {
				event.preventDefault();
				self._unSelectAll(event);
			});
			$('#tooltip_settings input[name="keep_popups"]').click(function() {
				self._toggleKeepPopups($('#tooltip_settings input[name="keep_popups"]').attr('checked'));
			});
			
			$.ui.gcTool.prototype._click.apply(self, arguments);
			
			if(!$('#tooltip_settings').dialog('isOpen')) $('#tooltip_settings').dialog('open');

		},
		
		_deactivate: function() {
			var self = this;
			
			// remove the selected features and destroy popups
			self._unSelectAll();
			
			// close the tooltip settings dialog
			if($('#tooltip_settings').dialog('isOpen')) $('#tooltip_settings').dialog('close');
			
			$('#tooltip_layer option[value="0"]').attr('selected', 'selected');
		},
		
		_requestToolTip: function(event) {
			var self = this;
			
			if(!self.options.keepPopups) self._unSelectAll();
			
			var lonLat = event.lonLat; // get the mouse position
			var selectedLayer = $('#tooltip_layer').val(); // get the layer selected by the user
			if(typeof(self.options.queryLayers[selectedLayer]) == 'undefined') return;
			var queryLayer = self.options.queryLayers[selectedLayer];
			var geom = new OpenLayers.Geometry.Point(lonLat.lon, lonLat.lat);
			// create the openlayers spatial filter
			var filter = new OpenLayers.Filter.Spatial({
				type: OpenLayers.Filter.Spatial.INTERSECTS,
				value: geom,
				projection: gisclient.getProjection(),
				property: 'the_geom'
			});
			var filter_1_1 = new OpenLayers.Format.Filter({version: "1.1.0"});
			var xml = new OpenLayers.Format.XML();
			var filterValue = xml.write(filter_1_1.write(filter));	

			self.options.cols[selectedLayer] = {};
			$.each(queryLayer.fields, function(key, col) {
				self.options.cols[selectedLayer][key] = col.fieldHeader;
			});
			
			gisclient.componentObjects.loadingHandler.show();
			
			// build the WFS url request
			var params = {
				PROJECT: gisclient.getProject(),
				MAP: queryLayer.layer.parameters.map,
				SERVICE: 'WFS',
				VERSION: '1.1.0',
				SRS: gisclient.getProjection(),
				REQUEST: 'GETFEATURE',
				TYPENAME: selectedLayer,
				FILTER: filterValue,
				OUTPUTFORMAT: 'text/xml;subtype=gml/2.1.2'
			};
			
			$.ajax({
				url: queryLayer.layer.url,
				type: 'GET',
				dataType: 'xml',
				data: params,
				success: function(response, status, jqXHR) {
					var format = new OpenLayers.Format.GML();
					var features = format.read(response);

					gisclient.componentObjects.loadingHandler.hide();
				
					if(features.length > 0) {
						// add vector features to selection layer
						var selectionLayer = gisclient.componentObjects.gcLayersManager.getSelectionLayer();
						selectionLayer.addFeatures(features);
						
						var cols = self.options.cols[selectedLayer];
						// create a temporary tooltip to get the correct height
						if($('#temp_tooltip').length < 1) $('body').append('<div id="temp_tooltip" style="display:none;width:'+self.options.tooltipWidth+';"></div>');
						//create the tooltip html
						var html = '<div class="tooptip">'+OpenLayers.i18n('${count} objects found', {count:features.length})+'<br>';//LANG
						// HACK: openlayers need a feature to handle a popup. The request can return more than one features, so we will add popups on just one of the features (one_feature)
						var one_feature;
						$.each(features, function(i, feature) {
							one_feature = feature;
							$.each(cols, function(key, label) {
								html += '<strong>'+label+'</strong>: '+feature.attributes[key]+'<br />';
							});
							html += '<hr>';
						});
						html += '</div>';
						// add the html to the temp_tooltip and measure its height
						$('#temp_tooltip').html(html);
						var h = ($('#temp_tooltip').height())+10;
						// create the popup and add it to the map (using the one_feature)
						one_feature.popup = new OpenLayers.Popup.Anchored('',lonLat,new OpenLayers.Size(self.options.tooltipWidth,h),html,null,true,function(event) {
							self._onPopupClose(this);
						});
						one_feature.popup.featureArray = features;
						gisclient.map.addPopup(one_feature.popup);
					}					
				},
				error: function(response, status, jqXHR) {
					var string = OpenLayers.i18n('Error reading results, the request has been aborted');
					gisclient.componentObjects.errorHandler.show(string);//LANG
					gisclient.log(jqXHR.responseText);
					return false;
				}
			});
		},
		
		_onPopupClose: function(popup) {
			var self = this;
			
			var selectionLayer = gisclient.componentObjects.gcLayersManager.getSelectionLayer();
			selectionLayer.removeFeatures(popup.featureArray);
			
			popup.hide();
		},
		
		_toggleKeepPopups: function(checked) {
			var self = this;
			self.options.keepPopups = checked;
		},
		
		_unSelectAll: function(event) {
			var self = this;
			var selectionLayer = gisclient.componentObjects.gcLayersManager.getSelectionLayer();
			while(gisclient.map.popups.length > 0) {
				gisclient.map.removePopup(gisclient.map.popups[0]);
			}
			selectionLayer.removeFeatures(selectionLayer.features);
		}
	});

	$.extend($.gcTool.toolTip, {
		version: "3.0.0"
	});
})(jQuery);
