var gmaps = {
	// centrujeme na stred republiky
	defaultZoom: 6, // zaber na republiku
	defaultLatitude: 49.930008,
	defaultLongitude: 15.369873,

	// adresa pro nacitani objektu - na ni budou POSTem poslany souradnice
	// aktualniho vyrezu mapy
	ajaxUrl: false,

	// stred mapy
	center: false,

	// umoznuje urcit stred mapy adresou namisto souradnic - pozor, Google
	// tuto funkci omezuje na pocet pouziti za den!
	geoName: false,

	// stav nacitani dat: 0 = nic se nenacita, 1 = nacita se,
	// 2 = cekani na dokonceni predchozi operace
	loadStatus: 0,

	// hlavni objekt mapy
	map: false,

	// docasne vyradi udalost vyvolanou presunem v mape
	// obnovi se pri dalsi udalosti
	// true zabrani uplne prvni udalosti
	preventMoveEvent: true,
	
	// Callback funkce volana po nacteni objektu pres AJAX. Jako parametr
	// dostane pole objektu.
	onObjects: null,
	
	// URL loga pro zobrazeni v bubline mapy
	serverLogo: null,
	
	// veci na mape
	markers: [],

	//Info okno
	infowindow: null,

	//Info okno otevreno
	infowindowOpened: false,

	//Info okno muze byt kliknutim otevreno
	infowindowOpeneable: true,

	// inicializuje Google Maps
	load: function(mapObjects) {
		if (this.init()) {
			if (mapObjects.length) {
				gmaps.setObjectsToMap(mapObjects);
			}
			// pokud jsme na detailu objektu zobrazime pouze jeho a pak uz nic vic
			if (this.ajaxUrl) {
				// odposlouchavame na udalost pohyb s mapou
				google.maps.event.addListener(
					this.map,
					'idle',
					function () {
						gmaps.mapMoveHandler();
					}
				);
			}
		}
		this.setupMapEnlargeButton();
	},

	// Inicializuje mapu (nastavi stred atd.)
	init: function() {
		// pokud jsme na kraji, okrese, nebo meste nechame si zjistit pozice pres geomapy, 
		// toto je omezena na 15 000 requests/24hour z jedne IP adressy
		if (this.center == false) {
			if (this.geoName != false) {
				geocoder = new google.maps.Geocoder();
				if (geocoder) {
					geocoder.geocode( 
						{ 'address': this.geoName},
						function(results, status) {
							if (status == google.maps.GeocoderStatus.OK) {
								gmaps.center = results[0].geometry.location;
							} else {
								this.setDefaultCenter();							
							}
							gmaps.load();
						}
					);
	
					return false;
				} else {
					this.setDefaultCenter();
				}
			} else {
				this.setDefaultCenter();
			}
		}
		
		var mapOptions = {
			zoom: this.defaultZoom,
			center: this.center,
			mapTypeId: google.maps.MapTypeId.ROADMAP
		};

		// jQuery syntaxi nebere
		this.map = new google.maps.Map(document.getElementById('gMap'), mapOptions); // nastavime mapu do objektu X

		this.infowindow = new google.maps.InfoWindow();
		
		google.maps.event.addListener(this.infowindow, 'closeclick', function() {
			gmaps.infowindowOpened = false;
		});
		
		return true;
	},

	setDefaultCenter: function() {
		this.center = new google.maps.LatLng(
			this.defaultLatitude,
			this.defaultLongitude
		);
	},

	removeMarkers: function() {
		if (this.markers) {
			for (i in this.markers) {
				this.markers[i].setMap(null);
			}
			this.markers.length = 0;
		}
	},
	
	// Nastavi chovani tlacitka pro zvetseni mapy pres cely prohlizec
	setupMapEnlargeButton: function() {
		var mapElement = $('#gMap');
		var mapElementParent = mapElement.parent();
		var mapW = $('#gMap').css('width');
		var mapH = $('#gMap').css('height');
		var mapCenter = null;

		$('#zoom-map').show();
		$('#zoom-map a').overlay({
			expose: {
				color: '#000',
				opacity: 0.5,
				loadSpeed: 0,
				closeSpeed: 0,
				zIndex: 14998
			},
			zIndex: 15000,
			speed: 1,
			fadeInSpeed: 1,
			target: '#map-overlay',
			onBeforeLoad: function () {
				mapCenter = gmaps.map.getCenter();
				gmaps.map.setOptions({scrollwheel: true});
				mapElementParent.hide();
				this.getTrigger().hide();
			},
			onLoad: function () {
				var mapWidth = 800;
				var mapHeight = 600;
				var TrackHeight = 100;
				$('#map-overlay').append(mapElement);

				if(typeof(gMapAlts) != 'undefined') {
					var validHeights = false;
					var minHeight = 99999;
					var maxHeight = -99999;
					for(var i in gMapAlts) {
						if((i>0) && (gMapAlts[i-1][1] != gMapAlts[i][1])) {
							validHeights = true;
						}
						if (gMapAlts[i][1] < minHeight ) {
							minHeight = gMapAlts[i][1];
						}
						if (gMapAlts[i][1] > maxHeight ) {
							maxHeight = gMapAlts[i][1];
						}
					}
					if(validHeights) {
						mapHeight -= TrackHeight;
						$('#map-overlay').append('<span id="track-profile"></span>');
						$('#track-profile').sparkline(
							gMapAlts,
							{
								type:'line',
								lineColor: '#3B5B30',
								fillColor: '#7F8807',
								width: mapWidth+'px',
								height: TrackHeight+'px',
								spotColor: false,
								minSpotColor: false,
								maxSpotColor: false
							}
						);
						$('#track-profile')
							.append('<span class="alt-max">'+Math.round(maxHeight)+' m n. m.</span>')
							.append('<span class="alt-min">'+Math.round(minHeight)+' m n. m.</span>');
					}
				}
				mapElement.css({
					width: mapWidth + 'px',
					height: mapHeight + 'px',
					zIndex: $('#map-overlay').css('z-index') - 1
				});
				var iframe = $('<iframe frameborder="0"></iframe>').css({
					position: 'absolute',
					border: 'none',
					top: 0,
					left: 0,
					width: $('#map-overlay').css('width'),
					height: $('#map-overlay').css('height'),
					zIndex: mapElement.css('z-index') - 100
				});
				mapElement.after(iframe);
				google.maps.event.trigger(gmaps.map, 'resize');
				gmaps.map.setCenter(mapCenter);
			},
			onBeforeClose: function () {
				//$('span.alt-max, span.alt-min').remove();
				mapElement.parent().find('iframe').remove();
				mapElementParent.prepend(mapElement);
				$('#track-profile').remove();
				mapCenter = gmaps.map.getCenter();
				mapElement.css({ width: mapW, height: mapH });
				mapElementParent.show();
				google.maps.event.trigger(gmaps.map, 'resize');
				gmaps.map.setCenter(mapCenter);
				this.getTrigger().show();
				if (cookie("map_wheel_zoom") == false) {
					gmaps.map.setOptions({scrollwheel: false});
				}
			}
		});
	},

	// map move handler
	mapMoveHandler: function() {
		
		// presouvaci udalosti jsou docasne vypnute
		if (this.preventMoveEvent) {
			this.preventMoveEvent = false;
			return false;
		}

		// pouze pokud je zoom vetsi nez N pak si natahnem objekty
		if (this.map.getZoom() >= 3) {

			if (gmaps.infowindowOpened) {
				return false;
			}

			if (this.loadStatus > 0) {
				this.loadStatus = 2;
				return false;
			}
			this.loadStatus = 1;
			var bounds = this.map.getBounds();
			var coordSWMapX = bounds.getSouthWest().lng(); // jihozapadni delka
			var coordSWMapY = bounds.getSouthWest().lat(); // jihozapadni sirka
			var coordNEMapX = bounds.getNorthEast().lng(); // severovychodni delka
			var coordNEMapY = bounds.getNorthEast().lat(); // severovychodni sirka
			var center = this.map.getCenter();
			// post pro ajax, predavame pozice, databazi, a filtry ktere mame zvolene,
			// protoze filteru muze byt mnoho zpracujem je jiz v sablone, poku nejsou neposilaji se
			var postData = 'swx=' + coordSWMapX + '&swy=' + coordSWMapY
				+  '&nex=' + coordNEMapX + '&ney=' + coordNEMapY
				+ '&lat=' + center.lat() + '&lng=' + center.lng()
				+ '&zoom=' + this.map.getZoom();
			$.ajax({
				type: 'POST',
				data: postData,
				url: gmaps.ajaxUrl,
				success: function (data) {
					var mapObjects = eval('(' + data + ')');
					if (gmaps.onObjects) {
						gmaps.onObjects(mapObjects);
					}
					gmaps.setObjectsToMap(mapObjects);
					gmaps.loadStatus = 0;
				}
			});
		}
		return true;
	},

	// Prida do mapy ikony pro jednotlive zadane body
	setObjectsToMap: function (mapObjects) {
		if (!mapObjects.length) {
			return;
		}
		// pridam pouze objekty, ktere tam nejsou
		// tim zabranim blikani
		// nefunguje kvuli neunikatnim ID
		for (id in this.markers) {
			if (this.markers[id] === undefined) {
				continue;
			}
			this.markers[id].set("remove", true);
		}
		for (var i = 0; i < mapObjects.length; i++) {
			if (this.markers[mapObjects[i].id] === undefined) {
				var marker = gmaps.createObjectMarker(mapObjects[i]);
				marker.setMap(this.map);
				marker.set("remove", false);
				this.markers[mapObjects[i].id] = marker;
			} else {
				this.markers[mapObjects[i].id].set("remove", false);
			}
		}
		for (id in this.markers) {
			if (this.markers[id] === undefined) {
				continue;
			}
			if (this.markers[id].get("remove")) {
				this.markers[id].setMap(null);
				this.markers[id] = undefined;
				delete(this.markers[id]);
			}
		}
		
	},


	// Manipulace s body v mape a jejich ikonami

	// Vytvori ikonu pro objekty typu Marker apod.
	createIcon: function(iconUrl, width, height) {
		return new google.maps.MarkerImage(
			iconUrl,
			new google.maps.Size(width, height),
			// The origin for this image is 0,0.
			new google.maps.Point(0,0),
			// The anchor for this image is the base of the flagpole at 0,32.
			new google.maps.Point(12, 31)
		);
	},

	// Vytvori marker (i/konu v mape)
	createMarker: function(id, latitude, longitude, text, icon,
			shadow, openInfoWindow) {
		var point = new google.maps.LatLng(latitude, longitude);
		
		var marker = new google.maps.Marker({
			position: point,
			shadow: shadow,
			icon: icon
		});

		marker.set("id", id);

		if(gmaps.infowindowOpeneable) {
			google.maps.event.addListener(marker, 'click', function() {
				gmaps.infowindow.setContent(text);
				gmaps.infowindowOpened = true;
				gmaps.infowindow.open(gmaps.map, marker);
			});
		}
		if (openInfoWindow) {
			gmaps.infowindow.setContent(text);
			gmaps.infowindowOpened = true;
			gmaps.infowindow.open(gmaps.map, marker);
		}
		return marker;
	},

	// Vytvori ikonu pro objekty typu Marker atd. z dat ve strukture mapObject
	createObjectIcon: function(mapObject) {
		return this.createIcon(mapObject.iconUrl, 24, 31);
	},
	// Vytvori stin pro objekty typu Marker atd. z dat ve strukture mapObject
	createObjectShadow: function(mapObject) {
		return this.createIcon(mapObject.iconShadowUrl, 32, 31);
	},

	// Vytvori marker (ikonu v mape) z dat ve strukture mapObject
	createObjectMarker: function(mapObject) {
		return this.createMarker(
			mapObject.id,
			mapObject.latitude, 
			mapObject.longitude,
			gmaps.createObjectInfoWindowContent(mapObject),
			gmaps.createObjectIcon(mapObject),
			gmaps.createObjectShadow(mapObject),
			mapObject.openInfoWindow
		);
	},

	// Vytvori obsah bubliny u ikony z dat v mapObjectu
	createObjectInfoWindowContent: function(mapObject) {
		if (mapObject.infoWindowText) {
			return mapObject.infoWindowText;
		}
		return (gmaps.serverLogo ? '<img width="53" height="14" style="margin: 0 7px 0 0;" src="' + gmaps.serverLogo + '" alt="logo" />' : '')
			+ (mapObject.type ? '<span style="position: relative; top: -3px; font-size: 80%;">' + mapObject.type + '</span>' : '')
			+ (mapObject.title ? '<h4 style="margin: 3px 0pt 0pt; font-size: 100%;">' + mapObject.title + '</h4>' : '')
			+ (mapObject.address ? '<div style="margin: 3px 0pt; font-size: 11px;">' + mapObject.address + '</div>' : '')
			+ (mapObject.link ? '<a class="g-link-more" href="' + mapObject.link + '">Podrobné informace</a>' : '');
	},

	// hledani a spol
	mapSearch: function(address) {
		this.removeMarkers();

		var clearResults = function() {
			$('#map-search-results').hide();
			$('#map-search-results ul').remove();
			gmaps.removeMarkers();
		}

		var addPoint = function(id, placemark) {
			var coord = placemark.geometry.location;
			var marker = gmaps.createMarker(id, coord.lat(), coord.lng(), placemark.formatted_address);
			marker.setMap(gmaps.map);
			gmaps.markers[id] = marker;
			return new google.maps.LatLng(coord.lat(), coord.lng());
		}

		var addResultToPage = function(placemark, point) {
			var $link = $('<a href=""></a>');
			$link.text(placemark.formatted_address);
			$link.click(function() {
				clearResults();
				gmaps.map.setCenter(point);
				gmaps.map.setZoom(16);
				return false;
			});
			var $li = $('<li></li>');
			$li.append($link);
			$('#map-search-results ul').append($li);
		}

		clearResults();

		var geocoder = new google.maps.Geocoder();
		geocoder.geocode(
			{ "address": address},
			function(results, status) {
				// nenalezeno
				if (
					(status != google.maps.GeocoderStatus.OK) ||
					results.length == 0
				) {
					alert(address + ' not found'); // XXX
					return;
				}
				
				var point;

				// nalezen jeden bod
				if (results.length == 1) {
					point = addPoint('point-1', results[0])
					gmaps.map.setCenter(point);
					gmaps.map.setZoom(15);
					return;
				}
				
				gmaps.preventMoveEvent = true;

				// nalezeno vice bodu
				$('#map-search-results').append($('<ul></ul>'))
					.show();
				var bounds = new google.maps.LatLngBounds();

				var index = 0;
				for (var i in results) {
					var placemark = results[i];
					point = addPoint('point-' + ++index , placemark);
					bounds.extend(point);

					addResultToPage(placemark, point);
				}
				gmaps.map.fitBounds(bounds);
			});
	}
}

