function MapItem(id, type, strokeColor, fillColor, icon) {
	this.id = id;
	this.type = type;	// 1=icon, 2=line, 3=polygon
	this.strokeColor = strokeColor;
	this.fillColor = fillColor;
	this.icon = icon;
	this.centerLatitude = null;
	this.centerLongitude = null;
	this.zoomLevel = null;

	this.overlay = null;

	// array of GLatLng
	this.points = new Array();
}

var MapUtils = {

	/* Settings */
	gMap		: null,
	gMapType	: G_NORMAL_MAP ,
	gMapCenter	: new GLatLng(22.376110961435952, 114.1204833984375),
	gMapZoom	: 11,

	/* Data */
	items		: new Array(),	/* array of MapItem */
	topics		: {},
	ids			: {},
	subdomain	: {},
	/* Dom */
	menu		: null,

	getGMap: function() {
		return this.gMap;
	},

	display: function(id, centerLatitude, centerLongitude, zoomLevel) {
		var obj = document.getElementById(id);

		if (typeof obj == "object" && GBrowserIsCompatible()) {
			this.gMap = new GMap2(obj);
			this.gMap.setCenter(new GLatLng(centerLatitude, centerLongitude), zoomLevel, this.gMapType);
			this.gMap.addControl(new GSmallMapControl());
			this.gMap.addControl(new GMapTypeControl());
		}

		// better to unload them
		jQuery(window).bind('unload', this.unload);
	},

	load: function(id, str) {
		var obj = document.getElementById(id);

		if (typeof obj == "object" && GBrowserIsCompatible()) {
			this.gMap = new GMap2(obj);
			this.gMap.setCenter(this.gMapCenter, this.gMapZoom, this.gMapType);
			this.gMap.addControl(new GSmallMapControl());
			this.gMap.addControl(new GMapTypeControl());
			// this.gMap.enableContinuousZoom();
			// this.gMap.enableScrollWheelZoom();

			GEvent.addListener(this.gMap, "click",
					function(marker, point) {

						if (marker) {
							MapUtils.getGMap().removeOverlay(marker);
							MapUtils.removePoint(MapUtils.getCurrentItem(), point, marker);
						} else {
							if (MapUtils.items.length >0) {
								MapUtils.addPoint(MapUtils.getCurrentItem(), point);

								if (MapUtils.getCurrentItem().icon != null) {
									var icon = new GIcon();
									var p = window.location.href.split("\/");
									p.splice(p.length-1, 1);
									icon.image = p.join("\/") + "/imgs/admin/emoticons/mark_"+ MapUtils.getCurrentItem().icon +".png";
									icon.shadow = p.join("\/") + "/imgs/admin/emoticons/transparent.png";
									// icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
									icon.iconSize = new GSize(20, 33);
									icon.shadowSize = new GSize(1, 1);
									icon.iconAnchor = new GPoint(18, 38);
									icon.infoWindowAnchor = new GPoint(5, 1);
									MapUtils.getGMap().addOverlay(new GMarker(point, icon));
								} else {
									MapUtils.getGMap().addOverlay(new GMarker(point));
								}
							} else {
								alert(str);
							}
						}
					}
				);
		}

		// better to unload them
		jQuery(window).bind('unload', this.unload);
	},

	unload: function() {
		GUnload();
	},

	setMenu: function(obj) {
		this.menu = obj;
	},

	saveData: function() {
		// this.getCurrentItem().name = jQuery("#itemName").val();
		this.getCurrentItem().description = jQuery("#itemDescription").val();
		this.getCurrentItem().type = jQuery("#itemType").val();
		this.getCurrentItem().strokeColor = jQuery("#itemStrokeColor").val();
		this.getCurrentItem().fillColor = jQuery("#itemFillColor").val();
		this.getCurrentItem().icon = jQuery("#itemIcon").val();
	},

	loadData: function() {
		var item = this.getCurrentItem();
		jQuery("#itemDescription").val( item.description );
		jQuery("#itemType")[0].selectedIndex = item.type - 1;
		jQuery("#itemStrokeColor").val( item.strokeColor );
		jQuery("#itemFillColor").val( item.fillColor );
		jQuery("#itemIcon").val( item.icon );
	},

	setItemType: function(type) {
		this.getCurrentItem().type = type;
	},

	getCurrentItem: function() {
		if ( this.menu.selectedIndex != -1 ) {
			return this.items[this.menu.selectedIndex];
		} else {
			return false;
		}
	},

	newItem : function(type, strokeColor, fillColor, icon ) {
		var item = new MapItem(this.items.length, type, strokeColor,  fillColor, icon );

		this.items.push(item);
		this.currentItem++;
		this.menu.options[this.menu.options.length] = new Option(item.name, item.id);
		this.menu.selectedIndex = this.items.length-1;

		jQuery("#itemType").selectedIndex = 0;
		jQuery("#itemStrokeColor").val( strokeColor );
		jQuery("#itemFillColor").val( fillColor );
		jQuery("#itemIcon").val( type );

		return item;
	},

	removeItem: function(id) {
		var id = this.menu[this.menu.selectedIndex].value;
		for (var i=0; i<this.items.length; i++) {
			if (this.items[i].id == id) {
				this.items.splice(i,1);
				this.menu.options[i] = null;
				return;
			}
		}
	},

	addPoint : function(item, point) {
		var key = point.lat() + "-" + point.lng();
		eval('item.points.push({ "'+key+'": point}) ');
	},

	addPointUrl : function(item, point, subdomain, topics, ids) {
		var key = point.lat() + "-" + point.lng();
		eval('item.points.push({ "'+key+'": point}) ');
		this.topics[key] = topics;
		this.ids[key] = ids;
		this.subdomain[key] = subdomain;
	},

	removePoint	: function(item, point, marker) {
		// this.clear();
		var key = marker.getPoint().lat() + "-" + marker.getPoint().lng();
		for (var i=0; i<item.points.length; i++) {
			var type = eval('typeof item.points[i]["'+key+'"]');
			if (type == "object" ) {
				item.points.splice(i,1);
				return;
			}
		}
	},

	getPointsGLatLng: function(item) {
		var points = new Array();
		for (var i=0; i<item.points.length; i++) {
			for (p in item.points[i]) {
    			points.push( item.points[i][p] );
			}
		}
		return points;
	},

	addMarker: function(item, point, t) {

					var icon = new GIcon();
					var p = window.location.href.split("\/");
					p.splice(p.length-1, 1);
					icon.image = p.join("\/") + "/imgs/admin/emoticons/mark_"+ MapUtils.getCurrentItem().icon +".png";
					icon.shadow = p.join("\/") + "/imgs/admin/emoticons/transparent.png";
					// icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
					icon.iconSize = new GSize(20, 33);
					icon.shadowSize = new GSize(1, 1);
					icon.iconAnchor = new GPoint(18, 38);
					icon.infoWindowAnchor = new GPoint(5, 1);

					if (t==1) {
						icon.image = p.join("\/") + "/imgs/admin/emoticons/mark_3.png";
						icon.iconSize = new GSize(24, 42);
						icon.iconAnchor = new GPoint(20, 45);
					}

					var marker;
					if (item.type==1) {
						marker = new GMarker(point, icon);
					} else if (item.type==2) {
						var opt = new Object();
						opt.icon=icon;
						opt.title="點擊這條線";
						marker = new GMarker(point, opt);
					} else {
						var opt = new Object();
						opt.icon=icon;
						opt.title="點擊這面框";
						marker = new GMarker(point, opt);
					}

					GEvent.addListener(marker, "click", function() {

							var key = point.lat() + "-" + point.lng();
							var topics = MapUtils.topics[key].split(",");
							var ids = MapUtils.ids[key].split(",");
							if (topics.length==1) {
								window.open("http://"+MapUtils.subdomain[key]+".wanchaiinfo.hk/index.php?op=ViewArticle&articleId=" + ids[0]);
									// top.location.href="http://"+MapUtils.subdomain+".wanchaiinfo.hk/index.php?op=ViewArticle&articleId=" + ids[0];
							} else {
								var str = "";
								for(var i=0; i<topics.length ;i++) {
									if (i==5){break}
									str += " <div style='font-size:11px'> " + (i+1) + ". <a target='_blank' style='font-size:11px;color:#339999;font-family: Arial, Helvetica, sans-serif;' href='http://"+MapUtils.subdomain[key]+".wanchaiinfo.hk/index.php?op=ViewArticle&articleId="+ ids[i] + "'>" + topics[i] + "</a><div>";
								}
								marker.openInfoWindowHtml(str);
							}

							MapUtils.getGMap().removeOverlay(marker);
							MapUtils.addMarker(item, point, 1);

						}
					);
					MapUtils.getGMap().addOverlay(marker);
	},

	addPoints: function(item) {
		if (item.overlay != null ) {
			this.gMap.removeOverlay(item.overlay);
		}
		for (var i=0; i<item.points.length; i++) {
			for (t in item.points[i]) {
				var point = item.points[i][t];
				if (MapUtils.getCurrentItem().icon != null) {

					this.addMarker(item, point, 0);


				} else {
					MapUtils.getGMap().addOverlay(new GMarker(point));
				}
			}
		}
	},

	addLine: function(item) {
		if (item.overlay != null) {
			this.clear(item);
		}

		item.overlay = new GPolyline(this.getPointsGLatLng(item), item.strokeColor, 5);
		this.gMap.addOverlay(  item.overlay  );
	},

	addPolygon: function(item) {
		if (item.overlay != null) {
			this.clear(item);
		}

		var points = this.getPointsGLatLng(item);
		points[points.length] = points[0];	// join the points

		item.overlay = new GPolygon(points, "#000000", 3,
									1, item.fillColor, 0.5);

		this.gMap.addOverlay( item.overlay );
	},

	clear	: function(item) {
		this.gMap.removeOverlay(item.overlay);
		item.points = Array();
	},

	clearAll: function() {
		this.gMap.clearOverlays();
		this.getCurrentItem().points = new Array();

	},

	debug: function() {
		console.debug( this.items );
	},

	render: function() {
		if ( jQuery("#itemStrokeColor").val() != null ) {
			this.getCurrentItem().strokeColor = jQuery("#itemStrokeColor").val();
		}

		if ( jQuery("#itemFillColor").val() != null ) {
			this.getCurrentItem().fillColor = jQuery("#itemFillColor").val();
		}
		if (this.getCurrentItem().type ==1) {
			this.addPoints(this.getCurrentItem());
		} else if (this.getCurrentItem().type == 2) {
			this.addLine(this.getCurrentItem());
		} else if (this.getCurrentItem().type == 3) {
			this.addPolygon(this.getCurrentItem());
		}
	},

	renderMore: function() {

		if ( this.getCurrentItem().type == 2 ||  this.getCurrentItem().type == 3) {
				this.getCurrentItem().points.splice(0,this.getCurrentItem().points.length-1);
				this.getCurrentItem().overlay = null;
				if ( this.getCurrentItem().type == 2) {
					this.getCurrentItem().icon=99;
				} else {
					this.getCurrentItem().icon=98;
				}
				this.addPoints(this.getCurrentItem());
		}

	},

	useIcon: function(iconId) {
		jQuery(".mapIcon").css("background-color", "#ffffff");
		jQuery("#mapIcon"+iconId).css("background-color", "#dedede");
		this.getCurrentItem().icon = iconId;
	},

	finish: function(obj, msg) {
		this.items[0].centerLatitude =  this.gMap.getCenter().y;
		this.items[0].centerLongitude =  this.gMap.getCenter().x;
		this.items[0].zoomLevel = this.gMap.getZoom();
		this.items[0].overlay = "";

		if (jQuery("#mapName").val() == "" || this.items[0].points.length ==0) {
			alert(msg); jQuery("#mapName").focus();
		} else {
			jQuery("#jsonMapItems").val( JSON.stringify( this.items[0] ) );
			obj.submit();
		}
	}
}
