	function PlaceClass(placeID, lat, lng, name, imageName, resizeImage, imageWidth, imageHeight, overlay) {
		this.placeID	= placeID;

		this.lat	= lat;
		this.lng	= lng;

		this.name	= name;

		this.imageName		= imageName;
		this.resizeImage	= resizeImage;
		this.imageWidth		= imageWidth;
		this.imageHeight	= imageHeight;

		this.overlay	= overlay;
	}

	var MapClass = new function() {
		this.GoogleMap	= null;
		this.placeHash	= new hashTable();

		this.imgPath	= "resize/";
		this.localTag	= new arrList();

		this.newMap = function(id, lat, lng, level) {
			if (GBrowserIsCompatible()) {
				MapClass.GoogleMap = new GMap2(document.getElementById(id));
				MapClass.GoogleMap.addControl(new GLargeMapControl());
				MapClass.GoogleMap.addControl(new GMapTypeControl());
				MapClass.GoogleMap.enableDoubleClickZoom();
				MapClass.GoogleMap.enableContinuousZoom();
				GEvent.addListener(MapClass.GoogleMap, "moveend", function() {
					MapClass.loadPlace();
				});
				GEvent.addListener(MapClass.GoogleMap, "click", function(overlay, point) {
					MenuClass.closeMenu();
				});
				GEvent.addListener(MapClass.GoogleMap, "dragstart", function() {
					MenuClass.closeMenu();
				});
				MapClass.GoogleMap.setCenter(new GLatLng(lat, lng), level, G_HYBRID_MAP);

				MapClass.placeHash = new hashTable();
				MapClass.loadPlace();
			}
		}
		this.Unload = function() {
			MapClass.placeHash	= new hashTable();
		}

		this.zoom = function(level, mousePos) {
			if(mousePos != undefined) {
				MapClass.GoogleMap.setCenter(MapClass.fromPointToLatLng(mousePos), level);
				return;
			}
			MapClass.GoogleMap.setZoom(level);
		}
		this.zoomIn = function(mousePos, level) {
			if(mousePos != undefined) {
				if(level == undefined)
					level = MapClass.GoogleMap.getZoom() + 1;
				MapClass.zoom(level, mousePos);
				return;
			}
			MapClass.GoogleMap.zoomIn();
		}
		this.zoomOut = function(mousePos, level) {
			if(mousePos != undefined) {
				if(level == undefined)
					level = MapClass.GoogleMap.getZoom() - 1;
				MapClass.zoom(level, mousePos);
				return;
			}
			MapClass.GoogleMap.zoomOut();
		}

		this.loadPlace = function() {
			if(MapClass.GoogleMap.getZoom() < 16)
				return;

			var bounds = MapClass.GoogleMap.getBounds();
			var southWest = bounds.getSouthWest();
			var northEast = bounds.getNorthEast();
			var lngDelta = (northEast.lng() - southWest.lng()) / 2;
			var latDelta = (northEast.lat() - southWest.lat()) / 2;

			var parameter = "";
			parameter += "southWestLng=" + (southWest.lng() - lngDelta);
			parameter += "&southWestLat=" + (southWest.lat() - latDelta);
			parameter += "&northEastLng=" + (northEast.lng() + lngDelta);
			parameter += "&northEastLat=" + (northEast.lat() + latDelta);

			makeHttpRequest("browser/loadPic.php", "MapClass.loadPlace_CallBack", true, "POST", parameter);
		}
		this.loadPlace_CallBack = function(responseXML) {
			MapClass.localTag.clear();

			var place = responseXML.documentElement.firstChild;
			while(place != null) {
				MapClass.addNewPlace(place);

				place = place.nextSibling;
			}

			MapClass.refreshRightframe();
		}
		this.addNewPlace = function(place) {
			try {
				var maxImage = parseInt(Math.pow(2.0, parseFloat(18 - MapClass.GoogleMap.getZoom())));

				var placeID = parseInt(place.getElementsByTagName("PlaceID")[0].firstChild.nodeValue);

				if(MapClass.placeHash.containsKey(placeID)) {
					MapClass.addLocalTag(placeID);
					return false;
				}

				var lat = parseFloat(place.getElementsByTagName("Latitude")[0].firstChild.nodeValue);
				var lng = parseFloat(place.getElementsByTagName("Longitude")[0].firstChild.nodeValue);
				var oldLatLng = new GLatLng(lat, lng);

				try {
					var name = unescape(place.getElementsByTagName("Name")[0].firstChild.nodeValue);
				} catch (e) {
					var name = "";
				}

				var imageName = place.getElementsByTagName("Image")[0].firstChild.nodeValue;
				var resizeImage = place.getElementsByTagName("ResizeImage")[0].firstChild.nodeValue;

				var imageWidth = parseInt(place.getElementsByTagName("ImageWidth")[0].firstChild.nodeValue);
				var imageHeight = parseInt(place.getElementsByTagName("ImageHeight")[0].firstChild.nodeValue);

				var resizeImageName = MapClass.imgPath + resizeImage;

				var point = MapClass.GoogleMap.fromLatLngToDivPixel(oldLatLng);
				var newLatLng = MapClass.GoogleMap.fromDivPixelToLatLng(new GPoint(point.x + imageWidth / maxImage, point.y + imageHeight / maxImage));

				var rectBounds = new GLatLngBounds(newLatLng, oldLatLng);

				var overlay = new PlaceRectangle(rectBounds, placeID, resizeImageName);

				MapClass.GoogleMap.addOverlay(overlay);

				MapClass.placeHash.put(placeID, new PlaceClass(placeID, lat, lng, name, imageName, resizeImage, imageWidth, imageHeight, overlay));
				MapClass.addLocalTag(placeID);

				return true;
			} catch (e) {
				return false;
			}
		}
		this.addLocalTag = function(placeID) {
			var place = MapClass.placeHash.get(placeID);

			var bounds = MapClass.GoogleMap.getBounds();
			var southWest = bounds.getSouthWest();
			var northEast = bounds.getNorthEast();

			if(southWest.lat() > place.lat || northEast.lat() < place.lat)
				return false;
			if(southWest.lng() > place.lng || northEast.lng() < place.lng)
				return false;

			MapClass.localTag.add(place);
			return true;
		}

		this.getNorthWestPoint = function() {
			return new GPoint(
					MapClass.GoogleMap.fromLatLngToDivPixel(MapClass.GoogleMap.getBounds().getSouthWest()).x,
					MapClass.GoogleMap.fromLatLngToDivPixel(MapClass.GoogleMap.getBounds().getNorthEast()).y);
		}
		this.fromMapPointToLatLng = function(point) {
			var northWestPoint = MapClass.getNorthWestPoint();
			return MapClass.GoogleMap.fromDivPixelToLatLng(
					new GPoint(
						northWestPoint.x + point.x,
						northWestPoint.y + point.y));
		}
		this.fromPointToLatLng = function(point) {
			var mapObj = document.getElementById("map");
			var mapPos = getObjPos(mapObj);
			return MapClass.fromMapPointToLatLng(new GPoint(point.x - mapPos.x, point.y - mapPos.y));
		}
		this.fromLatLngToPoint = function(latLng) {
			var mapObj = document.getElementById("map");
			var mapPos = getObjPos(mapObj);

			var northWestPoint = MapClass.getNorthWestPoint();
			var point = MapClass.GoogleMap.fromLatLngToDivPixel(latLng);

			return new GPoint(point.x - northWestPoint.x + mapPos.x, point.y - northWestPoint.y + mapPos.y);
		}

		this.getCenterFromPlace = function(place) {
			var maxImage = parseInt(Math.pow(2.0, parseFloat(18 - MapClass.GoogleMap.getZoom())));

			var oldLatLng = new GLatLng(place.lat, place.lng);

			var imageWidth = parseInt(place.imageWidth / maxImage);
			var imageHeight = parseInt(place.imageHeight / maxImage);

			var northWestPoint = MapClass.getNorthWestPoint();
			var point = MapClass.GoogleMap.fromLatLngToDivPixel(oldLatLng);
			return new GPoint(point.x + imageWidth / 2 - northWestPoint.x, point.y + imageHeight / 2 - northWestPoint.y);
		}
		this.getPlaceCenter = function(placeID) {
			if(!MapClass.placeHash.containsKey(placeID))
				return null;

			return MapClass.getCenterFromPlace(MapClass.placeHash.get(placeID));
		}
		this.removeOverlay = function(placeID) {
			MapClass.GoogleMap.removeOverlay(MapClass.placeHash.get(placeID).overlay);
			MapClass.placeHash.remove(placeID);
		}

		this.refreshRightframe = function() {
			//if(Math.random() * 5 <= 1) {
				var str = "";
				var tagArr = MapClass.localTag.copy();
				while(tagArr.count() > 0) {
					var ran = Math.floor(Math.random() * tagArr.count());
					str += tagArr.getAt(ran).placeID + ",";
					tagArr.removeAt(ran);
				}

				//document.getElementById('rightframe').src = 'frame/rightframe.php?q=' + str;
				showPlace(str);
			//}
		}
		this.panTo = function(placeID, lat, lng, imageWidth, imageHeight) {
			var point = MapClass.getPlaceCenter(placeID);
			if(point == null) {
				point = MapClass.getCenterFromPlace(new PlaceClass(placeID, lat, lng, "", "", "", imageWidth, imageHeight, ""));
			}

			MapClass.GoogleMap.panTo(MapClass.fromMapPointToLatLng(point));
		}
	}

	function PlaceRectangle(bounds, placeID, img) {
		this.bounds_ = bounds;
		this.placeID_ = placeID;
		this.img_ = img;
	}
	PlaceRectangle.prototype = new GOverlay();
	// Creates the DIV representing this PlaceRectangle.
	PlaceRectangle.prototype.initialize = function(map) {
		// Create the DIV representing our rectangle
		var div = document.createElement("div");
		div.style.position = "absolute";
		div.innerHTML = "<div style='border-width:1px; border-style:solid; border-color:#FFFFFF; cursor: pointer;' onclick='return MenuClass.openMenuPlace(event, " + this.placeID_ + ");' onmouseover='return HintClass.placeOver(event, " + this.placeID_ + ");' onmouseout='return HintClass.clearPlace();' onblur='return HintClass.clearPlace();'>"
							+ "<img onmouseover='this.style.borderStyle=\"solid\"; this.style.borderColor=\"#FFFF00\"; this.style.borderWidth=\"1px\";' onmouseout='this.style.borderStyle=\"solid\"; this.style.borderColor=\"#000000\"; this.style.borderWidth=\"1px\"; ' src='"+ this.img_ +"' border='1' style='border-color:#000000' />"
						+ "</div>";
		// Our rectangle is flat against the map, so we add our selves to the
		// MAP_PANE pane, which is at the same z-index as the map itself (i.e.,
		// below the marker shadows)
		map.getPane(G_MAP_MARKER_PANE).appendChild(div);
		this.map_ = map;
		this.div_ = div;
	}
	// Remove the main DIV from the map pane
	PlaceRectangle.prototype.remove = function() {
		this.div_.parentNode.removeChild(this.div_);
	}
	// Copy our data to a new Rectangle
	PlaceRectangle.prototype.copy = function() {
		return new Rectangle(this.bounds_, this.placeID_, this.img_);
	}
	// Redraw the rectangle based on the current projection and zoom level
	PlaceRectangle.prototype.redraw = function(force) {
		// We only need to redraw if the coordinate system has changed
		if (!force) return;
		// Calculate the DIV coordinates of two opposite corners of our bounds to
		// get the size and position of our rectangle
		var c1 = this.map_.fromLatLngToDivPixel(this.bounds_.getSouthWest());
		var c2 = this.map_.fromLatLngToDivPixel(this.bounds_.getNorthEast());
		// Now position our DIV based on the DIV coordinates of our bounds
		this.div_.getElementsByTagName("IMG")[0].style.width = this.div_.style.width = Math.abs(c2.x - c1.x) + "px";
		this.div_.getElementsByTagName("IMG")[0].style.height = this.div_.style.height = Math.abs(c2.y - c1.y) + "px";
		this.div_.style.left = Math.min(c2.x, c1.x) + "px";
		this.div_.style.top = Math.min(c2.y, c1.y) + "px";
	}