(
	function($)
	{
		$.jMap = $.jMap || {};

		$.fn.extend(
		{
			jMap : function(poi, opts)
			{
				if (poi && (poi.css != undefined || poi.zoom != undefined || poi.scale != undefined || poi.overview != undefined || poi.click != undefined || poi.flow != undefined || poi.wheel != undefined || poi.logo != undefined || poi.copyright != undefined || poi.scaleLevel != undefined || poi.contains != undefined || poi.poiCallback != undefined || poi.overFn != undefined || poi.outFn != undefined))
				{
					opts = poi;
					poi = null;
				}
				if (!poi) poi = [];
				if (poi.constructor != Array) poi = [poi];
				return this.each
				(function(i){
					$.jMap.init(this, poi[i], opts);
				});
			},
			jMapPoint : function(poi, opts)
			{
				if (!poi) poi = [];
				if (poi.constructor != Array) poi = [poi];
				return this.each
				(function(i){
					$.jMap.addPoint(this, poi[i], opts);
				});
			}
		});



		/********************************************************************************************************/

		$.jMap.init = function(obj, poi, opts)
		{
				if (!obj) return;
				opts = opts || {};
				var $obj = $(obj).css($.jMap.settings.css);
				if (opts.css) $obj.css(opts.css);
				var map = $.jMap.getMap(obj, opts.hold);
				if (!map) return;
				if (opts.zoom) map.addControl(opts.zoom == 1 ? new GLargeMapControl() : opts.zoom == 2 ? new GSmallMapControl() : new GSmallZoomControl());
				if (opts.scale) map.addControl(new GScaleControl(), new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(opts.logo ? 68 : 7, 4)));
				if (opts.overview) map.addControl(new GOverviewMapControl());
				if (opts.drag != undefined && !opts.drag) map.disableDragging();
				if (opts.click == undefined || opts.click) map.enableDoubleClickZoom();
				if (opts.flow == undefined || opts.flow) map.enableContinuousZoom();
				if (opts.wheel == undefined || opts.wheel) map.enableScrollWheelZoom();
				try
				{
					var link = $obj.find("span.gmnoprint > a");
					if (opts.logo == undefined || opts.logo) link.after(link.children().clone());
					link.remove();
				}
				catch (e)
				{
				}
				if (opts.copyright == undefined || !opts.copyright){try{$obj.find("div > span,div > a").remove();}catch(e){}}
				poi = $.jMap.checkPOI(poi, $.jMap.settings.center);
				var p = poi[0];
				opts.scaleLevel = p.isDef ? 4 : (opts.scaleLevel != undefined ? opts.scaleLevel : 15);
				map.setCenter(new GLatLng(p.lat, p.lng), opts.scaleLevel);
				if (p.isCenter || p.isDef) poi.shift();
				if (poi.length > 0) $.jMap.addPoint(obj, poi, {contains:opts.contains, overFn:opts.overFn, outFn:opts.outFn, poiCallback : opts.poiCallback});
		};

		$.extend($.jMap ,
		{
			LARGE : {css:{width:"650px",height:"498px"},zoom:1,scale:1,overview:1,copyright:1,scaleLevel:16},
			SMALL : {css:{width:"170px",height:"170px"},click:0,wheel:0},
			settings : 
			{
				digi : 16,
				add : 10,
				plus : 7,
				cha : 36,
				css : {border:"1px solid #333"},
				draggerIconIndex : "dragger",
				draggerText : "拖动此图标在地图上标注位置",
				center : {lat : 34.957995, lng : 107.050781, isDef : true}
			},
			encode : function(jLatLng)
			{
				var apiKey = parseInt(Math.random()*(90-65+1)+65);
				var mLat = parseInt(parseFloat(jLatLng.Lat) * 100000);
				var mLng = parseInt(parseFloat(jLatLng.Lng) * 100000);
				var subLL = (mLng - mLat + parseInt(apiKey)).toString(this.settings.digi);
				var addLL = (mLng + mLat).toString(this.settings.digi);
				var code = "";
				for(var i=0;i<subLL.length;i++)
				{
					var hash = parseInt(subLL.charAt(i), this.settings.digi);
					code += (((hash >= this.settings.add) ? (hash+this.settings.plus) : hash) + this.settings.add).toString(this.settings.cha);
				}
				code += "z";
				for(var i=0;i<addLL.length;i++)
				{
					var hash=parseInt(addLL.charAt(i),this.settings.digi);
					code += (((hash >= this.settings.add) ? (hash + this.settings.plus) : hash) + this.settings.add).toString(this.settings.cha);
				}
				return code.toUpperCase() + String.fromCharCode(apiKey);
			},
			decode : function(poi)
			{
				var index = -1;
				var count = 0;
				var code = "";
				var len = poi.length;
				var apiKey = poi.charCodeAt(len - 1);
				poi = poi.substring(0, len - 1);
				len--;
				for(var i=0;i<len;i++)
				{
					var hash = parseInt(poi.charAt(i), this.settings.cha) - this.settings.add;
					if(hash >= this.settings.add)
					{
						hash = hash - this.settings.plus;
					}
					code += (hash).toString(this.settings.cha);
					if(hash > count)
					{
						index = i;
						count = hash;
					}
				}
				var subLL = parseInt(code.substring(0, index), this.settings.digi);
				var addLL = parseInt(code.substring(index + 1), this.settings.digi);
				var lng = (subLL + addLL - parseInt(apiKey))/2;
				var lat =(addLL- lng)/100000.0;
				lng /= 100000.0;
				return {"lat" : lat, "lng" : lng};
			},
			imgPath : "http://www.mabelle.com",
			icons : function(index)
			{
				var url = this.imgPath + "/gmap/";
				if (typeof index == "string")
				{
					return url + index + ".png";
				}
				else if (typeof index == "number")
				{
					return url + (index % 10 + 1) + ".png";
				}
			},
			getMap : function(obj, hold)
			{
				var map = $.data(obj, "map");
				if (!map || !hold)
				{
					if (GBrowserIsCompatible == undefined || !GBrowserIsCompatible()) return;
					map = new GMap2(obj);
					$.data(obj, "map", map);
				}
				return map;
			},
			checkPOI : function(poi, def)
			{
				if (!poi) poi = new Array(def);
				if (typeof poi == "string") poi = new Array(this.decode(poi));
				if (poi.constructor != Array) poi = new Array(poi);
				var length = poi.length;
				for(var i = 0;i<length;i++)
				{
					var p = poi[i] || "";
					if (p.poi)
					{
						var tmpPOI = this.decode(p.poi);
						p.lat = tmpPOI.lat;
						p.lng = tmpPOI.lng;
					}
					if (!p.lat || !p.lng)
					{
						poi.splice(i, 1);
						length--;
					}
				}
				if (def && poi.length < 1) poi = new Array(def);
				return poi;
			},
			eventHandler: function(obj, eventName, event, map, marker, msg, id)
			{
				GEvent.addListener(obj, eventName, function(){event(map, marker, msg, id);});
			},
			addPoint : function(obj, poi, opts)
			{
				var map = this.getMap(obj, true);
				if (!map) return;
				opts = opts || {};
				poi = this.checkPOI(poi, (opts.dFn ? {lat:(map.getCenter().lat()), lng:(map.getCenter().lng())} : null));
				if (poi.length < 1) return;
				var bounds = null;
				if (opts.contains)
				{
					bounds = new GLatLngBounds();
				}
				var iconI = 0;
				var markerArray = [];
				for(var i = 0;i<poi.length;i++)
				{
					var p = poi[i];
					var dFn = p.dFn || opts.dFn;
					var isdFn = (typeof dFn == "function");
					var icoImg = null;
					if (typeof p.ico == "string")
					{
						icoImg = ico;
					}
					else if(p.icoIndex || p.icoIndex>= 0)
					{
						icoImg = this.icons(p.icoIndex);
					}
					else if (isdFn)
					{
						icoImg = this.icons(this.settings.draggerIconIndex);
					}

					var ico = new GIcon(G_DEFAULT_ICON, icoImg);
					var ll = new GLatLng(p.lat, p.lng);
					var marker = new GMarker(ll, {icon : ico, draggable : isdFn});
					map.addOverlay(marker);
					if (isdFn)
					{
						GEvent.addListener(marker, "dragend", dFn);
					}
					if (opts.contains)
					{
						bounds.extend(ll);
					}
					if (!p.msg && isdFn)
					{
						p.msg = {html:this.settings.draggerText,open:1};
					}
					if (p.msg)
					{
						if (typeof p.msg == "string")
						{
							p.msg = {html:p.msg};
						}
						if (p.msg.html)
						{
							marker.bindInfoWindowHtml(p.msg.html);
							if (p.msg.open)
							{
								marker.openInfoWindowHtml(p.msg.html);
							}
						}
						if (isdFn)
						{
							GEvent.addListener(marker, "dragstart", function() {  marker.closeInfoWindow();  });
						}
						if (typeof opts.overFn == "function" && p.id)
						{
							new this.eventHandler(marker, "mouseover", opts.overFn, map, marker, p.msg.html, p.id);
						}
						if (typeof opts.outFn == "function" && p.id)
						{
							new this.eventHandler(marker, "mouseout", opts.outFn, map, marker, p.msg.html, p.id);
						}
						if (typeof opts.poiCallback == "function" && p.id)
						{
							new opts.poiCallback(map, marker, p.msg.html, p.id);
						}
					}
					markerArray.push(marker);
				}
				
				if (opts.contains)
				{
					map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
				}
				return (markerArray.length > 1) ? markerArray : markerArray[0];
			}
		});
	}
)
($);
