/*########## bePALmap Funktionen ##########*/
function addMarker(marker)
{
	getMapObj().addOverlay(marker);
}

function removeMarker(marker)
{
	if (marker)
		getMapObj().removeOverlay(marker);
}

function createMarker(mPoint, icon) 
{ 
	if(icon) 
	{
		return new GMarker(mPoint, icon); 
	} 
	else 
	{
		return new GMarker(mPoint); 
	}
}

function createTextMarker(mPoint, mText, mIcon, markerId, mLabel) 
{ 
	var opts = {};
	if (mIcon)
		opts.icon = mIcon;
	if (mLabel)
		opts.title = mLabel;
	var marker = new GMarker(mPoint, opts);
	
	if (markerId >= 0)
	{
		GEvent.addListener(marker, 'click', function() { showMarkerDetails(markerId, false); });
	}
	else
		GEvent.addListener(marker, 'click', function() { marker.openInfoWindowHtml(mText); });
	if (zoomMarker)
	{
		GEvent.addListener(marker, 'mouseover', function() { showZoomMarker(marker); });
		GEvent.addListener(marker, 'mouseout', function() { timerReset("hideZoomMarker()"); });
	}
	return marker; 
}

function panMapTo(lat, lng) 
{
	getMapObj().setCenter(new GLatLng(lat, lng));
}

function setZoomlevel(level) 
{
	getMapObj().setZoom(level);
}

function showAddress(address) 
{
	if (geocoder) 
	{
		geocoder.getLatLng(address, function(point)
		{ 
			if (!point) {
				alert(address+' konnte nicht gefunden werden');
			} else { 
				getMapObj().removeOverlay(arrowmarker);
				getMapObj().setCenter(point, 13);
				arrowmarker = createMarker(point, getArrowIcon());
				getMapObj().addOverlay(arrowmarker);
			}
		});
	}
}

function getIcon(img)
{
	if (img)
	{
		var icon = new GIcon(baseIcon);
		icon.image = iconPath + img;
		return icon;
	}
	return baseIcon;
}

function getArrowIcon()
{
	var icon = new GIcon();
	icon.image = iconPath + 'arrow_0.png';
	icon.shadow = iconPath + 'arrow_shadow.png';
	icon.iconSize = new GSize(39, 34);
	icon.shadowSize = new GSize(39, 34);
	icon.iconAnchor= new GPoint(10, 32);
	return icon;
}

function createZoomMarker(icImg, icW, icH, shImg, shW, shH, anchX, anchY, anchInfoX, anchInfoY, titletext)
{
	var ic = new GIcon();
	ic.image = icImg;
	ic.iconSize = new GSize(icW, icH);
	ic.iconAnchor = new GPoint(anchX, anchY);
	if (shImg)
	{
		ic.shadow = shImg;
		ic.shadowSize = new GSize(shW, shH);
	}
	if (anchInfoX && anchInfoY)
		ic.infoWindowAnchor = new GPoint(anchInfoX, anchInfoY);
	else
		ic.infoWindowAnchor = new GPoint(0, 0);
	
	var opts = {
		icon:ic,
		zIndexProcess:function(){ return 10000; },
		title:titletext
		};
	zoomMarker = new GMarker(new GLatLng(0, 0), opts);
	zoomMarker.hide();
	GEvent.addListener(zoomMarker, 'click', function() { zoomPanTo(zoomMarker); });
	GEvent.addListener(zoomMarker, 'mouseover', function() { timerStop(); });
	GEvent.addListener(zoomMarker, 'mouseout', function() { timerReset("hideZoomMarker()"); });
	addMarker(zoomMarker);
}

function showZoomMarker(marker)
{
	if ((getMapObj().getZoom() < mapMaxZoom) && zoomMarker.isHidden())
	{
		timerStop();
		zoomMarker.setPoint(marker.getPoint());
		zoomMarker.show();
	}
}

function hideZoomMarker()
{
	zoomMarker.hide();
}

function zoomPanTo(marker) 
{
	hideZoomMarker();
	var ln = marker.getPoint();
	panMapTo(ln.lat(), ln.lng());
	setZoomlevel(mapMaxZoom);
}

function submitRoute(tohere, print, targetId)
{
	var markeraddress = document.getElementById('markeraddress').value;
	var address = '';
	if (document.getElementById('routingaddress') !== null)
	{
		address = document.getElementById('routingaddress').value;
	}
	address = (address.length < 1) ? routingaddress : address;
	var url = (print) ? 'http://maps.google.de/maps?hl=de&f=d&z=17&om=1&pw=2&' : 'http://maps.google.de/maps?';
	var start = 'saddr=';
	var dest = 'daddr=';
	if (tohere)
	{
		start += address;
		dest += markeraddress;
	}
	else
	{
		start += markeraddress;
		dest += address;
	}
	
	logRoute(print, targetId);
	showInfo(targetId);
	
	url += start + '&' + dest;
	window.open(url, '_blank');
}

function logRoute(print, targetId)
{
	var action = (print) ? "drucken" : "berechnen";
	loadXML(basepath + 'logAction.php?id='+ownUserId+'&action='+action+'&target='+targetId, null);
}

function setMapSize()
{
	var size = getBodySize();
	var w = (size[0] > 0) ? size[0] : 800;
	w = w - mapMarginX;
	
	var h = (size[1] > 0) ? size[1] : 600;
	var mapDiv = getElement(mapContainerId);
	var pos = findPos(mapDiv);
	h = h - pos[1] - 10;
	
	var csideDiv = getElement('cSidebar');
	mapDiv.style.height = h + 'px';
	if (sidebarWidth > 0)
	{
		mapDiv.style.width = (w - sidebarWidth) + 'px';
		var sideDiv = getElement('bePALsidebar');
		var detailDiv = getElement('detailbar');
		csideDiv.style.height = h + 'px';
		csideDiv.style.top = pos[1] + 'px';
		var sh = Math.round(h * 0.46);
		sideDiv.style.height = sh + 'px';
		detailDiv.style.height = (h - sh - 6) + 'px';
	}
	else
	{
		mapDiv.style.width = w + 'px';
		if (csideDiv)
			csideDiv.style.display = 'none';
	}
}

/**
 * gibt den Befehl zum speichern der Kartenposition und Zoom in die DB
**/
function saveMapOptions(savepath)
{
	var mapObj = getMapObj();
	if (typeof mapObj != 'object')
		return;
	var z = mapObj.getZoom();
	var latlng = mapObj.getCenter();
	var lat = latlng.lat();
	var lng = latlng.lng();

	savepath += '&lat=' + lat + '&lng=' + lng + '&zoom=' + z;
	window.location.href = savepath;
}

/**
 * Lädt XML-Datei führt die übergebene Funktion aus
**/
function loadXML(url, func)
{
	//IE
	var xmlDoc;
	if (window.ActiveXObject)
	{
		xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
		xmlDoc.async = false;
		xmlDoc.load(url);
		if (func)
			func(xmlDoc);
	}
	//Mozilla, Firefox, Opera, etc.
	else if (document.implementation && document.implementation.createDocument)
	{
		xmlDoc = document.implementation.createDocument("", "", null);
		xmlDoc.load(url);
		if (func)
			xmlDoc.onload = function() { func(xmlDoc); };
	}
	else
	{
		alert('Die hier verwendeten interaktiven Inhalte sind mit Ihrem \nverwendeten Browser leider nicht kompatibel. \nEs können keine Daten dargestellt werden');
	}
}

/**
 * prüft, ob Kartendaten neu geladen werden müssen
**/
var checkUpdates = function(xmlDoc) 
{
	var t = new Date();
	t = t.getTime();
	var update = getTextContent(xmlDoc.getElementsByTagName("lastUpdate")[0]);
	if ((update != lastUpdate) || (markerList.length < 1))
	{
		lastUpdate = update;
		loadXML(xmlPath +'placemarks.xml?t='+t, initOverlays);
	}
	mapRefreshTimer = window.setTimeout(function() { loadXML(xmlPath +'version.xml?t='+t, checkUpdates); }, 30000);
	if (window.loadBanner)
		loadBanner();
}

/**
 * Erzeugt die Marker Icons
 * @param xmlNodes IconStyle Nodes
**/
function createMarkerIcons(xmlNodes)
{
	if (iconList.length > 0)
		return;
	for (var i = 0; i < xmlNodes.length; i++) 
	{
		var icon = xmlNodes[i].getElementsByTagName("Icon")[0];
		if (icon == null)
			continue;

		if ((icon.getElementsByTagName("href")[0] == null) || getTextContent(icon.getElementsByTagName("href")[0]).length < 2)
			continue;
		var icId = xmlNodes[i].getAttribute("id");
		var icW = getTextContent(icon.getElementsByTagName("width")[0]);
		var icH = getTextContent(icon.getElementsByTagName("height")[0]);
		var anchX = getTextContent(icon.getElementsByTagName("anchorX")[0]);
		var anchY = getTextContent(icon.getElementsByTagName("anchorY")[0]);
		var infoanchX = getTextContent(icon.getElementsByTagName("infowindowAnchorX")[0]);
		var infoanchY = getTextContent(icon.getElementsByTagName("infowindowAnchorY")[0]);
		var hover = getTextContent(icon.getElementsByTagName("hover")[0]);
		
		var newIcon = new GIcon(baseIcon);
		newIcon.iconAnchor= new GPoint(anchX, anchY);
		newIcon.shadow = getTextContent(icon.getElementsByTagName("shadow")[0]);
		newIcon.shadowSize = new GSize(icW, icH);
		newIcon.image = getTextContent(icon.getElementsByTagName("href")[0]);
		newIcon.iconSize = new GSize(icW, icH);
		newIcon.infoWindowAnchor = new GPoint(infoanchX, infoanchY);
		iconList[icId] = newIcon;
		
		if ((hover !== null) || (hover.length > 1))
		{
			var hoverIcon = new GIcon(newIcon);
			hoverIcon.image = getTextContent(icon.getElementsByTagName("hover")[0]);
			iconList[icId + 'Hover'] = hoverIcon;
		}
	}
}

function getIndexOfMarker(id)
{
	for (var i = 0; i < markerList.length; i++) 
	{
		if (markerList[i][0] == id)
			return i;
	}
	return -1;
}

function setFilter(type, id)
{
	if (type == 1)
		filter.type = id;
	else
		filter.state = id;

	filter.changed = true;
	loadXML(xmlPath +'placemarks.xml', initOverlays);
}

function addMarkerFromPlacemark(xmlNode)
{
	var id = xmlNode.getAttribute("id");
	var ppoint = getTextContent(xmlNode.getElementsByTagName("coordinates")[0]).split(",");
	if (ppoint.length < 2 || id < 1)
		return null;
	var lastUpdate = getTextContent(xmlNode.getElementsByTagName("lastUpdate")[0]);
	var markerIndex = getIndexOfMarker(id);
	if (filter.changed !== true && markerIndex >= 0 && markerList[markerIndex][6] == lastUpdate)
		return null;
	var platlng = new GLatLng(ppoint[1], ppoint[0]);
	if (id == ownUserId)
	{
		if (ownMarker)
			getMapObj().removeOverlay(ownMarker);
		ownMarker = createMarker(platlng, getArrowIcon());
		addMarker(ownMarker);
		var ownImg = getElement('ownAmpelstateImg');
		if (ownImg != null)
			ownImg.src = iconPath + 'ampel_status_'+ getTextContent(xmlNode.getElementsByTagName("ampelState")[0]) +'.png';
		return;
	}
	
	var picon;
	var pdesc;
	var sbDesc;
	var ampelstate = 0;
	var typeId = 0;
	var fType = (filter.type == 'undefined') ? 0 : parseInt(filter.type);
	var fState = (filter.state == 'undefined') ? 0 : parseInt(filter.state);
	var meta = xmlNode.getElementsByTagName("MetaData")[0];
	if (meta == null)
	{
		picon = getTextContent(xmlNode.getElementsByTagName("styleUrl")[0]).substring(6);
		pdesc = getTextContent(xmlNode.getElementsByTagName("description")[0]);
	}
	else
	{
		picon = getTextContent(xmlNode.getElementsByTagName("iconStyle")[0]);
		pdesc = getTextContent(xmlNode.getElementsByTagName("markerText")[0]);
		sbDesc = getTextContent(xmlNode.getElementsByTagName("sidebarText")[0]);
		ampelstate = getTextContent(xmlNode.getElementsByTagName("ampelState")[0]);
		typeId = getTextContent(xmlNode.getElementsByTagName("typeId")[0]);
	}
	
	//filtern
	if ((fType > 0 && fType != typeId) || (fState > 0 && ampelstate == 1))
	{
		if (markerIndex >= 0)
		{
			getMapObj().removeOverlay(markerList[markerIndex][3]);
			markerList.splice(markerIndex, 1);
		}
		return;
	}

	var dist = (platlng.distanceFrom(ownMarker.getPoint()) / 1000).toFixed(2);
	var name = getTextContent(xmlNode.getElementsByTagName("name")[0]);
	var marker;
	if (markerIndex >= 0)
	{
		marker = createTextMarker(platlng, pdesc, iconList[picon], id, name);
		getMapObj().removeOverlay(markerList[markerIndex][3]);
		markerList[markerIndex] = [id, dist, name, marker, pdesc, sbDesc, lastUpdate, ampelstate];
	}
	else
	{
		marker = createTextMarker(platlng, pdesc, iconList[picon], id, name);
		markerList.push([id, dist, name, marker, pdesc, sbDesc, lastUpdate, ampelstate]);
	}
	addMarker(marker);
}

/**
 * Fügt die Marker aus der XML-Datei in die Karte ein
**/
var initOverlays = function(xmlDoc)
{
	//icons erzeugen
	createMarkerIcons(xmlDoc.getElementsByTagName("IconStyle"));
	
	//marker holen und erzeugen
	xmlNodes = xmlDoc.getElementsByTagName("Placemark");
	for (var i = 0; i < xmlNodes.length; i++) 
	{
		addMarkerFromPlacemark(xmlNodes[i]);
	}
	
	//Sidebar erzeugen
	//marker nach Entfernung sortieren
	markerList.sort(function(a,b) { return compareArray(a[1],b[1],'num');});
	sidebarList = [];
	for (var i = 0; i < markerList.length; i++) 
	{
		if (sidebarList.length > 19)
			break;
		if (markerList[i][7] <= 1)
			continue;
		sidebarList.push('<p><img src="'+ iconPath +'ampel_info_'+ markerList[i][7] +'.png"> <a href="javascript:void(0)" onclick="showDirection('+ markerList[i][0] +', true)"><b>'+ markerList[i][2] +'</b></a><br />Entfernung: ' + markerList[i][1] + ' km.</p>');
	}
	
	var sb = getElement('bePALsidebar');
	sb.innerHTML = sidebarList.join(" ");
	filter.changed = false;
}

function showMarkerDetails(markerId, dir)
{
	var idx = getIndexOfMarker(markerId);
	if (idx < 0)
		return;
	var m = markerList[idx][3];
	var p = m.getLatLng();
	getMapObj().openInfoWindowHtml(p, markerList[idx][4]);
	var db = getElement('detailbar');
	db.innerHTML = markerList[idx][5];
	if (ownMarker && dir)
	{
		var bounds = new GLatLngBounds();
		bounds.extend(p);
		bounds.extend(ownMarker.getLatLng());
		getMapObj().setZoom(getMapObj().getBoundsZoomLevel(bounds));
		getMapObj().setCenter(bounds.getCenter());
		bePALdirection.load("from: "+ ownMarker.getLatLng().toUrlValue() +" to: "+ p.toUrlValue());
	}

	//var dd = bePALdirection.getDistance();
	//var ds = bePALdirection.getStatus();
	//var c = 0;
}

function showDirection(markerId, closeInfo)
{
	if (ownMarker == null)
		return;
	var idx = getIndexOfMarker(markerId);
	if (idx < 0)
		return;
	if (closeInfo)
		getMapObj().closeInfoWindow();
	var db = getElement('detailbar');
	db.innerHTML = markerList[idx][5];
	var m = markerList[idx][3];
	bePALdirection.load("from: "+ ownMarker.getPoint().toUrlValue() +" to: "+ m.getPoint().toUrlValue(), { preserveViewport:true });

	var oLat = parseFloat(ownMarker.getPoint().lat()); //start
	var mLat = parseFloat(m.getPoint().lat()); //end
	var oLng = parseFloat(ownMarker.getPoint().lng());
	var mLng = parseFloat(m.getPoint().lng());
	
	var offset = 0.006;
	var sLat = (mLat > oLat) ? (offset * -1) : offset;
	var eLat = (mLat > oLat) ? offset : (offset * -1);
	if (mLat > oLat && !closeInfo) //Start ist südlicher als end
		eLat += offset;
	
	var sLng = (oLng < mLng) ? (offset * -1) : offset;
	var eLng = (oLng < mLng) ? offset : (offset * -1);
	
	var bounds = new GLatLngBounds();
	bounds.extend(new GLatLng(oLat + sLat, oLng + sLng));
	bounds.extend(new GLatLng(mLat + eLat, mLng + eLng));
	var z = getMapObj().getBoundsZoomLevel(bounds);
//	if (!closeInfo)
//		z--;
	getMapObj().setZoom(z);
	getMapObj().setCenter(bounds.getCenter());
}

function clearDirection()
{
	if (bePALdirection != null)
		bePALdirection.clear();
}
/*END########## bePALmap Funktionen ##########*/


/*########## Timer Funktionen ##########*/
var timerId = null;
var delay = 1000;
function timerReset(func)
{
	timerStop();
	timerStart(func, delay);
}

function timerStop()
{
	if (timerId)
	{
		clearTimeout(timerId);
		timerId = null;
	}
}

function timerStart(func, delay)
{
	timerId = window.setTimeout(func, delay);
}
/*END########## Timer Funktionen ##########*/


/*########## Allgemeine Funktionen ##########*/
function hideOverlay(objId)
{
	var d = getElement(objId);
	d.style.display = "none";
}

function getElement(elementId)
{
	return (document.getElementById) ? document.getElementById(elementId) : document.all.elementId;
}

function getTextContent(domNode)
{
	return ((domNode == null) || (domNode.childNodes.length < 1)) ? '' : domNode.childNodes[0].nodeValue;
}

function compareArray(a, b, type)
{
	if (type == 'num')
		return a - b;
	else
	{
		if (a < b) 
			return -1;
		if (a > b) 
			return 1;
		return 0;
	}
}

function findPos(obj) 
{
	var left = 0;
	var top = 0;
	if (obj.offsetParent) 
	{
		left = obj.offsetLeft
		top = obj.offsetTop
		while (obj = obj.offsetParent) 
		{
			left += obj.offsetLeft
			top += obj.offsetTop
		}
	}
	return [left, top];
}

/**
 *	Liefert die Breite und Höhe des sichtbaren Browser-Body
 * @return Array [0] = Breite, [1] = Höhe
**/
function getBodySize()
{
	var w = -1;
	if(window.innerWidth)
		w = window.innerWidth;
	else if(document.body && document.body.clientWidth)
		w = document.body.clientWidth;
	
	var h = -1;
	if(window.innerHeight)
		h = window.innerHeight;
	else if(document.documentElement)
		h = document.documentElement.offsetHeight;
	else if(document.body && document.body.offsetHeight)
		h = document.body.offsetHeight;
	
	return [w, h];
}
/*END########## Allgemeine Funktionen ##########*/

