	var RoutenPlaner = {};
	
	RoutenPlaner.lang = {
		'EN_en': {
			'GoogleMaps._onGDirectionsError.unknownAddress': 'Sorry, a match could not be found in our database. Please check your input.',
			'Interface._doSearch.streetError': 'Please fill in a street.',
			'Interface._doSearch.zipError': 'Please fill in a zip code.',
			'Interface._doSearch.cityError': 'Please fill in a city.',
			'Interface._onGDirectionsLoad.description': 'Description',
			'Interface._onGDirectionsLoad.distance': 'Distance',
			'Interface._onGDirectionsLoad.timeToTravel': 'Time of travel',
			'Interface._onGDirectionsLoad.searchResults': 'search results'
		},
		
		'DE_de': {
			'GoogleMaps._onGDirectionsError.unknownAddress': 'Die von Ihnen eingegebene Adresse konnte nicht gefunden werden. Bitte %FCberpr%FCfen Sie Ihre Eingabe.',
			'Interface._doSearch.streetError': 'Bitte geben Sie eine Stra%DFe an.',
			'Interface._doSearch.zipError': 'Bitte geben Sie eine PLZ an.',
			'Interface._doSearch.cityError': 'Bitte geben Sie eine Stadt an.',
			'Interface._onGDirectionsLoad.description': 'Beschreibung',
			'Interface._onGDirectionsLoad.distance': 'Strecke',
			'Interface._onGDirectionsLoad.timeToTravel': 'Fahrzeit',
			'Interface._onGDirectionsLoad.searchResults': 'Gesamtangaben'
		}
	}
	
	RoutenPlaner.GoogleMaps = Class.create({
		_element: null,
		_map: null,
		_gdir: null,
		_options: {},
		
		initialize: function(element, options)
		{
			this._options = Object.extend({
				startCords: [0.0, 0.0],
				locale: 'EN_en'
			}, options || {});
			
			if ($(element))
				this._element = $(element);
			else
				return false;
			
			this._map = new GMap2(this._element);
			this._map.addControl(new GLargeMapControl());
			
			this._gdir = new GDirections(this._map);
			
			GEvent.addListener(this._gdir, 'load', this._onGDirectionsLoad.bind(this));
			GEvent.addListener(this._gdir, 'error', this._onGDirectionsError.bind(this));
			
			this.showStartPosition();
			
			return true;
		},
		
		setDirections: function(fromAddress, toAddress)
		{
			this._gdir.load('from: ' + fromAddress + ' to: ' + toAddress, {
				'locale': this._options.locale,
				getPolyline: true,
				getSteps: true
			});
		},
		
		_onGDirectionsLoad: function() { },
		
		_onGDirectionsError: function()
		{
			if (this._gdir.getStatus().code == G_GEO_UNKNOWN_ADDRESS)
				alert(unescape(RoutenPlaner.lang['GoogleMaps._onGDirectionsError.unknownAddress']));
			else if (this._gdir.getStatus().code == G_GEO_SERVER_ERROR)
				alert("A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.\n Error code: " + this._gdir.getStatus().code);
			else if (this._gdir.getStatus().code == G_GEO_MISSING_QUERY)
				alert("The HTTP q parameter was either missing or had no value. For geocoder requests, this means that an empty address was specified as input. For directions requests, this means that no query was specified in the input.\n Error code: " + this._gdir.getStatus().code);
			else if (this._gdir.getStatus().code == G_GEO_BAD_KEY)
				alert("The given key is either invalid or does not match the domain for which it was given. \n Error code: " + this._gdir.getStatus().code);
			else if (this._gdir.getStatus().code == G_GEO_BAD_REQUEST)
				alert("A directions request could not be successfully parsed.\n Error code: " + this._gdir.getStatus().code);
			else
				alert("An unknown error occurred.");
		},
	
		showStartPosition: function()
		{
			this._map.setCenter(
				new GLatLng(this._options.startCords[0], this._options.startCords[1]),
				15, G_NORMAL_MAP
			);
			var point = new GLatLng(
				this._options.startCords[0], this._options.startCords[1]
			);
			
			this.addMarker(point, null);
		},
		
		addMarker: function(point, icon)
		{
			if (!point) return;
			
			this._map.addOverlay(
				new GMarker(point, {
					icon: icon
				})
			);
		}
	});
	
	RoutenPlaner.Interface = Class.create(RoutenPlaner.GoogleMaps, {
		_searchForm: null,
		_loader: null,
		_options: {},
		
		initialize: function($super, element, options)
		{
			this._options = Object.extend({
				toAddress: ''
			}, options || {});
			
			if (!$super(element, this._options))
				throw('GoogleMaps error');
			
			if (!(this._searchForm = $('google-map-form')))
				throw('Searchformular not found');
			
			this._searchForm.observe('submit', this._doSearch.bindAsEventListener(this));
			$('google-map-changesearch').observe('click', this._changeAddress.bindAsEventListener(this));
		},
		
		_doSearch: function(e)
		{
			e.stop();
			
			var street = this._searchForm.elements['strasse'];
			var zip = this._searchForm.elements['plz'];
			var city = this._searchForm.elements['ort'];
			
			if (street.value.length == 0)
			{
				alert(unescape(RoutenPlaner.lang['Interface._doSearch.streetError']));
				street.focus();
				return false;
			}
			else if (zip.value.length == 0)
			{
				alert(unescape(RoutenPlaner.lang['Interface._doSearch.zipError']));
				zip.focus();
				return false;
			}
			else if (city.value.length == 0)
			{
				alert(unescape(RoutenPlaner.lang['Interface._doSearch.cityError']));
				city.focus();
				return false;
			}
			
			var address = street.value + ', ' + zip.value + ', ' + city.value;
			
			this._showLoader();
			this.setDirections(address, this._options.toAddress);
			
			return true;
		},
		
		_changeAddress: function(e)
		{
			e.stop();
			this._showSearchForm();
		},
		
		_showSearchForm: function()
		{
			if (this._loader != null)
			{
				this._loader.hide();
			}
			
			$('google-map-start').hide();
			$('google-map-destination').hide();
			$('google-map-print').hide();
			
			this._searchForm.show();
		},
		
		_showLoader: function()
		{
			if (this._loader == null)
				this._createLoader();
			
			this._loader.show();
		},
		
		_createLoader: function()
		{
			var div = new Element('div', {
				'style': 'position:relative;'
			});
			
			this._searchForm.wrap(div);
			
			div.insert(
				new Element('div', {
					'id': 'google-map-form-loader'
				}).setStyle({
					position: 'absolute',
					top: 0, left: 0,
					width: '100%',
					height: div.getHeight() + 'px',
					backgroundColor: 'black',
					backgroundRepeat: 'no-repeat',
					backgroundPosition: '50% 50%',
					backgroundImage: 'url(/nrwinvest_englisch/system/layout/bilder/loader.gif)',
					'text-align': 'center',
					opacity: 0.8
				})
			);
			
			this._loader = $('google-map-form-loader');
		},
		
		_showStartDestinationAddress: function()
		{
			var street = this._searchForm.elements['strasse'];
			var zip = this._searchForm.elements['plz'];
			var city = this._searchForm.elements['ort'];
			
			this._searchForm.hide();
			this._loader.hide();
			
			var elements = $$('#google-map-start > dd');
			elements[0].update(street.value);
			elements[1].update(zip.value + ', ' + city.value);
			
			$('google-map-start').show();
			$('google-map-destination').show();
			$('google-map-print').show();
		},
		
		_onGDirectionsLoad: function($super)
		{
			$super();
			this._showStartDestinationAddress();
			
			var description = '<table id="routen-tabelle" cellpadding="0" cellspacing="0" summary="Die folgende Tabelle gibt eine Wegschreibung zum gew&auml;hlten Ziel an.">'
				+ '<thead><tr><th id="platzierung"></th>'
				+ '<th id="beschreibung">' + unescape(RoutenPlaner.lang['Interface._onGDirectionsLoad.description']) + '</th>'
				+ '<th id="Strecke">' + unescape(RoutenPlaner.lang['Interface._onGDirectionsLoad.distance']) + '</th>'
				+ '<th id="Zeit">' + unescape(RoutenPlaner.lang['Interface._onGDirectionsLoad.timeToTravel']) + '</th></tr>'
				+ '</thead><tbody>';
			
			 for (var i=0; i < this._gdir.getRoute(0).getNumSteps(0); i++)
			 {
				description+= '<tr><td class="rank">' + (i + 1) + '</td>';
				description+= '<td class="desc">' + this._gdir.getRoute(0).getStep(i).getDescriptionHtml() + '</td>';
				description+= '<td class="km">' + this._gdir.getRoute(0).getStep(i).getDistance().html + '</td>';
				description+= '<td class="time"><small>' + this._gdir.getRoute(0).getStep(i).getDuration().html + '</small></td></tr>';
			 }
			 
			 description+= '</tbody></table>';
			 		 
			$('summary')
				.update(unescape(RoutenPlaner.lang['Interface._onGDirectionsLoad.searchResults']) + ': ' + this._gdir.getSummaryHtml())
				.show();
			$('routenbeschreibung')
				.update(description)
				.show();
		},
		
		_onGDirectionsError: function($super)
		{
			$super();
			this._showSearchForm();
		}
	});
	
	RoutenPlaner.start = function(element, lang, options)
	{
		var options = Object.extend({
			locale: lang
		}, options || {});
		
		RoutenPlaner.lang = RoutenPlaner.lang[lang];
		
		Event.observe(window, 'unload', GUnload);
		Event.observe(window, 'load', function() {
			if (GBrowserIsCompatible())
			{
				try
				{
					new RoutenPlaner.Interface(element, options);
				}
				catch(e)
				{
					alert(e);
				}
			}
			else
			{
				alert("Sorry, the Google Maps API is not compatible with this browser.");
			}
		});
	}