/*===============================================================================
 Red4Net(R) - Content Management System : www.netsoftworks.eu
 Copyright (C) 2000-11 NETSOFTWORKS - Antonio Fonseca All Rights Reserved
 ===============================================================================*/
/**
 * SCRIPT: google_map_init_lib.js
 * DESCR:	 Bibliothek mit Initialisierungsfunktionen für GoogleMaps.
 * INTERFACE:
 * function googleMapInitDispatcher(mapConfig)
 * function googleMapInitBlock(mapConfig)
 * function googleMapInitList(mapConfig, canvas)
 * function googleMapInitContent(mapConfig)
 * function googleMapInitTextModule(mapConfig)
 * function googleMapInitSearch(mapConfig)
 * ==============================================================================
 *
 * function initializeGoogleMap(map)
 * function addSearchFormHandler()
 * function createMarker(map, point)
 * function createObjMarker(map, obj)
 * function getInfoWindowContent(map, marker, obj)
 * function calculateZoom()
 * function clearLocation()
 * function clearCoordinates()
 * function setCoordinates(point)
 * function createCircle(map, center, radius, nodes, strokeColor, strokeWeight, strokeOpacity, fillColor, fillOpacity)
 * ==============================================================================
 * function getCanvas(mapConfig)
 * function dump(mapConfig)
 */
// Globale Variablen
var infowindow; //An overlay that looks like a bubble
/** dispatches the init functions for google maps
 */
function googleMapInitDispatcher(mapConfig) {

	// canvas
	var canvas = getCanvas(mapConfig);
	if ('undefined' === typeof(canvas)) 
		return;
	// callback
	switch (mapConfig.call) {
		case 'googleMapInitBlock':
			googleMapInitBlock(mapConfig, canvas);
			break;
		case 'googleMapInitContent':
			googleMapInitContent(mapConfig, canvas);
			break;
		case 'googleMapInitList':
			googleMapInitList(mapConfig, canvas);
			break;
		case 'googleMapInitTextModule':
			googleMapInitTextModule(mapConfig, canvas);
			break;
		case 'googleMapInitSearch':
			googleMapInitSearch(mapConfig, canvas);
			break;
		default:
			alert('unregistered google map init function: ' + mapConfig.call);
			
	}
}

/** google map init funtion for blocks
 */
function googleMapInitBlock(mapConfig, canvas) {

	// point
	var point = new google.maps.LatLng(mapConfig.latitude, mapConfig.longitude);
	
	var myOptions = {
		center: point,
		zoom: mapConfig.zoom,
		disableDefaultUI: true,
		mapTypeId: google.maps.MapTypeId.ROADMAP
	}
	// map
	var map = new google.maps.Map(canvas, myOptions);
	
	// marker
	var marker = new google.maps.Marker({
		position: point,
		map: map
	});
	
}

function googleMapInitList(mapConfig, canvas) {

	if (canvas) {
		var myOptions = {
			center: new google.maps.LatLng(51.151786, 10.415039),
			zoom: 4,
			panControl: true,
			zoomControl: true,
			scaleControl: true,
			mapTypeId: google.maps.MapTypeId.ROADMAP
		}
		var map = new google.maps.Map(canvas, myOptions);

		//spinner while loading marker
		var img=new Image(16, 16);
		$(img).attr('alt','loading markers');
		$(img).attr('id', 'r4n-map-icon-loading');
		$(img).attr('style', 'z-index: 100000; margin-left:100px;');
		$(img).attr('src', '/share/modules/blockui/spinner.gif');
		map.controls[google.maps.ControlPosition.TOP].push(img);

		// get href vom window.top
		$.url.setUrl(window.top.location) 
		var referrer = $.url.attr('file');
		var scriptName, typeParam;
		if ("pub_org.asp" == referrer) {
			scriptName = "serv_front_group_action.asp";
			typeParam = "typ";
		} else if ("pub_content_list.asp" == referrer || "pub_content.asp" == referrer) {
			scriptName = "serv_front_content_action.asp";
			typeParam = "content";
		} else {
			alert('cannot determine script to request markers');
			return;
		}

		var data;
		var url = scriptName + '?' + $.url.attr('query');
		$.ajax({
			type: 'GET',
			url: url,
			data: {
				anti: Math.random(),
				action: 'getMarkerListJson'
			},
			async: true, // needs to be synchronized!
			dataType: 'json', // get object as json
			success: function(data, status, xhr) {
				data = data;
				// LatLngBounds object
				var bounds = new google.maps.LatLngBounds();
				// Array for all Markers
				var markers = [];
				for (i = 0; i < data.objs.length; i++) {
					var lat = data.objs[i].latitude;
					var lng = data.objs[i].longitude
					if ('' != lat && '' != lng) {
						var obj = new Object();
						obj['title'] = data.objs[i].title;
						obj['point'] = new google.maps.LatLng(lat, lng);
						obj['id'] = data.objs[i].id;
						obj['typeId'] = $.url.param(typeParam);
						// Extending the bounds object with each LatLng
						bounds.extend(obj['point']);
						//Create Marker and add to MarkerArray
						var marker = createObjMarker(map, obj);
						markers.push(marker);
					}
				}
				//hide spinner
				$('#r4n-map-icon-loading').hide();

				// Create MarkerCluster, on maxZoom all markers are displayed
				var markerCluster = new MarkerClusterer(map, markers, {
					maxZoom: 8
				});
				// Adjusting the map to new bounding box
				map.fitBounds(bounds)
				//close InfoWindow
				google.maps.event.addListener(map, 'click', function() {
					if (infowindow) 
						infowindow.close();
				});
			},
			error: function(xhr, status, error) {
				data = {};
				//alert(error)
			}
			
		});
	}

}

/** google map init funtion for content
 */
function googleMapInitContent(mapConfig, canvas) {

	// point
	var point = new google.maps.LatLng(mapConfig.latitude, mapConfig.longitude);
	
	var myOptions = {
		center: point,
		zoom: mapConfig.zoom,
		panControl: true,
		zoomControl: true,
		scaleControl: true,
		mapTypeId: google.maps.MapTypeId.ROADMAP
	}
	
	var map = new google.maps.Map(canvas, myOptions);
		// Marker erstellen
	var image = new google.maps.MarkerImage(app_template_url + '/images/star-3.png', new google.maps.Size(32, 37), new google.maps.Point(0, 0), new google.maps.Point(16, 45));
	// marker
	var marker = new google.maps.Marker({
		position: point,
		map: map,
		icon: image
	})

	if ($('#directions_panel').length > 0) {
		// Route
		directionsDisplay = new google.maps.DirectionsRenderer();
		directionsDisplay.setMap(map);
		directionsDisplay.setPanel(document.getElementById('directions_panel'));
		var startControl = document.getElementById('start_control');
		startControl.style.display = 'block';
		map.controls[google.maps.ControlPosition.BOTTOM].push(startControl);
	}
}

/** google map init funtion for text modules
 */
function googleMapInitTextModule(mapConfig, canvas) {

	// point
	var point = new google.maps.LatLng(mapConfig.latitude, mapConfig.longitude);
	
	var myOptions = {
		center: point,
		zoom: mapConfig.zoom,
		panControl: true,
		zoomControl: true,
		scaleControl: true,
		mapTypeId: google.maps.MapTypeId.ROADMAP
	}
	
	// map
	var map = new google.maps.Map(canvas, myOptions);

	// Marker erstellen
	var image = new google.maps.MarkerImage(app_template_url + '/images/star-3.png', new google.maps.Size(32, 37), new google.maps.Point(0, 0), new google.maps.Point(16, 45));
	// marker
	var marker = new google.maps.Marker({
		position: point,
		map: map,
		icon: image
	});
	
}

/** google map init funtion for search
 */
function googleMapInitSearch(mapConfig, canvas) {

	var myOptions = {
		panControl: true,
		zoomControl: true,
		scaleControl: true,
		streetViewControl: false,
		mapTypeId: google.maps.MapTypeId.ROADMAP
	}
	
	// Karte in Division erstellen
	var map = new google.maps.Map(canvas, myOptions);
	
	//latitude = 51; longitude = 9.5; // initiale Koordinaten
	//latitude und longitude (initiale Koordinaten) werden im Template definiert
	
	// GoogleMap initialisieren
	initializeGoogleMap(map);
	
	// Handler zum Submit des SuchFormulares hinzufügen
	addSearchFormHandler(mapConfig, map);
	
}

/* ============================================================================== */

/** Initialisiert die GoogleMap anhand der Daten aus dem Formular des Vaterfensters.
 */
function initializeGoogleMap(map) {

	var currentLatitude;
	var currentLongitude;
	
	// from template
	// latitude, longitude, initialZoom werden im Template definiert
	if (latitude && longitude) {
		currentLatitude = latitude;
		currentLongitude = longitude;
		if (initialZoom) 
			map.setZoom(initialZoom);
	}
	// from form
	// Koordinaten nach denen gesucht wurde
	var searchLatitude = $('#search_latitude').val(); // hidden input
	var searchLongitude = $('#search_longitude').val(); // hidden input
	if (searchLatitude && searchLongitude) {
		//alert('searchLatitude und searchLongitude vorhanden');
		currentLatitude = searchLatitude * 1;
		currentLongitude = searchLongitude * 1;
		// nötig?
		latitude = searchLatitude * 1;
		longitude = searchLongitude * 1;
		map.setZoom(calculateZoom());
	}
	
	if (currentLatitude && currentLongitude) {
		//alert('currentLatitude und currentLongitude vorhanden');
		var point = new google.maps.LatLng(currentLatitude, currentLongitude);
		// Karte zentrieren
		map.setCenter(point);
		if (searchLatitude && searchLongitude) {
			//alert('searchLatitude und searchLongitude vorhanden');
			// Marker erzeugen
			marker = createMarker(map, point);
			// Umkreis erzeugen
			var search_circle = $('#search_circle').val();
			if (0 < search_circle.length) {
				// alten Circle entfernen
				if (circle) 
					circle.setMap(null);
				// Circle erzeugen
				circle = createCircle(map, point, search_circle);
			}
		}
	}
	// ClickEventHandler für Map
	google.maps.event.addListener(map, 'click', function(event) {
		map.setCenter(event.latLng); // Karte zentrieren & zoomen
		map.setZoom(calculateZoom()); // Karte zoomen
		if (marker) {
			marker.setPosition(event.latLng); // Marker verschieben
		} else {
			marker = createMarker(map, event.latLng); // oder Marker erzeugen
		}
		
		if (circle) 
			circle.setMap(null); // Circle entfernen
		if ($('#search_circle').val() == '') {
			$('#search_circle').val(100);
		}
		circle = createCircle(map, event.latLng, $('#search_circle').val()); // Circle erzeugen
		setCoordinates(event.latLng); // Koordinaten in eigenes Fenster schreiben
		clearLocation(); // Adresse löschen
	});
	
	// Geocoder erstellen
	geocoder = new google.maps.Geocoder();
	
	// bounds ?wofür?
	if (fitMap) 
		bounds = new google.maps.LatLngBounds();
	
}

/** Fügt dem SuchFormular einen Handler hinzu, sodaß beim Submit geprüft wird,
 * ob Koordinaten zur Verfügung stehen.
 */
function addSearchFormHandler(mapConfig, map) {

	// form
	if ($('#form_advanced_search').length <= 0) 
		return;
	
	$('#form_advanced_search').submit(function() {
		var form = this;
		// Koordinaten nach denen gesucht wurde
		var searchLatitude = $('#search_latitude').val(); // hidden input
		var searchLongitude = $('#search_longitude').val(); // hidden input
		// Wenn Länge und Breite bekannt sind muß ich diese
		// nicht erst ermitteln und kann das Formular abschicken
		if (searchLongitude && searchLatitude) 
			return true;
		// PLZ oder Ort nach dem gesucht wurde
		var searchLocation = $('#search_location').val(); // text input
		// Wenn weder nach PLZ noch Ort gesucht wurde muß ich keine
		// Koordinaten ermitteln und kann das Formular abschicken
		if (searchLocation.length == 0) 
			return true;
		// Jetzt hab ich zwar eine "Adresse" aber keine Koordinaten
		// also kann ich diese mittels Geocoder ermitteln:
		// Koordinaten der Adresse mittels Geocoder abfragen
		
		geocoder.geocode({
			'address': searchLocation
		}, function(results, status) {
			// Abrechen wenn keine Koordinaten ermittelt werden konnten
			if (status != google.maps.GeocoderStatus.OK) {
				alert(status);
				return
			}
			// Koordinaten in eigenes Fenster schreiben
			setCoordinates(results[0].geometry.location);
			form.submit();
		});
		return false;
	});
	
	$('#search_location').focus(function() {
		//clearCoordinates();
	}).change(function() {
		var searchString = $(this).val(); // text input
		if (searchString.length == 0) 
			return true;
		// Koordinaten der Adresse mittels Geocoder abfragen
		geocoder.geocode({
			'address': searchString
		}, function(results, status) {
			// Abrechen wenn keine Koordinaten ermittelt werden konnten
			if (status != google.maps.GeocoderStatus.OK) {
				alert(status);
				return
			}
			// Karte zentrieren
			map.setCenter(results[0].geometry.location);
			map.setZoom(initialZoom);
			if (marker) 
				marker.setPosition(results[0].geometry.location); // Marker verschieben

			else marker = createMarker(map, results[0].geometry.location); // oder erzeugen wenn es noch keinen gibt
			if (circle) 
				circle.setMap(null); // Circle entfernen
			circle = createCircle(map, results[0].geometry.location, $('#search_circle').val()); // Circle erzeugen
			setCoordinates(results[0].geometry.location); // Koordinaten in eigenes Fenster schreiben
		});
	});
	
	$('#search_circle').change(function() {
		if (!marker) 
			return;
		
		// ist not numeric or empty: no circumcircle search
		if (isNaN($('#search_circle').val()) || $('#search_circle').val() == '') {
			marker.setMap(null);
			//damit beim ändern des #search_circle wenn noch kein circumcircle auf
			//der Karte vorhanden ist einem circumcircle ohne Marker hinzugefügt wird.
			marker = null;
			circle.setMap(null);
			// alert when value not empty and not numeric
			if ($('#search_circle').val() != '') {
				alert($('span.search_circle > label').html() + ': ' + $('#search_circle').val() + ' in not numeric! Value will be change to empty.'); //I18N
			}
			$('#search_circle').val('');
			clearCoordinates();
			return false;
		}
		
		if (circle) 
			circle.setMap(null);
		
		circle = createCircle(map, marker.getPosition(), $('#search_circle').val());
		map.setCenter(marker.getPosition());
		map.setZoom(calculateZoom());
	});
	
}

/** Erzeugt einen Marker für die GoogleMap.
 */
function createMarker(map, point) {
	// Marker erstellen
	var image = new google.maps.MarkerImage(app_template_url + '/images/star-3.png', new google.maps.Size(32, 37), new google.maps.Point(0, 0), new google.maps.Point(16, 45));
	//shadow = new google.maps.MarkerImage('/images/gmap/house_shadow.png', new google.maps.Size(70, 50), new google.maps.Point(0, 0), new google.maps.Point(24, 50));
	marker = new google.maps.Marker({
		'position': point,
		'map': map,
		'icon': image,
		'draggable': true,
		'clickable': false
	});
	
	// DragEventHandler für Marker
	google.maps.event.addListener(marker, 'dragend', function() {
		map.setCenter(marker.getPosition()); // Karte zentrieren
		map.setZoom(calculateZoom()); // Karte zoomen
		if (circle) 
			circle.setMap(null); // Circle entfernen
		circle = createCircle(map, marker.getPosition(), $('#search_circle').val()); // Circle erzeugen
		setCoordinates(marker.getPosition()); // Koordinaten in eigenes Fenster schreiben
		clearLocation(); // Adresse löschen
	});
	
	// Marker zurückgeben
	return marker;
}

/**
 * Creates a marker width marker.mouseover -> infoWindow & marker.click -> go to lacation
 */
function createObjMarker(map, obj) {

	var objPoint = obj['point'];
	var objName = obj['title'];
	
	// Marker erstellen
	var image = new google.maps.MarkerImage(app_template_url + '/images/star-3.png', new google.maps.Size(32, 37), new google.maps.Point(0, 0), new google.maps.Point(16, 45));
	//var shadow = new google.maps.MarkerImage('http://www.google.com/mapfiles/shadow50.png', new google.maps.Size(37, 34), new google.maps.Point(-5, 0), new google.maps.Point(18, 34));
	var marker = new google.maps.Marker({
		'position': obj['point'],
		'title': obj['title'],
		'icon': image,
		'map': map
	});
	
	//		'shadow': shadow,
	
	google.maps.event.addListener(marker, 'click', function() {
		getInfoWindowContent(map, marker, obj)
	});
	
	//	google.maps.event.addListener(marker, 'click', function() {
	//		$.url.setUrl();
	//		window.location = 'pub_content.asp?' + $.url.attr('query') + '&id=' + content['id'];
	//	});
	
	return marker;
	
}

function getInfoWindowContent(map, marker, obj) {

	// get href vom window.top
	$.url.setUrl(window.top.location);
	var referrer = $.url.attr('file');

	var urlAction, typ;
	if ("pub_org.asp" == referrer) {
		urlAction = 'serv_front_group_action.asp?org=' + obj['id'];
		typ = $.url.param("typ");
		if(null != typ)
			urlAction += '&typ=' + typ;
	} else if ("pub_content_list.asp" == referrer || "pub_content.asp" == referrer) {
		urlAction = 'serv_front_content_action.asp?id=' + obj['id'];
		typ = $.url.param("content");
		if(null != typ)
			urlAction += '&content=' + typ;
		cat = $.url.param("kat");
		if(null != cat)
			urlAction += '&kat=' + cat;
	}

	var locale = $.url.param('locale');
	if (null != locale)
		urlAction += '&locale=' + locale;

	var pmi = $.url.param('pmi');
	if (null != pmi)
		urlAction += '&pmi=' + pmi;

	var gmi = $.url.param('gmi');
	if (null != gmi)
		urlAction += '&gmi=' + gmi;

	if (infowindow) 
		infowindow.close();

	$.ajax({
		type: 'GET',
		url: urlAction,
		data: {
			anti: Math.random(),
			action: 'getInfoWindowJson'
		},
		async: true, // needs to be synchronized!
		dataType: 'json', // get object as json
		success: function(data, status, xhr) {
			var objImage = undefined === data.image ? '' : data.image;
			var objAbstract = undefined === data['abstract'] ? '' : data['abstract'];
			var objMore = undefined === data.more ? '' : data.more;
			infowindow = new google.maps.InfoWindow({
				content: '<div class="r4n-info-window">' + data.title + objImage + objAbstract + objMore + '</div>'
			});
			infowindow.open(map, marker);
		},
		error: function(xhr, status, error) {
			data = {};
			alert(error);
		}
	});
	
}

/**
 */
function calculateZoom() {
	if (1 > $('#form_advanced_search').length) 
		return 5;
	var zoom;
	var search_circle = $('#search_circle').val() * 1
	if(search_circle < 2){
		zoom = 12;
	} else if(search_circle < 5){
		zoom = 11;
	} else if(search_circle < 10){
		zoom = 10;
	} else if(search_circle < 20){
		zoom = 9;
	} else if(search_circle < 50){
		zoom = 7;
	} else if(search_circle < 100){
		zoom = 6;
	} else if(search_circle < 200){
		zoom = 5;
	} else if(search_circle < 500){
		zoom = 3;
	} else if(search_circle < 1000){
		zoom = 2;
	}	else{
		zoom = 1;
	}
	return zoom;
}

/**
 */
function clearLocation() {
	if (1 > $('#form_advanced_search').length) 
		return;
	$('#search_location').val('');
}

/**
 */
function clearCoordinates() {
	if (1 > $('#form_advanced_search').length) 
		return;
	$('#search_latitude').val('');
	$('#search_longitude').val('');
};

/**
 */
function setCoordinates(point) {
	if (1 > $('#form_advanced_search').length) 
		return;
	$('#search_latitude').val(point.lat());
	$('#search_longitude').val(point.lng());
}

/** Creates a circle around a given point on a google map.
 *	@param map <GMap> the map
 *	@param center <GLatLng> circle center
 *	@param radius <int> circle radius
 *	@param nodes <int> circle points (circle will be created as a polygon)
 *	@param strokeColor <str> line color
 *	@param strokeWeight <int> line width
 *	@param strokeOpacity <dbl> line opacity
 *	@param fillColor <dbl> filling color
 *	@param fillOpacity <dbl> filling opacity
 *	@source http://esa.ilmari.googlepages.com/circle.htm
 */
function createCircle(map, center, radius, nodes, strokeColor, strokeWeight, strokeOpacity, fillColor, fillOpacity) {

	fillColor = fillColor || strokeColor || '#0055ff';
	
	strokeWeight = strokeWeight || 2;
	
	// Add a Circle overlay to the map. 
	//The colors are given as a string
	// that contains the color in hexadecimal numeric HTML style, i.e. #RRGGBB.
	// The weight is the width of the line in pixels. The opacities is given as a
	// number between 0 and 1. The line will be antialiased and semitransparent.
	// (Since 2.69)
	
	
	var circle = new google.maps.Circle({
		map: map,
		center: center,
		strokeColor: strokeColor,
		strokeWeight: strokeWeight,
		strokeOpacity: strokeOpacity,
		fillColor: fillColor,
		fillOpacity: fillOpacity,
		radius: radius * 1000
	});
	
	// Since Circle and Marker both extend MVCObject, you can bind them 
	// together using MVCObject's bindTo() method. Here, we're binding 
	// the Circle's center to the Marker's position. 
	// http://code.google.com/apis/maps/documentation/v3/reference.html#MVCObject 
	//circle.bindTo('center', marker, 'position'); 
	
	
	return circle;
	
}

/** google map Get Directions
 */
function calcRoute(endPoint) {
	
	var startPoint = $('#startroute').attr("value");
	
	var request = {
		origin: startPoint, 
		destination: endPoint,
		travelMode: google.maps.DirectionsTravelMode.DRIVING
	};
	directionsService.route(request, function(response, status) {
		if (status == google.maps.DirectionsStatus.OK) {
			directionsDisplay.setDirections(response);
		}
	});
}
/* ============================================================================== */

/** helper to get canvas object from config
 */
function getCanvas(mapConfig) {
	if (mapConfig.dump) 
		alert(dump(mapConfig));
	//if (!GBrowserIsCompatible())
	//	return;
	if (mapConfig.canvas) {
		var canvas = $(mapConfig.canvas);
		if (1 > canvas.length) 
			return;
		return canvas[0];
	} else {
		return;
	}
}

/** dumps the google map configuration
 */
function dump(mapConfig) {
	var dump = 'DUMP';
	dump += '\n\tcall: ' + mapConfig.call;
	dump += '\n\tcanvas: ' + mapConfig.canvas;
	dump += '\n\tlongitude: ' + mapConfig.longitude;
	dump += '\n\tlatitude: ' + mapConfig.latitude;
	dump += '\n\tzoom: ' + mapConfig.zoom;
	//dump += '\n\ttype: ' + mapConfig.map_type;
	//dump += '\n\tcontrol: ' + mapConfig.controls;
	//dump += '\n\tdrag: ' + mapConfig.dragging;
	return dump;
}

/** Set onunload event handler!

 */

//no GUnload() in v3
//window.onunload = GUnload;

