var serviceIcons = [];

function initIcons() {
	var dIcon = new GIcon();
	dIcon.shadow = "/images/map_services/shadow.png";
	dIcon.iconSize = new GSize(19, 23);
	dIcon.shadowSize = new GSize(35, 23);
	dIcon.iconAnchor = new GPoint(9, 23);
	dIcon.infoWindowAnchor = new GPoint(19, 0);
	dIcon.infoShadowAnchor = new GPoint(19, 12);
	for (var i = 1; i < 12; i++) {
		serviceIcons[i] = new GIcon(dIcon);
		serviceIcons[i].image = "/images/map_services/" + i + ".gif";
	}
}



var mMap = {
	createMap: function(obj, params) {
		obj = $(obj);
		var me = this;
		if (!$isdef(params.marker)) params.marker = {};
		if (!$isdef(params.data)) params.data = {};
		if (GBrowserIsCompatible()) {
			var lat = 55.755351248757826;
			var lng = 37.6171875;
			if (params.latlng) {
				lat = params.latlng.lat;
				lng = params.latlng.lng;
			}
			var zoom = (params.zoom ? params.zoom : 13);
			me.map = new GMap2(obj);
			me.map.setCenter(new GLatLng(lat, lng), zoom);
			if (($isdef(params.simpleMap) ? !params.simpleMap : true)) {
				me.map.addControl(new GMapTypeControl());
				me.map.addControl(new GLargeMapControl());
				me.map.addControl(new GScaleControl());
			} else {
				me.map.addControl(new GSmallMapControl())
				$(obj, "*")[1].style.display = "none";
			}
			me.map.enableDoubleClickZoom();
			me.map.enableContinuousZoom();
		} else {
			hide($(obj));
			if (params.onCrash) {
				params.onCrash();
			}
			return null;
		}
		if (params.marker.canAdd) {
			var markerAdded = false;
			var mIcon = new GIcon();
			mIcon.image = "/images/map_services/new.gif";
			mIcon.iconSize = new GSize(19, 23);
			mIcon.iconAnchor = new GPoint(9, 23);
			if (params.marker.icon) {
				mIcon.image = params.marker.icon.link;
				if (params.marker.icon.size) {
					mIcon.iconSize = new GSize(params.marker.icon.size.x, params.marker.icon.size.y);
				}
				if (params.marker.icon.anchor) {
					mIcon.iconAnchor = new GPoint(params.marker.icon.anchor.x, params.marker.icon.anchor.y);
				}
			}
			mIcon.shadow = "/images/map_services/shadow.png";
			mIcon.shadowSize = new GSize(35, 23);
			if (params.marker.shadow) {
				mIcon.shadow = params.marker.shadow.link;
				if (params.marker.icon.size) {
					mIcon.shadowSize = new GSize(params.marker.shadow.size.x, params.marker.shadow.size.y);
				}
			}
			var mOptions = { icon: mIcon }
			if (params.marker.canMove) {
				mOptions['draggable'] = true;
			}
			me.marker = new GMarker(me.map.getCenter(), mOptions);
			var onChange = params.marker.onChange ? params.marker.onChange : Function.empty;
			if (params.marker.canMove) {
				GEvent.addListener(me.marker, "dragend", function() {
					var latlng = me.marker.getLatLng();
					onChange(latlng);
				});
			}
			me.addMarker = function (latlng) {
				if (markerAdded) return false;
				markerAdded = true;
				if (!$isdef(latlng)) {
					var latlng = me.map.getCenter();
				}
				me.marker.setLatLng(latlng);
				me.map.addOverlay(me.marker);
				if (params.marker.onAdd) {
					params.marker.onAdd();
				}
				onChange(latlng);
				if (params.marker.canMoveByClick) {
					me.hMoveClick = GEvent.addListener(me.map, "click", function(overlay, latlng) {
						if (overlay == null) {
							me.marker.setLatLng(latlng);
							onChange(latlng);
						}
					});
				}
			}
			if (params.marker.canAddByClick) {
				me.hAddClick = GEvent.addListener(me.map, "click", function(overlay, latlng) {
					if (overlay == null) {
						me.addMarker(latlng);
						GEvent.removeListener(me.hAddClick);
					}
				});
			}
			if (params.marker.canDel) {
				me.delMarker = function () {
					if (!markerAdded) return;
					markerAdded = false;
					me.map.removeOverlay(me.marker);
					if (params.marker.onDel) {
						params.marker.onDel();
					}
					if (params.marker.canMoveByClick) {
						GEvent.removeListener(me.hMoveClick);
					}
					if (params.marker.canAddByClick) {
						me.hAddClick = GEvent.addListener(me.map, "click", function(overlay, latlng) {
							if (overlay == null) {
								me.addMarker(latlng);
								GEvent.removeListener(me.hAddClick);
							}
						});
					}
				}
			}
			if (params.marker.latlng) {
				me.addMarker(new GLatLng(params.marker.latlng.lat, params.marker.latlng.lng));
				me.map.setCenter(new GLatLng(params.marker.latlng.lat, params.marker.latlng.lng), me.map.getZoom());
			}
		}
		if (params.canSearch) {
			me.geoCoder = new GClientGeocoder();
			me.search = function (address) {
				me.geoCoder.getLatLng(address, function(latlng) {
					if (latlng == null) {
						if (params.onSearchFail) {
							params.onSearchFail(address);
						}
					} else {
						me.map.setCenter(latlng);
					}
				});
			}
		}
		if (params.data.canLoad) {
			initIcons();
			me.data = {
				markers: {},
				zoomLimit: 10,
				showM: [true, true, true, true, true, true, true, true, true, true, true, true]
			}

			var load = function () {
				var zoom = me.map.getZoom();
				if (zoom > me.data.zoomLimit) {
					var bounds = me.map.getBounds();
					var sw = bounds.getSouthWest();
					var ne = bounds.getNorthEast();
					$ajax.request({
						url: params.data.link,
						method: 'get',
						data: {
							sw_lat: sw.lat(),
							sw_lng: sw.lng(),
							ne_lat: ne.lat(),
							ne_lng: ne.lng()
						},
						onSuccess: function(data, raw) {
							if (data) {
								for(var i in data) {
									if (me.data.markers[i]) {
										continue;
									} else {
										me.data.markers[i] = data[i];
										me.data.markers[i].object = mMap.createMarker(me.data.markers[i]);
										me.map.addOverlay(me.data.markers[i].object);
										me.data.markers[i].object[me.data.showM[me.data.markers[i].type] ? "show" : "hide"]();
									}
								}
							}
						}
					});
				}
			}
			me.reShow = function (_showM) {
				me.data.showM = _showM
				for (var i in me.data.markers) {
					me.data.markers[i].object[me.data.showM[me.data.markers[i].type] ? "show" : "hide"]();
				}
			}
			GEvent.addListener(me.map, "moveend", load);
			load();
		}
		return this;
	},
	createMarker: function(data) {
		var options = {
			title: data.name,
			icon: serviceIcons[data.type]
		}
		var marker = new GMarker(new GLatLng(data.lat, data.lng), options);
		GEvent.addListener(marker, "click", function() {
			marker.openInfoWindowHtml('<div class="infoWindow" style="width: 300px;"><a href="' + data.link + '">' + data.name + '</a> (' + data.comments + ')<br /><br />' + data.text + '</div>', {maxWidth: 300});
		});
		return marker;
	}
}