function CityMap() {
	// Get attachment method
	// Normal version
	var hook = function(object, event, callback, phase) {
		object.addEventListener(event, callback, phase);
	};

	// Lame version
	if (typeof window.addEventListener == 'undefined') {
		hook = function(object, event, callback, phase) {
			object.attachEvent('on' + event, callback);
		};
	};
	
	function CityMap(container) {
		var managers = [];
		var tagged_markers = {};
		var gmap;
		var settings = {region_zoom: 13};
	
		function Initialize(lat, lng, z) {
			gmap = new GMap2(container);
			gmap.setCenter(new GLatLng(lat, lng), z);
			gmap.setUIToDefault();
		}
	
		function AddMarkers(markers, z_min, z_max) {
			var manager = new MarkerManager(gmap);
			manager.addMarkers(markers,z_min,z_max);
			managers.push(manager);
			manager.hide();
			return manager;
		}
		
		// Add marker group
		function AttachMarkerEvent(marker, event, callback) {
			GEvent.addListener(marker.marker, event, callback);
			for (var i=0; i<marker.handles.length; i++)
				GEvent.addDomListener(marker.handles[i], event, callback);
		}
		
		// Attach handlers
		function MakeHoverable(hover_src, normal_src, marker) {
			AttachMarkerEvent(marker, "mouseover", function () { marker.marker.setImage(hover_src); });
			AttachMarkerEvent(marker, "mouseout", function () { marker.marker.setImage(normal_src); });
		}
		
		function MakeZoomable(zoom, marker) {
			AttachMarkerEvent(marker, "click", function () { 
				gmap.setCenter(marker.marker.getLatLng(), zoom);
			});
		}
		
		function MakePopup(text, marker) {
			AttachMarkerEvent(marker, "click", function () { 
				marker.marker.openInfoWindowHtml(text);
			});
		}
		
		var active_managers = {}
		function MakeShower(manager, key, marker) {
			AttachMarkerEvent(marker, "click", function () {
				if (typeof active_managers.key != 'undefined')
					active_managers.key.hide()
				manager.show();
				active_managers.key = manager;
			});
		}
		
		function Marker(lat, lng, icon) {
			var marker = {};
			marker.marker = new GMarker(new GLatLng(lat, lng), {icon: icon});
			marker.handles = [];
			return marker;
		}
		
		function Regions(regions, region_zoom) {
			var region_markers = [], region_marker;
			var local_markers, local_marker;
			var region, point;
			var i,j;
			for (i=0; i < regions.length; i++) {
				region = regions[i];
				
				region_marker = Marker(region.lat, region.lng, region.icon);
				if (region.handle)
					region_marker.handles.push(region.handle);

				MakeHoverable(region.hover, region.icon.image, region_marker);
				MakeZoomable(region_zoom, region_marker);
				local_markers = []
				for (j=0; j < region.points.length; j++) {
					point = region.points[j];
					local_marker = Marker(point.lat, point.lng, point.icon);
					MakePopup(point.text, local_marker);
					local_markers.push(local_marker.marker);
				}
				MakeShower(AddMarkers(local_markers, region_zoom, 17), 'poop', region_marker);
				region_markers.push(region_marker.marker);
			}
			AddMarkers(region_markers, 0, region_zoom-1).show();			
		}
		
		return {
			Initialize: Initialize,
			Settings: function() { return settings; },
			Regions: Regions
			}
	};
	
	return {
		CityMap: CityMap
	};
}

if (GBrowserIsCompatible()) {
	var cm = CityMap();
	window.onload = function () {
		var map = cm.CityMap(document.getElementById('map'));
		map.Initialize(59.934800, 30.313300, 10)
		var icon = new GIcon(G_DEFAULT_ICON);
		icon.image = "/map/marker.png";
		icon.shadow = "";
		icon.iconSize = new GSize(65, 53);
		icon.iconAnchor = new GPoint(65, 53);
		icon.imageMap = [0,0,0,65,65,65,65,0];

		var region_map = [0,0,0,75,75,75,75,0];
		var region_anchor = new GPoint(75, 75);
		var region_size = new GSize(75, 75);
		
		var area_icon;
		var i,j,k;
		var regions = [];
		for (i=0; i<data.length; i++) {
			var region = {};
			regions.push(region);
			var reigon_details = data_areas[data[i][0]];
			region.handle = document.getElementById(reigon_details[3]);
			if (region.handle) {
				region.handle.innerHTML = data[i][1];
			}
			region.title = data[i][1];
			region.lat = data[i][2];
			region.lng = data[i][3];
			
			region.icon = new GIcon(G_DEFAULT_ICON);
			region.icon.image = reigon_details[1];
			region.icon.shadow = "";
			region.icon.iconSize = region_size;
			region.icon.iconAnchor = region_anchor;
			region.icon.imageMap = region_map;
			region.hover=reigon_details[2];
			
			region.points = [];
			var points = data[i][4];
			for (j=0; j<points.length; j++) {
				var point = {};
				region.points.push(point);
				point.lat = points[j][3];
				point.lng = points[j][4];
				point.icon = icon;
				point.text = '<div><h1>' + points[j][0] + 
				             '</h1><p>' + points[j][1] +
				             '</p><p>' + points[j][2]  + '</p></div>';
			}
		}
		map.Regions(regions, 13);
	}
}