Stb.Google = new Class();

/**
 * Stb.Google.Map
 * 
 * 
 */
Stb.Google.Map = new Class({
	Extends: Options,
	
	/**
	 * address takes precedence over latitude and longitude
	 */
	options: {
		address: '',
		latitude: '51.9883878',
		longitude: '5.8328333',
		zoom: 13,
		type: 'G_NORMAL_MAP' //Use string format. @see http://code.google.com/apis/maps/documentation/introduction.html#MapTypes
	},
	
	initialize: function(map, options) {
		this.setOptions(options);
		if(!GBrowserIsCompatible()) {
			return false;
		}
		this.gmap = new GMap2(map);
		this.geocoder = new GClientGeocoder();
		if(this.options.address && this.options.infoWindow) {
			var locator = new Stb.Google.Map.Locator(this, {
				zoom: this.options.zoom
			});
			locator.find(this.options.address, this.options.infoWindow);
		} else {
			this.gmap.setCenter(new GLatLng(this.options.latitude, this.options.longitude), this.options.zoom);
		}
		this.gmap.setUIToDefault();
		this.gmap.setMapType(eval(this.options.type));
		window.addEvent('unload', function() {
			GUnload();
		});
	}
});

Stb.Google.Map.Point = new Class({
	Extends: Options,
	
	initialize: function(map, latitude, longitude, options) {
		this.setOptions(options);
		this.map = map;
		this.latitude = latitude;
		this.longitude = longitude;
		
		if($chk(this.options.icon) && !$chk(this.options.marker)) {
			var icon = new GIcon(G_DEFAULT_ICON);
			$H(this.options.icon).each(function(value, attribute) {
				icon[attribute] = value;
			}, this);
			
			this.options.marker = {
				icon: icon
			};
		}
		this.gpoint = new GLatLng(latitude, longitude);
		this.marker = new GMarker(this.gpoint, $pick(this.options.marker, {}));
		
		if($chk(this.options.events)) {
			$H(this.options.events).each(function(action, event) {
				GEvent.addListener(this.marker, event, action.bind(this));
			}, this);
		}
		
		this.map.gmap.addOverlay(this.marker);
	},
	
	show: function() {
		this.map.gmap.panTo(this.gpoint);
	}
});

Stb.Google.Map.InfoWindow = new Class({
	Extends: Options,
	
	options: {
		event: 'click'
	},
	
	initialize: function(point, template, contents, options) {
		this.setOptions(options);
		var infoWindow = template.clone().insertData(contents).removeClass('stbTpl');
		
		GEvent.addListener(point.marker, this.options.event, function() {
			point.map.gmap.openInfoWindow(point.gpoint, infoWindow);
		}.bind(this));
	}
});

Stb.Google.Map.Locator = new Class({
	Extends: Options,
	
	initialize: function(map, options) {
		this.setOptions(options);
		this.map = map;
	},
	
	find: function(address, infoWindow) {
		this.map.geocoder.getLatLng(address, function(point) {
			if($chk(point)) {
				this.addressFound(address, point);
			} else {
				this.addressNotFound(address);
			}
		}.bind(this));
	},
	
	addressFound: function(address, point) {
		this.map.gmap.setCenter(point, this.options.zoom);
		this.map.geocoder.getLocations(address, function(response) {
			this.map.gmap.clearOverlays();
			if(!$chk(response) || response.Status.code != 200) {
				return this.addressNotFound(address);
			}
			this.place = response.Placemark[0];
			var point = new GLatLng(this.place.Point.coordinates[1], this.place.Point.coordinates[0]),
				marker = new GMarker(point),
				infoWindow = $('infoWindow').clone();
			infoWindow.removeClass('stbTpl');
			
			infoWindow.insertData({
				address: this.place.address
			});
			infoWindow.addActions({
				directions: function() {
					window.open('http://maps.google.nl/maps?daddr='+this.place.address);
				}
			}, this);
			
			if($chk(this.options.zoom)) {
				this.map.gmap.setZoom(this.options.zoom);
			}
			this.map.gmap.addOverlay(marker);
			this.map.gmap.openInfoWindow(point, infoWindow);
			GEvent.addListener(marker, "click", function() {
				this.map.gmap.openInfoWindow(point, infoWindow);
			}.bind(this));
		}.bind(this));
	},
	
	addressNotFound: function(address) {
		alert('Het adres '+address+' is niet gevonden');
	}
});

Stb.Google.Map.AddressFinder = new Class({
	Extends: Options,
	
	initialize: function(map, options) {
		this.setOptions(options); 
		this.map = map;
		
		this.options.searchInput.addEvent('keydown', function(event) {
			event = new Event(event);
			if(event.key == 'enter') {
				this.find(event);
			}
		}.bindWithEvent(this));
		this.options.searchButton.addEvent('click', this.find.bindWithEvent(this));
	},
	
	find: function(event) {
		var input = this.options.searchInput,
			address = input.get('value');
		if(address.length > 0) {
			if(!$chk(this.locator)) {
				this.locator = new Stb.Google.Map.Locator(this.map);
			}
			this.locator.find(address, this.options.infoWindow);
		}
	}
});
