$(document).ready (function () {
googleMaps={
	infoWindow: function (optionMap) {
		this._object=null;
		this._data=null;
		this._callback=function () {};
		this._properties= {
			content: null
		};
		this.map=null;
		this.anchor=null;
		jQuery.extend (true, this, optionMap);
		this._object = new google.maps.InfoWindow(this._properties);
	},
	marker: function (map, optionMap) {
		this._object=null;
		this._callback=null;
		this._data={};
		this._properties={
			position: [51, 10],
			icon: null
		};
		this.infoWindow=null;
		this.events=null;		
		
		jQuery.extend (true, this, optionMap);
		this._properties.map=this.map=map._object;
		
		googleMaps.parsePosition (this._properties.position, { marker: this }, function (latlng, wrappings) {
			wrappings.marker._properties.position=latlng;
			if (wrappings.marker._properties.icon!=null) jQuery.extend (true, wrappings.marker._properties, wrappings.marker._properties.icon);
			wrappings.marker._object = new google.maps.Marker(wrappings.marker._properties);
			
			if (wrappings.marker.infoWindow!=null) {
				wrappings.marker.infoWindow.map=wrappings.marker._properties.map;
				wrappings.marker.infoWindow.anchor=wrappings.marker._object;
				wrappings.marker.infoWindow=new googleMaps.infoWindow (wrappings.marker.infoWindow);
			}
						
			for (var eventType in wrappings.marker.events) googleMaps._attachEvent (wrappings.marker, eventType);
						
			wrappings.marker._callback (wrappings.marker);
		});
	},
	route: function (map, optionMap) {
		this._object=null;
		this._callback=function () {};
		this._properties={
			preserveViewport: true,
			markerOptions: {
					visible: false
			},
			map: null
		};
		this.calculatorProperties=null;
		this.route=null;
		this.map=map;
		jQuery.extend (true, this, optionMap);
		// this._properties.map=this.map=map._object;
				

		this._object=new google.maps.DirectionsRenderer (this._properties);
		var renderer=this._object;
		googleMaps.calcRoute (this, function (result, route) {
			route.route=result;
			renderer.setDirections(result);
			route._callback (route);
		});

		
	},
	map: function (container, optionMap) {
		this._object=null;
		this._container=document.getElementById (container);
		this._callback=function (map) {};
		this._properties={
			center: [51, 10], 
			zoom: 6,
			mapTypeId: 'google.maps.MapTypeId.ROADMAP',
			navigationControl: true,
			streetViewControl: false,
			disableDoubleClickZoom: true,
			scrollwheel: false,
			mapTypeControl: false
		};
		this.markers=[];
		this.routes=[];
		
		
	
		jQuery.extend (true, this, optionMap);
		this._properties.mapTypeId=eval (this._properties.mapTypeId);
		
		googleMaps.parsePosition (this._properties.center, { map: this }, function (latlng, wrappings) {
			wrappings.map._properties.center=latlng;
			wrappings.map._object = new google.maps.Map(wrappings.map._container, wrappings.map._properties);
			wrappings.map._callback (wrappings.map);
		});		
	},
	icons: {
		pin_ssp: {
			icon: new google.maps.MarkerImage(
				'/_lib/img/pin_ssp.png',
				new google.maps.Size(26,46),
				new google.maps.Point(0,0),
				new google.maps.Point(13,46)
			),
			shadow: new google.maps.MarkerImage(
				'/_lib/img/shadow.png',
				new google.maps.Size(52,46),
				new google.maps.Point(0,0),
				new google.maps.Point(13,46)
			),
			shape: {
				coord: [25,0,25,1,25,2,25,3,25,4,25,5,25,6,25,7,25,8,25,9,25,10,25,11,25,12,25,13,25,14,25,15,25,16,25,17,25,18,25,19,25,20,25,21,25,22,25,23,25,24,25,25,17,26,17,27,17,28,17,29,16,30,16,31,16,32,16,33,15,34,15,35,15,36,15,37,14,38,14,39,14,40,14,41,13,42,13,43,13,44,13,45,12,45,12,44,12,43,12,42,11,41,11,40,11,39,11,38,10,37,10,36,10,35,10,34,9,33,9,32,9,31,9,30,8,29,8,28,8,27,8,26,0,25,0,24,0,23,0,22,0,21,0,20,0,19,0,18,0,17,0,16,0,15,0,14,0,13,0,12,0,11,0,10,0,9,0,8,0,7,0,6,0,5,0,4,0,3,0,2,0,1,0,0,25,0],
					type: 'poly'
			}
		},
		pin_sn: {
			icon: new google.maps.MarkerImage(
				'/_lib/img/pin_sn.png',
				new google.maps.Size(26,46),
				new google.maps.Point(0,0),
				new google.maps.Point(13,46)
			),
			shadow: new google.maps.MarkerImage(
				'/_lib/img/shadow.png',
				new google.maps.Size(52,46),
				new google.maps.Point(0,0),
				new google.maps.Point(13,46)
			),
			shape: {
				coord: [25,0,25,1,25,2,25,3,25,4,25,5,25,6,25,7,25,8,25,9,25,10,25,11,25,12,25,13,25,14,25,15,25,16,25,17,25,18,25,19,25,20,25,21,25,22,25,23,25,24,25,25,17,26,17,27,17,28,17,29,16,30,16,31,16,32,16,33,15,34,15,35,15,36,15,37,14,38,14,39,14,40,14,41,13,42,13,43,13,44,13,45,12,45,12,44,12,43,12,42,11,41,11,40,11,39,11,38,10,37,10,36,10,35,10,34,9,33,9,32,9,31,9,30,8,29,8,28,8,27,8,26,0,25,0,24,0,23,0,22,0,21,0,20,0,19,0,18,0,17,0,16,0,15,0,14,0,13,0,12,0,11,0,10,0,9,0,8,0,7,0,6,0,5,0,4,0,3,0,2,0,1,0,0,25,0],
					type: 'poly'
			}
		}
	},
	parsePosition: function (position, wrappings, callback) {
		switch (typeof (position)) {
			case 'string':
				googleMaps.geoCode (position, wrappings, callback);
			break;
			case 'object':
				if (position.length) {
					callback (new google.maps.LatLng(position[0], position[1]), wrappings);
				} else {
					callback (position, wrappings);
				}
			break;
		}
	},
	geoCode: function (position, wrappings, callback) {
		
		var geoCoder=new google.maps.Geocoder();
		geoCoder.geocode( { 'address': position}, function(results, status) {
			if (status == google.maps.GeocoderStatus.OK) {
				callback (results[0].geometry.location, wrappings);
			} else {
				debug ("Geocoding-Fehler: " + status);
			}
		});				
	},
	calcRoute: function (route, callback) {
	
		var _properties={
			origin: null,
			destination: null,
			travelMode: 'DRIVING',
			waypoints: []			
		};
		var recurseParseRoute=function (route, element) {
			googleMaps.parsePosition (route.route[element], {route: route, element:element}, function (latlng, wrappings) {
				wrappings.route.route[wrappings.element]=latlng;
				wrappings.element++;
				if (wrappings.element<route.route.length) {
					recurseParseRoute (wrappings.route, wrappings.element);
				} else {
					jQuery.extend (true, _properties, wrappings.route.calculatorProperties);
					_properties.origin=wrappings.route.route[0];
					_properties.destination=wrappings.route.route[wrappings.route.route.length-1];
					if (wrappings.route.route.length>2) {
						_properties.waypoints=[];
						for (var i=1; i<(wrappings.route.route.length-1); i++) {
							_properties.waypoints.push ({ location: wrappings.route.route[i], stopover: false });
						}
					}
					
					
					var service=new google.maps.DirectionsService();
					service.route(_properties, function (result, status) {
						callback (result, wrappings.route);
					});			
				}
			});
		};
		
		recurseParseRoute (route, 0);
		
		
		
	},
	_attachEvent: function (element, eventType) {
		google.maps.event.addListener(element._object, eventType, function (event) {
			if (typeof (event)=='undefined') event={};
			event.data={
				element: element
			}
			element.events[eventType] (event);				
		});
	}
}
googleMaps.infoWindow.prototype.show=function () {
	this._object.open(this.map,this.anchor)
}

googleMaps.infoWindow.prototype.hide=function () {
	this._object.close (this.map,this.anchor)
}
googleMaps.infoWindow.prototype.setContent=function (content) {
	this._properties.content=content;
	this._object.setContent (content);
}

googleMaps.route.prototype.show=function () {
	this._object.setMap (this.map._object);
}

googleMaps.route.prototype.hide=function () {
	this._object.setMap (null);
}


googleMaps.map.prototype.addMarker=function (optionMap) {
	var _callback=typeof (optionMap._callback)=='undefined'?function (){}:optionMap._callback;
	var map=this;
	optionMap._callback=function (marker) {
		map.markers.push (marker);
		_callback (marker);
	}
	new googleMaps.marker (this, optionMap);
}

googleMaps.map.prototype.addRoute=function (optionMap) {
	var _callback=typeof (optionMap._callback)=='undefined'?function (){}:optionMap._callback;
	var map=this;
	optionMap._callback=function (route) {
		map.routes.push (route);
		_callback (route);
	}
	new googleMaps.route (map, optionMap);
}
});
