/**
 * @var Object GmapObject
 * @var settings
 */
var routePlanner = function(GmapObject, settings)
{
	/**
	 * @access private
	 */
	var settings = jQuery.extend({
		'form':             '#routeplanner-form',
		'formStreetField':  '#routeplanner-street',
		'formZipField':     '#routeplanner-zip',
		'formCityField':    '#routeplanner-city',
		'contentContainer': '#routeplanner-container',
		'content':          '#routeplanner-content',
		'lang':             'DE_de',
		'langFallback':     'default'
	}, settings || {});

	if (routePlanner.translations[settings.lang])
		this.translations = routePlanner.translations[settings.lang];
	else if (settings.langFallback && routePlanner.translations[settings.langFallback])
		this.translations = routePlanner.translations[settings.langFallback];
	else
		throw('No translations for "' + settings.lang + '" found');

	/**
	 * @access public
	 * @return Object
	 */
	this.getSettings = function()
	{
		return settings;
	};

	/**
	 * @return GMap2
	 * @access public
	 */
	this.getGmapObject = function()
	{
		return GmapObject
	};

	jQuery(this.getSettings().form).submit(jQuery.proxy(function() {
		this.doSearchRoute();
		return false;
	}, this));
};

/**
 * @access public
 * @return boolean
 */
routePlanner.prototype.doSearchRoute = function()
{
		var street = jQuery(this.getSettings().formStreetField).val();
		var zip    = jQuery(this.getSettings().formZipField).val();
		var city   = jQuery(this.getSettings().formCityField).val();

		if (street.length == 0)
		{
			alert(unescape(this.translations['Interface._doSearch.streetError']));
			jQuery(this.getSettings().formStreetField).focus();
			return false;
		}
		else if (zip.length > 0 && (zip.length < 5 || !/^\d+$/.test(zip)))
		{
			alert(unescape(this.translations['Interface._doSearch.zipError']));
			jQuery(this.getSettings().formZipField).focus();
			return false;
		}
		else if (city.length == 0)
		{
			alert(unescape(this.translations['Interface._doSearch.cityError']));
			jQuery(this.getSettings().formCityField).focus();
			return false;
		}

		this.getGmapObject().setDirections(
			{ 'street': street, 'zip': zip, 'city': city, country: 'DE' },
			this.getSettings().to
		);

		return true;
};

/**
 * @access public
 */
routePlanner.prototype.onDirectionLoad = function()
{
	this.getGmapObject().getMarkerManager().clearMarkers();

	var GDirectionsObject = this.getGmapObject().getGDirectionsObject();

	var description = unescape(this.translations['Interface._onGDirectionsLoad.summary']) + ' ' +
		GDirectionsObject.getSummaryHtml();

	description+= '<table id="routeplanner-result-table" cellpadding="0" cellspacing="0"><thead><tr>' +
		'<th class="rank"></th>' +
		'<th class="description">' + unescape(this.translations['Interface._onGDirectionsLoad.description']) + '</th>' +
		'<th class="distance">' + unescape(this.translations['Interface._onGDirectionsLoad.distance']) + '</th>' +
		'<th class="time">' + unescape(this.translations['Interface._onGDirectionsLoad.timeToTravel']) + '</th>' +
		'</tr></thead><tbody>';

	for (var i=0; i < GDirectionsObject.getRoute(0).getNumSteps(0); i++)
	{
		description+= '<tr><td class="rank">' + (i + 1) + '</td>' +
			'<td class="description">' + GDirectionsObject.getRoute(0).getStep(i).getDescriptionHtml() + '</td>' +
			'<td class="distance">' + GDirectionsObject.getRoute(0).getStep(i).getDistance().html + '</td>' +
			'<td class="time"><small>' + GDirectionsObject.getRoute(0).getStep(i).getDuration().html + '</small></td></tr>';
	}

	description+= '</tbody></table>';

	jQuery(this.getSettings().contentContainer).show();
	jQuery(this.getSettings().content).html(description);
};

/**
 * @access public
 */
routePlanner.prototype.onDirectionError = function()
{
	var GDirectionsObject = this.getGmapObject().getGDirectionsObject();
	if (GDirectionsObject.getStatus().code == G_GEO_UNKNOWN_ADDRESS)
		alert(unescape(this.translations['GoogleMaps._onGDirectionsError.unknownAddress']));
	else if (GDirectionsObject.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 (GDirectionsObject.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 (GDirectionsObject.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: " + GDirectionsObject.getStatus().code);
	else if (GDirectionsObject.getStatus().code == G_GEO_BAD_REQUEST)
		alert("A directions request could not be successfully parsed.\n Error code: " + GDirectionsObject.getStatus().code);
	else
		alert("An unknown error occurred.");
};

/**
 * Translations.
 * @var Object
 */
routePlanner.translations = {
	'default': {
		'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.summary': 'search results:'
	}
};

