/*
$('.map').gmapcluster({ url:'markerspack.html', map_options:{} });
http://google-maps-utility-library-v3.googlecode.com/svn/tags/markerclusterer/1.0/docs/reference.html
http://thydzik.com/thydzikGoogleMap/markerlink.php?text=&color=EC6500
*/
;(function($) {

	$.widget('cms.dealmaps', {
	
		options:{
			cache_tabs: {}, //przechowuje paczki odpowiedzi dla tabow, czyszcone przez clear_cache_tabs
			deal: null, //
			url_markers:'',
			url_infowindow: '/dealmaps.infowindow.html',
			url_missing_markers: '/offers/coordinates',
			zoom_min:13,
			zoom_max:15,
			//zoom_max_one_dealbox:14,
			zoom_default:10,
			zoom_deal_show: 16,
			pack_size:500,
			filter:{},
			cluster_options: { maxZoom:15 },
			center_default: { lat:51, lng:17 },
			dealbox_markers:[], //wyroznione markery poza klastrem
			map_options: {},
			url_marker_icons:{
					0: '/images/dealmaps/24x24/icon0.png',
					1: '/images/dealmaps/24x24/icon1.png',
					2: '/images/dealmaps/24x24/icon2.png',
					3: '/images/dealmaps/24x24/icon3.png',
					4: '/images/dealmaps/24x24/icon4.png',
					5: '/images/dealmaps/24x24/icon5.png',
					6: '/images/dealmaps/24x24/icon6.png',
					7: '/images/dealmaps/24x24/icon7.png',
					8: '/images/dealmaps/24x24/icon8.png',
					9: '/images/dealmaps/24x24/icon9.png',
					10: '/images/dealmaps/24x24/icon10.png',
					11: '/images/dealmaps/24x24/icon11.png',
					12: '/images/dealmaps/24x24/icon12.png',
					13: '/images/dealmaps/24x24/icon13.png',
					14: '/images/dealmaps/24x24/icon14.png',
					15: '/images/dealmaps/24x24/icon15.png',
					16: '/images/dealmaps/24x24/icon16.png',
					17: '/images/dealmaps/24x24/icon17.png'
			},
			url_dealbox_icons: '/icons/deal',
			dealboxes:null, //element
			dealboxes_options: {},
			zoom_changed_lock: true,
			_timeout_usepack: null
		},

		_init:function(){
			this.options.pack_range = { left:0, right: 0, top:0, bottom:0 };
			this.load_map({ filter_options:{ from_filter:1 } } );
			if (this.options.dealboxes) {
				$(this.options.dealboxes).dealboxes(this.options.dealboxes_options);
			}
			return this;
		},

		map_loaded:function(){
			return (!!this.options['googlemap']);
		},

		_icon_url:function(color, isdealbox){
			return (isdealbox) ? this.options.url_dealbox_icons + '/icon' + color + '.png' : this.options.url_marker_icons[color];
		},

		//! Ładuje mape google
		load_map:function(options){
			var self = this;
			cms_googlemaps.execute(function(){
				var latlng = new google.maps.LatLng(self.options.center_default.lat, self.options.center_default.lng);
				var map_options = $.extend({ zoom:self.options.zoom_default, center:latlng, mapTypeId:google.maps.MapTypeId.ROADMAP }, self.options.map_options);
				self.options['googlemap'] = new google.maps.Map($('.l-js-map',self.element).get(0), map_options);
				self.options['geocoder'] = new google.maps.Geocoder();

				google.maps.event.addListener(self.options['googlemap'], 'dragend', function(event){ return self._map_changed(event); });
				google.maps.event.addListener(self.options['googlemap'], 'zoom_changed', function(event){ 
					//_log(self.options.zoom_changed_lock);
					if (self.options.zoom_changed_lock) {
						self.options.zoom_changed_lock = false;  
						return;
					}
					self.options.zoom_changed_lock = false;
					return self._map_changed(event); 
				});
				self.options['clusterer'] = new MarkerClusterer(self.options['googlemap'], null, self.options['cluster_options']);
				self.options['load_pack_timer'] = setTimeout(function(){ self.load_pack(self.options.filter, options.filter_options); }, 2000);
				//self.options['infowindow'] = null;//new google.maps.InfoWindow({ content: '' });
				self.options['infowindow'] = new google.maps.InfoWindow({ content: '' }); 
				//google.maps.event.addListener(self.options['infowindow'], 'domready', function(event, data){  });
				
			});
			return this;
		},

		_map_changed:function(event){
			var self = this;
			if (this.options['googlemap'].getZoom()<this.options.zoom_min){
				this.options['googlemap'].setZoom(this.options.zoom_min);
			}
			//_log('range mapy po przesunieciu:');
			//_log(self._get_map_current_range());
			if (this._reload_required()) {
				//_log('wystapilo przeciecie - wymagane pobranie paczki');
				if (this.options['load_pack_timer']) clearTimeout(this.options['load_pack_timer']);
				//this.options['load_pack_timer'] = setTimeout(function(){ self.load_pack(null, { mapmoved:1 }); }, 1000);
				this.options['load_pack_timer'] = setTimeout(function(){ self.load_pack(null, { mapmoved:1, from_filter:0 }); }, 10);
				return false;
			}
			return true;
		},

		//! Dodaje prefiks do parametrow wysylanych do serwera { aa:bb } -> { prefix[aa]:bb }
		_prefix_params:function(params, prefix){
			var result = {};
			for(key in params) result[prefix + '[' + key + ']'] = params[key];
			return result;
		},

		//! Zwraca aktualnie wyswietlane wlasciwosci mapy
		_get_map_current_range:function(){
			if (!this.options['clusterer'].getProjection()) return null;
			var width = $(this.element).width();
			var height = $(this.element).height();
			var left_top = this.options['clusterer'].getProjection().fromContainerPixelToLatLng(new google.maps.Point(0, 0));
			var bottom_right = this.options['clusterer'].getProjection().fromContainerPixelToLatLng(new google.maps.Point(width, height));
			return { 
				left: left_top.lat(),
				top: left_top.lng(),
				right: bottom_right.lat(),
				bottom: bottom_right.lng(),
				zoom: this.options['googlemap'].getZoom(),
				world_width: this.options['clusterer'].getProjection().getWorldWidth(),
				width: width,
				height: height
			};
		},

		clear_cache_tabs:function(){
			delete this.options.cache_tabs;
			this.options.cache_tabs = {};
			return this;
		},
					 
		//! Sciaga z serwera paczke z markerami 
		load_pack:function(newfilter, options){
			var self = this;
			options = options || {};
			this.hide_infowindow();
			if (newfilter!=null) this.options['filter'] = newfilter;
			
			var tab = $(this.options.deal).deal('get_tab');

			//var f = this.options['filter'];
			//_log(newfilter);
			//_log((typeof(newfilter)!='undefined'));
			if (this.options['ajax']) {
				$('.deal-loader', this.element).hide();
				this.options['ajax'].abort();
				this.options.ajax_lock = false;
			}

			if (!options.mapmoved && this.options.cache_tabs[tab]) {
				//_log('maps: pack from cache, tab:' + tab);
				//this.options.ajax_lock = false;
				this.use_pack(this.options.cache_tabs[tab], newfilter!=null);
				$('.deal-loader', this.element).hide();
				return this;
			}

			//cms_googlemaps.execute(function(){
				//if (!self.options['clusterer']) return;
			
			if (!this.options.ajax_lock) {
				var range = self._get_map_current_range();
				if (range!=null) {
					$('.deal-loader', this.element).show();
					this.options.ajax_lock = true;
					self.options['ajax'] = $.ajax({
						url:self.options.url_markers,
						data:$.extend(self._prefix_params($.extend(range, { tab:tab, pack_size:self.options.pack_size }), 'pack'), this.options['filter'], options),
						dataType:'json',
						success:function(data){	
							self.options.cache_tabs	[tab] = data; 
							self.use_pack(data, newfilter!=null);
						},	
						//error:function(){ self.options.ajax_lock = false; $('.deal-loader', self.element).hide(); },
						complete:function(){ self.options.ajax_lock = false; $('.deal-loader', self.element).hide(); }
					});
				}
			}
			//});
			return this;
		},

		_create_marker:function(item){
					if (!(item.lat!=null && item.lng!=null)) return null;
					item.icon = parseInt(item.color,10);
					if (isNaN(item.icon)) item.color = 0;
					if (item.color>=this.options.url_marker_icons.length) item.color=this.options.url_marker_icons.length-1;
					var marker = new google.maps.Marker({
						position: new google.maps.LatLng(item.lat, item.lng),
						//icon: this.options.url_marker_icons[item.color]
						icon: this._icon_url(item.color, item.dealbox)
					});
					marker.id_deal = item.id;
					return marker;
		},

		//! Podlacza wskazana paczke markerow
		use_pack:function(data, fit_bounds){
			if (!data) return this;
			if (this.options._timeout_usepack) clearTimeout(this.options._timeout_usepack);

			var self = this;

			var f = function(){
				var markers = [];
				$('.deal-loader', self.element).hide();
				self.options.pack_range = data.range; //{ left:123, right:123, top:123, bottom:123 }
				//_log('przyszedl range:');
				//_log(data.range);
				//_log('range mapy:');
				//_log(self._get_map_current_range());
				$(data.markers).each(function(i, item){
						var marker = self._create_marker(item);		
						if (marker)	markers.push(marker);
					}
				);
				self.clear_dealbox_markers();
				self.clear_markers();
				if (data.dealboxes){
					if (self.options.dealboxes) $(self.options.dealboxes).dealboxes('set_dealboxes',{ html:data.dealboxes.html, deals:data.dealboxes.deals });
				}
				if (markers.length){
					self.add_markers(markers);
					if (fit_bounds) {
						self.fitbounds_allmarkers({ center:data.center });
						//this.options['clusterer'].getMap().setCenter(new google.maps.LatLng(data.center.lat, data.center.lng));
						//this.options['clusterer'].getMap().setZoom(this.options.zoom_min);
					}
				}else{
					if (fit_bounds) {//nie ma markerów więc ustawiamy mape na wskazaną pozycje
						//this.options.zoom_changed_lock = true;
						if (data.center_text) {
							self.set_center_address(data.center_text);
						}else{	
							self.options.zoom_changed_lock = true;
							self.options['clusterer'].getMap().setCenter(new google.maps.LatLng(data.center.lat, data.center.lng));
							self.options['clusterer'].getMap().setZoom(self.options.zoom_default);
						}
						//this.options['clusterer'].getMap().setZoom(this.options.zoom_default);
					}
				}
			};
			//f();
			this.options._timeout_usepack = setTimeout(f, 0);
			//_log(data.dealboxes);
			return this;
		},

		//! Sprawdza czy wmagane jest poranie nowej paczki markerow
		_reload_required:function(filter){
			var current_range = this._get_map_current_range();
			if (current_range==null) return false;
			return (
				current_range.left<this.options.pack_range.left ||
				current_range.right>this.options.pack_range.right || 
				current_range.top>this.options.pack_range.top || 
				current_range.bottom<this.options.pack_range.bottom 
			);
		},

		//! Dodaje marker
		add_marker:function(marker){
			var self = this;
			this.options['clusterer'].addMarker(marker);
			google.maps.event.addListener(marker, 'click', function(event) { self._show_marker_window(this); });
			this.hide_deal_markers_in_dealboxes();
			return this;
		},

		//! Dodaje tablice markerow
		add_markers:function(markers){
			var self = this;
			this.options['clusterer'].addMarkers(markers);
			$(markers).each(function(){
				google.maps.event.addListener(this, 'click', function(event) { self._show_marker_window(this); });
			});
			this.hide_deal_markers_in_dealboxes();
			return this;
		},

		//! Usuwa wszystkie markery
		clear_markers:function(){
			this.options['clusterer'].clearMarkers();
			return this;
		},

		//! Usuwa markery okreslonych deali z clustra
		remove_deals_from_cluster:function(deals){
			if (!$.isArray(deals)) return this;
			$(this.options['clusterer'].getMarkers()).each(function(){
				if ($.inArray(this.id_deal, deals)>=0) this.options['clusterer'].removeMarker(this);
			});
			return this;
		},
		
		//! dodaje promowanego deala
		add_dealbox_marker:function(id_deal, options){
			var self = this;
			if (options.lat==0 || options.lng==0) return this;
			//_log(id_deal);
			//_log(options);
			//var marker = new google.maps.Marker({
			//var marker = new RichMarker({
			var marker = new MarkerWithLabel({
				position: new google.maps.LatLng(options.lat, options.lng),
				//title: 'Deal ' + id_deal,
				//icon: this.options.url_dealbox_icons + '/icon' + options.color + '.png',
				icon: this._icon_url(options.color, true),
				zIndex: 5000
				//labelContent: options.nr,
				//labelAnchor: new google.maps.Point(10, 30),
				//labelClass: "dealmaps-dealbox-label", // the CSS class for the label
				//labelInBackground: false
			});
			marker.id_deal = id_deal;
			marker.setMap(this.options['googlemap']);
			google.maps.event.addListener(marker, 'click', function(event) { self._show_marker_window(this); });
			this.options.dealbox_markers.push(marker);
			this.hide_deal_marker(id_deal);
			return this;
		},

		//! Usuwa promowanego deala
		delete_dealbox_marker:function(id_deal){
			$(this.options.dealbox_markers).each(function(){ 
					if (this.id_deal == id_deal) {
						this.setVisible(false); 
						this.setMap(null); 
					}
			});
			this.show_deal_marker(id_deal);
			return this;
		},
		
		hide_deal_marker:function(id_deal){
			$(this.options['clusterer'].getMarkers()).each(function(){
				if (this.id_deal == id_deal) {
					//_log('hide' + id_deal);
					this.setVisible(false);
					this.setMap(null);
				}
			});
		},
		
		show_deal_marker:function(id_deal){
			var self = this;
			$(this.options['clusterer'].getMarkers()).each(function(){
				if (this.id_deal == id_deal) {
					//_log('show' + id_deal);
					//this.setVisible(true);
					this.setMap(self.options['clusterer'].getMap());
				}
			});
		},		
		
		hide_deal_markers_in_dealboxes: function(){
			var dealboxes_ids = [];
			$(this.options.dealbox_markers).each(function(){ dealboxes_ids.push(this.id_deal); });
			dealboxes_ids = $.unique(dealboxes_ids);
			//_log(dealboxes_ids);
			$(this.options['clusterer'].getMarkers()).each(function(){
				if ($.inArray(this.id_deal, dealboxes_ids)>=0) { 
					//_log(dealboxes_ids);
					//_log(this.id_deal);
					this.setMap(null);
					//this.setVisible(false); 
				}
			});
			return this;
		},
		
		fitbounds_dealbox_markers:function(){
			if (!this.map_loaded()) return this;
			//_log(this.options['dealbox_markers'].length);
			if (this.options['dealbox_markers'].length>1){
				var bounds = new google.maps.LatLngBounds();
				$(this.options['dealbox_markers']).each( function(){ 
						//_log('x');
						//_log(this.getVisible());
						//if (this.getVisible()) bounds.extend(this.getPosition());
						bounds.extend(this.getPosition()); 
				} );
				//_log('fitbounds_dealbox_markers');
				this.fitbounds(bounds, this.options.zoom_max);
				//this.options['googlemap'].fitBounds(bounds);
				//if (this.options['googlemap'].getZoom()>this.options.zoom_max) this.options['googlemap'].setZoom(this.options.zoom_max);
			}else{
				if (this.options['dealbox_markers'].length==1){
					//_log('zoom');
					//_log(this.options['dealbox_markers'][0].getPosition());
					this.options['googlemap'].setCenter(this.options['dealbox_markers'][0].getPosition());
					if (this.options['googlemap'].getZoom()>this.options.zoom_max) {
						this.options.zoom_changed_lock = true;
						this.options['googlemap'].setZoom(this.options.zoom_max);
					}
					//alert('zoom');
					//this.options['googlemap'].setZoom(15);
				}
			}
			return this;
		},

		fitbounds_allmarkers:function(options){ //markers and dealboxes
			if (!this.map_loaded()) return this;
			var self = this;
			//_log(this.options['dealbox_markers'].length);
			var bounds = new google.maps.LatLngBounds();
			var fitbounds = false;
			if (this.options['dealbox_markers'].length>1) $(this.options['dealbox_markers']).each( function(){ if (this.getVisible()) { bounds.extend(this.getPosition()); fitbounds=true; } } );
			$(this.options['clusterer'].getMarkers()).each(function(){ bounds.extend(this.getPosition()); fitbounds = true; });
			if (fitbounds){
				//self.options.zoom_change_lock = true;
				//_log(this.options.zoom_min);
				this.fitbounds(bounds, this.options.zoom_max, this.options.zoom_min, function(event, zoommax, zoommin){
						if (zoommax>0) if (this.getZoom() > zoommax) { self.options.coom_changed_lock = true; this.setZoom(zoommax); }
						if (zoommin>0) if (this.getZoom() < zoommin) { 
							//_log('callback');
							self.options.zoom_changed_lock = true;
							this.setZoom(zoommin);
							this.setCenter(new google.maps.LatLng(options.center.lat, options.center.lng));
						}
				});
				//this.options['googlemap'].fitBounds(bounds);
				//if (this.options['googlemap'].getZoom()>this.options.zoom_max) this.options['googlemap'].setZoom(this.options.zoom_max);
			}
			return this;
		},

		//! Usuwa wszystkie promowane deale 
		clear_dealbox_markers:function(){
			var self = this;
			$(this.options.dealbox_markers).each(function(){ 
				self.show_deal_marker(this.id_deal);
				this.setVisible(false); 
				this.setMap(null); 
			})
			this.options.dealbox_markers.length = 0;
			return this;
		},

		//! Szuka markerow danego deala
		_find_deal_markers:function(id_deal, first_only){
			var result = [];
			$(this.options['dealbox_markers']).each(function(){
				if (this.id_deal==id_deal) {
					result.push(this);
					return first_only;
				}
			});
			if (first_only && result.length>0) return result;
			$(this.options['clusterer'].getMarkers()).each(function(){
				if (this.id_deal==id_deal) {
					result.push(this);
					return first_only;
				}
			});
			return result;
		},

		show_deal:function(id_deal, options){
			options  = $.extend({zoom: this.options.zoom_deal_show}, options); 
			var self = this;
			var markers = this._find_deal_markers(id_deal,true);
			if (markers.length>0){
					this.options['googlemap'].setCenter(markers[0].getPosition());
					if (options['zoom']) { this.options.zoom_changed_lock = true; this.options['googlemap'].setZoom(options.zoom); }
					this._show_marker_window(markers[0]);
			}else{
				$.ajax({
					url: this.options.url_missing_markers,
					data: { id:id_deal },
					dataType:'json',
					success:function(data){
						var markers = [];
						$(data.markers).each(function(i, item){
							var marker = self._create_marker(item);		
							if (marker) markers.push(marker);
						});
						self.add_markers(markers);
						var markers = self._find_deal_markers(id_deal,true);
						self.options['googlemap'].setCenter(markers[0].getPosition());
						if (options['zoom']) { self.options.zoom_changed_lock = true; self.options['googlemap'].setZoom(options.zoom); }
						self._show_marker_window(markers[0]);
					}
				});
			}
			return this;
		},
		
		_show_marker_window:function(marker){
			var self = this;
			$.get(this.options.url_infowindow, { id:marker['id_deal'] }, function(data){ 
				//if (self.options['infowindow']) {
				//	self.options['infowindow'].close();
				//	delete self.options['infowindow'];
				//}
				//self.options['infowindow'] = new google.maps.InfoWindow({ content: data, position:marker.latLng }); 
				//self.options['infowindow'] = new google.maps.InfoWindow({ content: 'aaa<br />aaa<br />aaa<br />aaa<br />aaa<br />aaa<br />aaa<br />', position:marker.latLng }); 
				self.hide_infowindow();
				//self.options['infowindow'].close();
				self.options['infowindow'].setContent(data); 
				self.options['infowindow'].setPosition(marker.latLng);
				self.options['infowindow'].open(self.options['googlemap'], marker);  
				$('body').tevent('log', { id:'markerclick', offer:marker['id_deal'], event:'click' });
				self._bind_info_window();
			});
			return this;
		},
		
		hide_infowindow:function(){
			if (this.options['infowindow']) this.options['infowindow'].close();
			return this;
		},
		
		_bind_info_window:function(){
			var self = this;
			$('.deal-infowindow .deal-js-more').unbind('click.infowindow').bind('click.infowindow', function(event){ 
          if (self.options.deal) {
            var offer_id = $(this).attr('rel');
            $(self.options.deal).deal('item_more_dialog', offer_id); 
				    $('body').tevent('log', { id:'moreinfo', offer:offer_id, event:'click' }, event);
          }
          return false; 
      });
			return this;
		},
		
		fitbounds:function(bounds, zoommax, zoommin, callback){
			var self = this;
			//_log('fitbounds');
			if (this.options['googlemap']){
				self.options.zoom_changed_lock = true;
				var zoomListener = google.maps.event.addListener(this.options['googlemap'], 'zoom_changed', function() {
							google.maps.event.removeListener(zoomListener);
							var zoomChangeBoundsListener = google.maps.event.addListener(self.options['googlemap'], 'bounds_changed', function(event) {
								//_log('bounds_changed');
								google.maps.event.removeListener(zoomChangeBoundsListener);
								if ($.isFunction(callback)) callback.call(this, event, zoommax, zoommin);
								else {
									if (zoommax>0) if (this.getZoom() > zoommax) { self.options.zoom_changed_lock = true; this.setZoom(zoommax); }
									if (zoommin>0) if (this.getZoom() < zoommin) { self.options.zoom_changed_lock = true; this.setZoom(zoommin); }
								}
								
							});
				});
				this.options['googlemap'].fitBounds(bounds);
			}
			return this;
		},

		set_center_address:function(address){
                    	var self = this;
                    	var geocodeResult = function(results, status) {
                     		if (status == 'OK' && results.length > 0) {
					self.fitbounds(results[0].geometry.viewport);
                        		//self.options['googlemap'].fitBounds(results[0].geometry.viewport);
				} else {
                        		//alert($.i18n._('cms_core_googlemaps_find_location_not_found'));
                        	}
                    	}
			this.options['geocoder'].geocode( { 'address': address,   'partialmatch': true }, geocodeResult );
			return this;

		}

	});
	
})(jQuery);



