var fbGoogleTableMap = new Class({
	initialize: function(element, options) {
		
		this.element_map = element;
		this.element = $(element);
		
		this.baseIcon = new GIcon(G_DEFAULT_ICON);
		this.baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
		this.baseIcon.iconSize = new GSize(20, 34);
		this.baseIcon.shadowSize = new GSize(37, 34);
		this.baseIcon.iconAnchor = new GPoint(9, 34);
		this.baseIcon.infoWindowAnchor = new GPoint(9, 2);
		this.clusterMarkerCursor = 0;
		this.clusterMarkers = [];
		this.markers = [];
		this.icons = [];
		this.options = {
			'lat':0,
			'threeD':false,
			'lon':0,
			'control':'',
			'maptypecontrol':'0',
			'overviewcontrol':'0',
			'scalecontrol':'0',
			'livesite':'',
			'center':'middle',
			'ajax_refresh':0,
			'polyline':[],
			'polylinewidth':[],
			'polylinecolour':[],
			'refresh_rate':10000,
			'maptype':G_NORMAL_MAP,
			'use_cookies':'1'
		};
        $extend(this.options, options);
		if(this.options.ajax_refresh == 1) {
			this.updater = 	new Ajax( 'index.php', {
				data :{
					'option':'com_fabrik',
					'format':'raw',
					'controller':'plugin',
					'task':'pluginAjax',
					'plugin':'googlemap',
					'method':'ajax_getMarkers',
					'g':'visualization',
					'element_id':this.options.id
				},
				onSuccess:function(json) {
					this.options.icons = Json.evaluate(json);
					this.addIcons();
					if (this.options.ajax_refresh_center == 1) {
				  	this.center();
				  }
				}.bind(this)
			});
			this.timer = this.update.periodical(this.options.refresh_rate,this);
		}
		
		switch(this.options.maptype) {
			case 'G_NORMAL_MAP':
				this.options.maptype = G_NORMAL_MAP;
				break;
			case 'G_SATELLITE_MAP':
				this.options.maptype = G_SATELLITE_MAP;
				break;
			case 'G_HYBRID_MAP':
				this.options.maptype = G_HYBRID_MAP;
				break;
		}		
		window.addEvent('domready', function() {
			if (GBrowserIsCompatible()) {
				this.map = new GMap2($(this.element_map));
				this.map.setCenter(new GLatLng(this.options.lat, this.options.lon), this.options.zoomlevel.toInt());
				switch(this.options.control) {
					case 'GLargeMapControl':
						this.options.threeD == true ? this.map.addControl(new GLargeMapControl3D()) : this.map.addControl(new GLargeMapControl());
						break;
					case 'GSmallMapControl':
						this.map.addControl(new GSmallMapControl());
						break;
					case 'GSmallZoomControl':
						this.options.threeD == true ? this.map.addControl(new GSmallZoomControl3D()) : this.map.addControl(new GSmallZoomControl());
						break;
				}
				if(this.options.scalecontrol != '0') {
					this.map.addControl(new GScaleControl());
				}
				if(this.options.maptypecontrol != '0') {
					this.map.addControl(new GMapTypeControl());
				}
				if(this.options.overviewcontrol != '0') {
					this.map.addControl(new GOverviewMapControl());
				}
				this.bounds = new GLatLngBounds();
				if(this.options.clustering == false) {
					this.markerMgr = new MarkerManager(this.map);
				}
				this.addIcons();
				
				GEvent.addListener(this.map, "click", this.setCookies.bindAsEventListener(this));
				GEvent.addListener(this.map, "moveend", this.setCookies.bindAsEventListener(this));
				GEvent.addListener(this.map, "zoomend", this.setCookies.bindAsEventListener(this));

				if (this.options.use_cookies == '1') {
					// $$$ jazzbass - get previous stored location
					var mymapzoom = Cookie.get("mymapzoom_"+ this.options.id);
					var mymaplat = Cookie.get("mymaplat_"+ this.options.id);
					var mymaplng = Cookie.get("mymaplng_"+ this.options.id);
	
					if (mymaplat && mymaplat != '0' && mymapzoom != '0') {
						this.map.setCenter(new GLatLng(mymaplat.toFloat(), mymaplng.toFloat()), mymapzoom.toInt());
					} else {
						this.center();
					}
				}
				else {
					this.center();
				}
				//end
				
			  this.map.setMapType(this.options.maptype);
			  if (typeof(Slimbox) != 'undefined') {
				  Slimbox.scanPage();
			  }
			  else if (typeof(Mediabox) != 'undefined') {
				  Mediabox.scanPage();
			  }
			}
			
					//clear filter list
			this.container =  $(this.options.container);
			if($type(this.container) !== false) {
				var c = this.container.getElement('.clearFilters');
				if(c) {
					c.addEvent('click', function(e) {
						this.container.getElements('.fabrik_filter').each(function(f) {
							f.value = '';
						});
						new Event(e).stop();
						this.container.getElement('form[name=filter]').submit();
					}.bind(this));
				}
			}
	
			this.options.polyline.each(function(points, c) {
				var glatlng = [];
				points.each(function(p) {
					glatlng.push( new GLatLng(p[0], p[1]));
				});
				var width = this.options.polylinewidth[c];
				var colour = this.options.polylinecolour[c];
				var polyline = new GPolyline(glatlng, colour, width);
				this.map.addOverlay(polyline);
			}.bind(this));
		}.bind(this));
	},
	
	setCookies:function() {
		if (this.options.use_cookies == '1') {
			Cookie.set("mymapzoom_"+ this.options.id, this.map.getZoom(), {duration: 7});
			Cookie.set("mymaplat_"+ this.options.id, this.map.getCenter().lat(), {duration: 7});
			Cookie.set("mymaplng_"+ this.options.id, this.map.getCenter().lng(), {duration: 7}); 
		}
	},
	
	update: function() {
		this.updater.request();
	},
	
	addIcons: function() {
		if(this.options.clustering == false) {
			this.markerMgr.clearMarkers();
		}
		this.options.icons.each(function(i) {
			this.bounds.extend(new GLatLng(i[0], i[1]));
			this.addIcon(i[0], i[1], i[2], i[3], i[4], i[5]);
		}.bind(this));
	  
		if(this.options.clustering != false && this.clusterMarkers.length > 0) {
			if (this.options.clustering == 1) {
				// Using ClusterMarker, http://googlemapsapi.martinpearman.co.uk/articles.php?cat_id=1
				if (this.options.cluster_splits == '') {
					this.options.cluster_splits = '10,50';
				}
				if (this.options.icon_increment == '') {
					this.options.icon_increment = '5';
				}
				this.cluster=new ClusterMarker(this.map, { markers:this.clusterMarkers, 'splits':this.options.cluster_splits, 'icon_increment':this.options.icon_increment});
				this.cluster.fitMapToMarkers();
			}
			else {
				// Using MarkerClusterer, http://gmaps-utility-library.googlecode.com/svn/trunk/markerclusterer/1.0/docs/reference.html
				// @TODO - add a way of providing user defined styles
				// The following just duplicates some code in markerclusterer.js which builds their default styles array.
				// Building a replacement here so it uses local images rather than pulling from Google API site.
				var styles = [];
				var sizes = [53, 56, 66, 78, 90]; 
				var i = 0;
				for (i = 1; i <= 5; ++i) {
					styles.push({
						'url': this.options.livesite + "components/com_fabrik/libs/googlemaps/markerclusterer/1.0/images/m" + i + ".png",
						'height': sizes[i - 1],
						'width': sizes[i - 1]
					});
				} 			
				var zoom = null;
				// for now, overloading icon_increment setting to be maxZoom
				if (this.options.icon_increment != '') {
					zoom = parseInt(this.options.icon_increment);
					if (zoom > 14) {
						zoom = 14;
					}
				}
				var size = 60;
				// for now, overloading original cluster_splits setting to be gridSize
				if (this.options.cluster_splits != '') {
					if (this.options.cluster_splits.test('/,/')) {
						// they probably left it as the default 10,60 (group size in number of markers) for ClusterMarker params,
						// for MarkerClusterer we need a single number, gridSize in pixels, so just use default
						size = 60;
					} else {
						size = parseInt(this.options.cluster_splits);
					}
				}
				this.cluster = new MarkerClusterer(this.map, this.clusterMarkers, {maxZoom: zoom, gridSize: size, styles: styles});
			}
			this.map.savePosition();	//	enables the large map control centre button to return the map to initial view
		}
	}, 
	
	center: function() {
	//set the map to center on the center of all the points
		var c;
		switch(this.options.center) {
			case 'middle':
				c = this.bounds.getCenter();
				break;
			case 'userslocation':
				if(geo_position_js.init()) {
					geo_position_js.getCurrentPosition(this.geoCenter.bind(this),this.geoCenterErr.bind(this),{enableHighAccuracy:true});
				}
				else{
					fconsole('Geo locaiton functionality not available');
					c = this.bounds.getCenter();
				}
				break;
			default:
				var lasticon = this.options.icons.getLast();
				if(lasticon) {
		  		c = new GLatLng(lasticon[0], lasticon[1]);
		  	}else{
		  		c = this.bounds.getCenter();
		  	}
				break;
	  }
		this.map.setCenter(c);
	},
	
	geoCenter:function(p) {
		this.map.setCenter(new GLatLng(p.coords.latitude.toFixed(2), p.coords.longitude.toFixed(2)));
	},
	
	geoCenterErr:function(p) {
		fconsole('geo location error='+p.message);
	},
	
	addIcon: function(lat, lon, html, img, w, h) {
		var point = new GLatLng(lat, lon);
		
 		if(img !== '') {
 			var thisicon = new GIcon(this.baseIcon);
 			if(img.substr(0,7) != 'http://' && img.substr(0,8) != 'https://') {
 				thisicon.image = this.options.livesite + 'images/stories/' + img;
 			}else{
 				thisicon.image = img;
 			}
 			thisicon.shadowSize = new GSize(0, 0);
 		}else{
 			thisicon = this.baseIcon;
 		}
 		thisicon.iconSize = new GSize(w, h);
 		thisicon.iconAnchor = new GPoint((w/2)-1, h);
		var markerOptions = { 'icon':thisicon };
  	var marker = new GMarker(point, markerOptions);
     this.markers.push(marker);
		GEvent.addListener(marker, "click", function() {
			// $$$ jazzbass
			this.setCookies();
			//end
 			marker.openInfoWindowHtml(html);
 			this.periodCounter = 0;
 			this.timer = this.slimboxFunc.periodical(1000, this); //adds the number of seconds at the Site.
 		}.bind(this));
  	if(this.options.clustering == false) {
			this.markerMgr.addMarker(marker, 0);
		}else{
			this.clusterMarkers.push(marker);
			this.clusterMarkerCursor ++;
		}
	},
	
	slimboxFunc:  function(){
		// periodical function to observe the infowindow html to apply lightbox fx to images
			var links = $$("a").filter(function(el) {
				return el.rel && el.rel.test(/^lightbox/i);
			});
			if(links.length > 0 || this.periodCounter > 15) {
				clearInterval(this.timer);
				if (typeof(Slimbox) != 'undefined') {
					$$(links).slimbox({/* Put custom options here */}, null, function(el) {
						return (this == el) || ((this.rel.length > 8) && (this.rel == el.rel));
					});
				}
				else if (typeof(Mediabox) != 'undefined') {
					$$(links).mediabox({/* Put custom options here */}, null, function(el) {
						return (this == el) || ((this.rel.length > 8) && (this.rel == el.rel));
					});
				}
			}
			this.periodCounter ++;
		}
});