(function($) {
	var gmap, geo, gnode, Is, aD = new Array(), Mc = new Object(), De = false;
	$.omap = {} || $.omap;

	$.extend($.omap, {
	option:{
			initZoom:14,	// init map zoom ratio
			initDrag: true,	// when init map draggable
			Dwatcher : false,	// wather Drag movment
			adZoom:10, 		// when map draggable, catch map movment at map Zoom ratio
			where: false,	//get User location
			dXY:{x :121.555, y:25.112}, // default map center
			range: 0.4,	//
			ControlSize : 's',
			MoveEnd: '',
			info : '',
			Scale : false,
			shadow : 's.png',
			imgUrl : 'http://img.devel.obuy.tw/default/map/image/',
			sIcon:['point.gif','pointe.gif'] , // store icon
			itemcss: 'shop',
			debug : false,
			debug_func:''
	},
	moveTo:function(x, y){
		if( x == undefined) return false;
		if(typeof x == 'object') {
			gmap.setCenter(x);
		} else{
			if(isNaN(x)){
				var xy = x.replace(/[\(\)]+/g, '').split(',');
				gmap.setCenter(new GLatLng(xy[0], xy[1]));
			} else {
				gmap.setCenter(new GLatLng(y, x));
			}
		}
		return $.omap
	},
	addStores:function(data, callback, opennow){
		debug('addStores');
		var opt = $.omap.option;
		try{
			// in case data readly on map;
			if(opennow) var data_store = data[0];
			data = regMinfo(data);
			if(!data) {
				if(opennow) {
					var i = data_store.xy.replace(/[\(\)]+/g, '').split(',');
					var html = $.omap.aDinfo({x:i[0],y:i[1]});
					Is.openExtInfoWindow(gmap, opt.itemcss, html, {beakOffset: 2});
					return true;
				}
				debug('no new data');
				return false;
			}
		}catch(e){
			debug('addMarker recevice data error : ' + data );
			return false
		}
		var adnu = data.shift();
		var data = data.shift();

		try{
			var blueIcon = new GIcon(G_DEFAULT_ICON);
			blueIcon.iconSize = new GSize(32, 30);
			blueIcon.shadow = opt.imgUrl + opt.shadow;
			blueIcon.shadowSize = new GSize(32,21);
			var markerOptions = {icon:blueIcon};
		}catch(e){
			debug('Icon error');
		}

		for(var i=0, r=data[i];r;r=data[++i]){
			try{
				var img = (r.disc==0)? opt.sIcon[0] : opt.sIcon[1];
			}catch(e){
				var img =  opt.sIcon[0];
			}
			blueIcon.image = opt.imgUrl + img;
			var xy = r.xy.replace(/[\(\)]+/g, '').split(',');

			var point =  new GLatLng(xy[0] , xy[1]);
			var it = new GMarker(point, markerOptions);
			gmap.addOverlay(it);

			aD[(i+adnu)].Is = it;
			//Is.push(it);
			if(opennow == true){
				var html = $.omap.option.info(r);
				it.openExtInfoWindow(gmap, opt.itemcss, html, {beakOffset: 2});
			}
			new GEvent.addListener(it, 'mouseover', function(i){
				var node = $.omap.aDinfo(i);
				if(!node) {
					debug('Not Node been found ');
					return false
				}
				try{
					Is.openExtInfoWindow(gmap, opt.itemcss, node, {beakOffset: 2});
				}catch(e){debug(e)}
			});
		}
		data='';
		return  $.omap;
	},
	aDinfo:function(m){
		if( !m.x || !m.y) {
			debug('aDinfo_start');
			return false;
		}
		var ni = false;
		for(var i=0, node = aD[i]; node ; node = aD[++i]){
			var xy = node.xy.replace(/[\(\)]+/g, '');
			if( (xy == (m.x+','+m.y)) || (xy == (m.y+','+m.x)) ){
				ni = node;
				break;
			}
		}
		if(!ni) return false;
		Is = ni.Is;
		if (typeof $.omap.option.info == 'function') return $.omap.option.info(ni);
		return ni.id;
	},
	searchADD:function(address, callback){
        $.get('/ajax/areaswap.php', {'addr': address, 'get': 'old'}, function(address){
            if(!address) return false;
            if (typeof $.omap.Geocoder == 'undefined') {
                 var geocoder = $.omap.Geocoder = new GClientGeocoder;
            } else {
                var geocoder = $.omap.Geocoder;
            }
            geocoder.getLatLng(address, function(point){
                if (typeof callback == 'function') return callback(point);
                if (!point) {
                    debug('Cant Find this address');
                    return false;
                }
                return $.omap.moveTo(point);
            });
        }, 'json');
	},
	addPoint:function(pop){
		var mo;
		try{
			var blueIcon = new GIcon(G_DEFAULT_ICON);
			blueIcon.iconSize = new GSize(32, 30);
			blueIcon.image = $.omap.option.imgUrl + $.omap.option.sIcon[0];
			blueIcon.shadow = $.omap.option.imgUrl + $.omap.option.shadow;
			blueIcon.shadowSize = new GSize(32,21);
			mo = {icon:blueIcon};
		}catch(e){
			debug('addPoint::'+e);
		}

		var pop = $.extend({
			point:'',
			x:120,
			y:25
		}, pop);


		if(typeof pop.point == 'object') {
			var mmm = new GMarker(pop.point, mo);
			$.omap.moveTo(pop.point);
		} else {
			var mmm = new GMarker(new GLatLng(pop.y, pop.x), mo);
			$.omap.moveTo(pop.x, pop.y);
		}
		if(typeof mmm == 'object') {
			gmap.addOverlay(mmm);
		}
		return mmm;
	},
	addEvent:function(dom, event, callback){
		if(typeof dom != 'object' || typeof callback != 'function') return false;
		new GEvent.addListener(dom, event, callback);
	},
	clearEvent:function(dom, event){
		new GEvent.clearListeners(dom, event);
	},
	clearAP:function(){
		for(var i=0,dd=aD[i];dd;dd=aD[++i]){
			gmap.removeOverlay(dd.Is);
			dd='';
		};
		aD = new Array();
	},	
	getlen:function(){
		return aD.length;
	},
	debug2:function(msg){
		if ($.omap.option.debug) {
			if( typeof $.omap.option.debug_func == 'function' )  return $.omap.option.debug_func(mag);
			try{console.log(msg);}
			catch(e){
				alert(msg);
			}
		}
	}
	});

	$.fn.extend({
		omap : function(option, callback){
			if(this.length == 0)  return false;
			initChecks(this);
			var option = $.extend($.omap.option, option);

			jQuery(document).unload(function(){ new GUnload(); });

			try{
				//geo = $.omap.geo =  Gloader.ClientLocation;
				gmap = $.omap.gmap = new GMap2(this[0]);
			}catch(e){
				debug('1:'+this+"\n Error:"+e);
				return false;
			}

			try{
				var x = option.where? geo.longitude : option.dXY.x;
				var y = option.where? geo.latitude : option.dXY.y;
				if(!x || !y) return false;
			} catch(e){
				debug('2:' + x + '::' + y +' Geo:'+ geo.longitude + ',' + geo.latitude + "\n E:"+e );
				return false;
			}

			gmap.addControl(new GMapTypeControl());
			if (option.Scale) gmap.addControl(new GScaleControl());
			if(option.ControlSize == 'l'){
				gmap.addControl(new GLargeMapControl());
			} else {
				gmap.addControl(new GSmallMapControl());
			}
			if(!option.initDrag) {
				gmap.disableDragging();
			} else {
				if(option.Dwatcher) CatchDrag();
			}
			gmap.setCenter(new GLatLng(y, x), option.initZoom);

			if (typeof callback == 'function') return callback(this, option);
			return this[0];
		}
	})

	function CatchDrag(){

		$.omap.addEvent(gmap, 'zoomend', function(i){
			var zoom = gmap.getZoom();
			debug(zoom);
			if( zoom <= $.omap.option.adZoom ){
				if(!De) return false
				// if Drag Event  exist
				$.omap.clearEvent(gmap, 'movestart');
				$.omap.clearEvent(gmap, 'moveend');
				Mc = new Object();
				De = false;
				debug('Clear Movement Listeners!');
				return true;
			}

			if(De) return true;
			De = true; // reg Drag Enevt
			debug('DragEvent:true');
			// Before Move
			$.omap.addEvent(gmap, 'movestart', function(){
				var i = gmap.getCenter();
				if(Mc.x) return false;
				if ($.omap.option.debug) debug('Catch Move Start at :'+ i.x + ':' + i.y  );
				Mc.x = i.x;
				Mc.y = i.y;
			})

			//Afert Move
			$.omap.addEvent(gmap, 'moveend', function(i){
				// When movement unable to tigger MoveEnd  to reset Mc.x stop!!
				if(!Mc.x) return false;
				var rg = $.omap.option.range;
				var i = gmap.getCenter();
				var dx = Math.abs(Mc.x - i.x);
				var dy = Math.abs(Mc.y - i.y);
				if( (dx > rg) || (dy > rg) || ( Math.sqrt(dx+dy) > rg)){
					debug('Act MoveEnd Function');
					Mc = new Object();
					if (typeof $.omap.option.MoveEnd == 'function') return $.omap.option.MoveEnd($.omap, i);
				} else {
					if ($.omap.option.debug) debug('Distance : '+Math.round(dx*100)/100+':'+Math.round(dy*100)/100 );
				}
			});
		})

	}

	function initChecks(el){
		if (typeof GBrowserIsCompatible == 'undefined') {
			$(el).css("color",'#FFF').html('google map unabled to load!');
			throw Error('google map ajax api not load!');
		}
	}

	function regMinfo(data){
		if( !data   ||  (data.length <= 0) || (data == undefined)   )  return false;

		for(var i=0, d=aD[i]; d;d =aD[++i]){
			for(var j=0, jd=data[j]; jd; jd=data[++j]){
				if(d.id == jd.id){
					data.splice(j, 1);
					break;
				}
			}
		}
		if ($.omap.option.debug) debug('Process Data :  recvice data lengh '+ data.length  );

		if(data.length > 0) {
			var adn = aD.length;
			aD = aD.concat(data);
			return [adn,data];
		} else {
			return false;
		}
	}

	function debug(msg){
		if ($.omap.option.debug) {
			if( typeof $.omap.option.debug_func == 'function' )  return $.omap.option.debug_func(mag);
			try{console.log(msg);} catch(e){ alert(msg);}
		}
		return true;
	}

})(jQuery);



