/*
 * main.js
 * 
 * javascript-Datei
 * 
 * Projekt: Nationalpark Hainich
 * 
 * Diese Datei enthält die Funktionen zur Anzeige einer Google-Maps-Karte.
 * 
 * 
 * ToDo:
 * 
 * 
 * 
 */
var map = "";
var mapConfig = "";
var mapElements = "";
var curActiveMenuButton = "";
var clickHandlerElementCount = "";


//window.onload = function() {
//window.addEvent('domready', function() {
//document.addEvent('domready', function() {
//    //alert("The DOM is ready.");
//	initializeMap();
//});

/* 
 * function initializeMap()
 * 
 * Initalisierung der Google-Map.
 */
function initializeMap(){

	if (GBrowserIsCompatible()) {
		
		//alert("GBrowserIsCompatible!!!");
		// Karte ins DOM einhängen
		map = new GMap2($('map_canvas'));
		
		// default zoomlevel and center point
		var mapConfigZoomlevel = 12;
		var mapCenter = new GLatLng(51.05758110879136, 10.451431274414062);
		var encodedPolyline = new GPolyline();
		
		// find bounding polyline and recalculate map center
		for (var i = 0; i < mapElements.length; i++) {
			if (mapElements[i]['titel'] == "nationalparkhainich") {
					encodedPolyline = GPolyline.fromEncoded({
					points: mapElements[i]['pol'],
					levels: mapElements[i]['lev']
				});
				mapCenter = encodedPolyline.getBounds().getCenter();
				i = mapElements.length;
			}
		}
		
		// reset zoomlevel
		if (mapConfig[0]['zoomlevel']) 
			mapConfigZoomlevel = mapConfig[0]['zoomlevel'];
		// set map center
		map.setCenter(mapCenter, mapConfigZoomlevel);
		
		// set map controls
		map.addControl(new GLargeMapControl());
		map.addControl(new GMapTypeControl());
		
		// Kartenmenue initialisieren
		initializeMapMenue();
	}
	else{
		alert("Browser is not compatible to GoogleMaps API!");		
	}

}


/* function initializeMapMenu()
 * 
 * Initialisierung des Kartenmenüs.
 * Hinzufügen der click-Events für die jeweiligen Kategorie-Elemente 
 */
function initializeMapMenue(){

	clickHandlerElementCount = 0;
	
	// zuerst den Kategorie-Divs die click-Events zuordnen
	var categories = $('ul_mapMenuCategories').getChildren();
	
	/* Alle Kategorie-Elemente durchgehen
	 * und div der ersten Kategorie einblenden
	 * sowie die Ereignisbehandlungroutinen zuordnen 
	 */	
	categories.each(function(categoryItem, categoryIndex){
	
		if ( !$(categoryItem).hasClass('mapMenuCategories_current') ){
			$(categoryItem).addEvent('click', function(e){
				clickHandlerCat(e);
			});
		}else {
			curActiveMenuButton = categoryItem;
		}
		
		var elementsContainerID = $(categoryItem).getProperty('id')+'_elements';		
		var catElements = $(elementsContainerID).getFirst().getChildren();
		
		// alle Elemente innerhalb der Kategory behandeln
		catElements.each(function(elementItem, elementIndex){
			$(elementItem).addEvent('click', function(e){
				clickHandlerElements(e);
			});
		});
	});

	/* 
	* voreingestelltes Kartenelement anzeigen
	*
	* per Übergabe kann entschieden werden, ob das Objekt initial angezeigt werden soll, oder nicht.
	* 
	*/
	//alert("Anzahl der Elemente: "+mapElements.length);
	for (var i = 0; i < mapElements.length; i++) {

		// Initiale Umrisskarte des Hainich anzeigen
		if ( mapElements[i]['titel'] == "nationalparkhainich"){
			//alert("found hainich");
			addToMap(i,0,0);
		} 
		else if ( mapElements[i]['uid'] == mapConfig[0]['elementIDToShow'] ){
			if ( mapElements[i]['hidden'] > 0) {
				addToMap(i, 0, 1);
			}
			else{	
				var fireOnElementID = mapElements[i]['id'].toString();				
				var fireOnCategoryID = mapElements[i]['category'].toString();
					
				// Klickevents auslösen
				//if (Browser.Engine.trident){ //IE
				if (Browser.ie){ //IE
					$(fireOnCategoryID).click();
					$(fireOnElementID).click();				
				}
				else { // all others
					//Kategorie aktivieren
					var evObjCategory = document.createEvent("MouseEvents");
					evObjCategory.initEvent('click', true, true);
					$(fireOnCategoryID).dispatchEvent(evObjCategory);

					// Element aktivieren	
					var evObjElement = document.createEvent("MouseEvents");
					evObjElement.initEvent('click', true, true);
					$(fireOnElementID).dispatchEvent(evObjElement);
				}
			}
		}
	}
	
}


/* Event-Handler der Kategorien
*  
*  Umschaltung der Kategoiren im Menü unterhalb der Googlemaps-Karte.
*  
*/
function clickHandlerCat(event){
	
	var curVisibleDiv;
	var inFx, outFx;
	event = new Event(event);
	var button = event.target;
	
	// Elternelement suchen, welches id besitzt
	while( !$(button).getProperty('id') )
		button = $(button).getParent();

	// Button-ID der Ereignis-Quelle speichern
	var buttonID = $(button).getProperty('id').toString();	
	// ID des zu aktivierenden Divs zusammensetzen
	var curHiddenDivID = buttonID+'_elements'; 
	//alert( "entsprechendes div-Element: "+ mapMenuElementsDivID );

	// hole ein array aller Divs, die die Listen-Elemente der Karte beinhalten
	var mapMenuElementsDiv = $('mapMenuElements').getChildren();
	//alert("mapMenuElementsDiv: "+mapMenuElementsDiv);

	// alle diese Divs durchgehen, und das aktuell sichtbare suchen
//	mapMenuElementsDiv.forEach(function(item, index){
	mapMenuElementsDiv.each(function(item, index){
		if ( item.hasClass('elements_current') ) {
			curVisibleDiv = item;			
		}
	});

	// Button-Klassen setzen
	curActiveMenuButton.removeClass('mapMenuCategories_current');

	// Ereignisbehandlungsroutine wieder zuschalten
	curActiveMenuButton.addEvent('click',function(e){clickHandlerCat(e)});

	outFx = new Fx.Tween(curVisibleDiv, { 
	    duration: '50',
		onComplete: function(){
				
			curVisibleDiv.removeClass('elements_current');
			curVisibleDiv.addClass('elements');
					
			// gewähltes div einblenden
			inFx = new Fx.Tween($(curHiddenDivID), { 
			    duration: '50',
				onComplete: function(){
					button.addClass('mapMenuCategories_current');
					button.removeEvents('click');
					$(curHiddenDivID).removeClass('elements');
					$(curHiddenDivID).addClass('elements_current');
					curActiveMenuButton = button;
				}
			});
			inFx.start('opacity','0','1');
		}
	});
	outFx.start('opacity','1','0');

}// Ende 'click'-Event-Handler der MenüKategorien

/* Event-Handler für die Menüelemente
*  
*  Event-Hanlder für die einzelnen Elemente des Kartenmenüs.
*  
*/
function clickHandlerElements(event){
	
	var removeResult = -1;
	var addResult = -1;
	var tCatDivID = "";
	
	var _event = new Event(event);

	// Quelle des Ereignisses
    var button = _event.target;
	
	// erstes Eltern-Element holen, welches eine id besitzt 
	while( !$(button).getProperty('id') )
		button = $(button).getParent();
	var buttonID = $(button).getProperty('id').toString();
	
	// sollen alle Element einer Kategorie behandelt werden, ButtonAll gedrückt
	var buttonIDALL = (buttonID.substring(buttonID.length-4, buttonID.length)=="_all") ? 1 : 0; 
	if ( buttonIDALL==1 ) {

		if ($(button).hasClass("mapMenuElements_active")) {
			$(button).removeClass("mapMenuElements_active");
			$(button).getFirst().set('text',"Alle anzeigen");
		}
		else {
			$(button).addClass("mapMenuElements_active");
			$(button).getFirst().set('text',"Alle ausblenden");
		}
		// gesamtes DIV durchgehen
		tCatDivID = buttonID.substring(0, buttonID.length-4);
		for (var i = 0; i < mapElements.length; i++) {
			if ( mapElements[i]['category']==tCatDivID ) {
				if( $(button).hasClass("mapMenuElements_active") ){						
					addToMap(i,buttonIDALL,1);
				}
				else{
					removeFromMap(i);
				}
			}
		}
	}
	else { // einzelner Button gedrückt
		//alert("mapElements.length: "+mapElements.length);
		for (var i=0; i<mapElements.length; i++) { // durchsuche alle Elemente des arrays mapElements nach dem, dessen id der ButtonID entspricht
			if (mapElements[i]['id'] == buttonID){ 
				// entferne einzelne Objekte der Kategorie von der Karte
				if (mapElements[i]['visible'] == 1) {
					//alert("removeFromMap: " + i + ", visible: " + mapElements[i]['visible']);
					removeResult = removeFromMap(i);
					while (removeResult > 0) {
						removeResult = removeFromMap(removeResult);
					}
				}						
				// füge Element der Karte hinzu
				else if (mapElements[i]['visible'] < 1) {
					addResult = addToMap(i, 0, 1);
					while (addResult > 0) {
						addResult = addToMap(addResult, 0, 1);
					}
				}
			}
		}
	}
	updateElementDivClass();

}// Ende 'click'-Event-Handler der MenüElemente


function addToMap(lMapElementIndex, showAllCategoryElements, setContainerVisible){
	
	//alert("addToMap # lMapElementIndex: "+lMapElementIndex+" showAllCategoryElements: "+showAllCategoryElements+" setContainerVisible: "+setContainerVisible);
	var encodedPolyline;
	var iconHeight = 0;
	var iconWidth = 0;
	var gmLng = "";
	var gmLat = "";
	var gmLinkString = "";
	var infoContent = "";
	var polylineColor = "#A4491d";
	
	var i=0;
	var underlinePos = "";
	var sTitleSubStr = "";
	var iArrayIndex = -1;
	var sElementCategory = "";
	var sNextElementTitel = "";
	var iNextIndexToAddToMap = -1;
	
	// doppeltes Hinzufügen vermeiden
	if (mapElements[lMapElementIndex]['visible']==1)
		return;

	// default color for polyline
	if( mapElements[lMapElementIndex]['color'] != null )
		polylineColor = "#"+mapElements[lMapElementIndex]['color'];
	
	// Google-Map icon object
	var gMapIcon = new GIcon(G_DEFAULT_ICON);
	// does icon exist
	if ( mapElements[lMapElementIndex]['icon'].toString().length > 0) {
		gMapIcon.image = html_entity_decode(mapElements[lMapElementIndex]['icon']);
		gMapIcon.shadow = "";
		iconHeight = mapElements[lMapElementIndex]['iconheight'];
		iconWidth = mapElements[lMapElementIndex]['iconwidth'];
		gMapIcon.iconSize = new GSize(iconWidth,iconHeight);
		gMapIcon.iconAnchor = new GPoint(0,0);
		gMapIcon.infoWindowAnchor = new GPoint(15,10);
	}
	
	//+++ Google-Map InfoWindow Object 
	// soll gefüllt mit Zusatzinformationen angezeigt werden
	infoContent = "<div id=\"gMapInfoWindow\">";
	infoContent += "<h3>"+mapElements[lMapElementIndex]['headline'].toString()+"</h3>";
	if(mapElements[lMapElementIndex]['image'].toString().length>0)
		infoContent += "<img width=\""+mapElements[lMapElementIndex]['imagewidth'].toString()+"px\" height=\""+mapElements[lMapElementIndex]['imageheight'].toString()+"px\" src=\""+mapElements[lMapElementIndex]['image'].toString()+"\" alttext=\""+mapElements[lMapElementIndex]['imgalttext'].toString()+"\" title=\""+mapElements[lMapElementIndex]['imgtitle'].toString()+"\" />";
	if (mapElements[lMapElementIndex]['description'].toString().length > 0) {
		//alert(mapElements[lMapElementIndex]['description']);
		infoContent += "<p class=\"gmElementDescription\">"+html_entity_decode(mapElements[lMapElementIndex]['description'])+"</p>";
	}
	if(mapElements[lMapElementIndex]['download'].toString().length>0)
		infoContent += "<p class=\"gmElementDownload\">Faltblatt <a href=\""+mapElements[lMapElementIndex]['download'].toString()+"\" target=\"_blank\">herunterladen</a></p>";
	
	// sind alternative GoogleMaps-Punkte existent?
	if( mapElements[lMapElementIndex]['alternatelongitude'] != null )
		gmLng = mapElements[lMapElementIndex]['alternatelongitude'];
	else
		gmLng = mapElements[lMapElementIndex]['lng'];
	if( mapElements[lMapElementIndex]['alternatelatitude'] != null)
		gmLat = mapElements[lMapElementIndex]['alternatelatitude'];
	else
		gmLat = mapElements[lMapElementIndex]['lat'];
			
	if( mapElements[lMapElementIndex]['pol'].toString().length>0) {

		encodedPolyline = new GPolyline.fromEncoded({
			color: polylineColor,
			weight: 3,
			opacity: 1,
			points: mapElements[lMapElementIndex]['pol'].toString(),
			levels: mapElements[lMapElementIndex]['lev'].toString(),
			zoomFactor: 4,
			numLevels: 3
		});

		gmLng = encodedPolyline.getVertex(0).lng().toString();
		gmLat = encodedPolyline.getVertex(0).lat().toString();
	}
	
	// Kartenlink anzeigen, wenn dieser nicht explizit ausgeschaltet ist.
	if( (gmLng.toString().length>0) && (mapElements[lMapElementIndex]['hideMapLink']<1) ) {
		gmLinkString = "http://maps.google.de/maps?f=d&source=s_d&saddr=&daddr="+gmLat+","+gmLng+"&hl=de&geocode=&mra=mi&mrsp=0&sz=11&sll="+gmLat+","+gmLng+"&sspn=0.290464,0.578156&ie=UTF8&ll="+gmLat+","+gmLng+"&spn=0.645961,1.234589&z=10";
		infoContent += "<p class=\"gmElementRouteLink\"><a href=\"" + gmLinkString + "\" target=\"_blank\">Anfahrtsweg berechnen</a></p>";
	}	
	
	infoContent += "</div>";
	// InfoWindow-Text an das Objekt hängen
	// alert ("infoWindowContent: "+infoContent);
	mapElements[lMapElementIndex]['infoWindowContent'] = infoContent;

	//--- Ende Google-Map InfoWindow Object 

	// Zusatzinformationen
	var bindInfoWindowHtmlOptions = { 
		noCloseOnClick : true,
		pixelOffset : new GSize(0,0),
		maxWidth : 	300
	};
	
	
	// does element contain POLYLINE information?	
	if( mapElements[lMapElementIndex]['pol'].toString().length > 0 ){

		//alert("Element with number: "+lMapElementIndex+" is a polyline !");
		
		if ( mapElements[lMapElementIndex]['titel'] == "nationalparkhainich") {
			var encodedPolygon = new GPolygon.fromEncoded({
				polylines: [
					{
						color: polylineColor,
						weight: 3,
						opacity: 0.75,
						points: mapElements[lMapElementIndex]['pol'].toString(),
						levels: mapElements[lMapElementIndex]['lev'].toString(),
						zoomFactor: 4,
						numLevels: 3
					}
				],
				fill: true,
				color: polylineColor,
				opacity: 0.15,
				outline: true
			});
			map.addOverlay(encodedPolygon);
		}
		else {
			// add polyline to map
			map.addOverlay(encodedPolyline);
			// add customized Icon to map at starting point of polyline
			var polylineMarkerStartPoint = encodedPolyline.getVertex(Math.round(encodedPolyline.getVertexCount()/10*8));
			var polylineMarkerOptions = { icon:gMapIcon };
			var polylineMarker = new GMarker(polylineMarkerStartPoint, polylineMarkerOptions);
			polylineMarker.bindInfoWindowHtml(infoContent, bindInfoWindowHtmlOptions);
			// save overlay information
			mapElements[lMapElementIndex]['polyline']=encodedPolyline;
			mapElements[lMapElementIndex]['marker']=polylineMarker;
			if (setContainerVisible == 1) {
				mapElements[lMapElementIndex]['visible'] = 1;
				map.addOverlay(polylineMarker);
			}
			
			// map recenter, if element is outside the mapscreen
			while ( (!map.getBounds().containsBounds(encodedPolyline.getBounds())) & (showAllCategoryElements==0) ) {
				var newCenterPointLng = (map.getBounds().getCenter().lng()+encodedPolyline.getBounds().getCenter().lng() )/2;
				var newCenterPointLat = (map.getBounds().getCenter().lat()+encodedPolyline.getBounds().getCenter().lat() )/2;
				map.panTo(new GLatLng(newCenterPointLat,newCenterPointLng));
				map.setCenter(new GLatLng(newCenterPointLat, newCenterPointLng));
				if (!map.getBounds().containsBounds(encodedPolyline.getBounds())){
					map.zoomOut();
				}
			}
		}
	}
	// does element contain point information
	else if( mapElements[lMapElementIndex]['lng'].toString().length > 0 ){
		
		//alert("Element with number: "+lMapElementIndex+" is a point !");

        var point = new GLatLng(mapElements[lMapElementIndex]['lat'].toFloat(),mapElements[lMapElementIndex]['lng'].toFloat());
        
		var markerOptions = { 
			icon: gMapIcon
		 };
		var marker = new GMarker(point,markerOptions);
		marker.bindInfoWindowHtml(infoContent,bindInfoWindowHtmlOptions);
		mapElements[lMapElementIndex]['polyline'] = "";
		mapElements[lMapElementIndex]['marker'] = marker;
		if (setContainerVisible == 1) {
			mapElements[lMapElementIndex]['visible'] = 1;
			map.addOverlay(marker);
		}
		// map recenter, if element is outside the mapscreen
		while ((!map.getBounds().containsLatLng(marker.getLatLng())) & (showAllCategoryElements == 0)) {
			var newCenterPointLng = (map.getBounds().getCenter().lng() + marker.getLatLng().lng()) / 2;
			var newCenterPointLat = (map.getBounds().getCenter().lat() + marker.getLatLng().lat()) / 2;
			map.panTo(new GLatLng(newCenterPointLat, newCenterPointLng));
			map.setCenter(new GLatLng(newCenterPointLat, newCenterPointLng));
			if (!map.getBounds().containsLatLng(marker.getLatLng())){
				map.zoomOut();
			}
		}
		// sofortiges Anzeigen des InfoWindow auslösen
//		if( ( mapElements[lMapElementIndex]['uid'] == mapConfig[0]['elementIDToShow'] ) && (mapElements[lMapElementIndex]['hidden'] > 0) ){
		if( mapElements[lMapElementIndex]['uid'] == mapConfig[0]['elementIDToShow'] ){
			marker.openInfoWindowHtml(infoContent,bindInfoWindowHtmlOptions);
		}

	}
	else{
		alert("Element does not contain any Google-Map information!");
	}
	
	
	// solle ein weiteres Element existieren, dessen Kategorie dieselbe, wie die des gerade angezeigten Elementes ist, 
	// und dessen Titel sich aus dem aktuellen Titel+1 zusammensetzt, dann rufe addToMap ein weiteres mal auf.
	underlinePos = mapElements[lMapElementIndex]['titel'].indexOf("_");
	if (underlinePos > -1) {// underline gefunden
		// extrahiere den Index-String
		sTitleSubStr = mapElements[lMapElementIndex]['titel'].substr(underlinePos+1,mapElements[lMapElementIndex]['titel'].length);
		//alert("sTitleSubStr: +"+sTitleSubStr+"#");	
		// konvertiere diesen in eine integer-Zahl
		iArrayIndex = parseInt(sTitleSubStr,10);
		//alert("iArrayIndex: #"+iArrayIndex+"#");
		// hole die Kategorie des aktuellen Elementes
		sElementCategory = mapElements[lMapElementIndex]['category'];
		// setze nächsten gesuchten Titel zusammen
		sNextElementTitel = mapElements[lMapElementIndex]['titel'].substr(0,underlinePos+1);
		iArrayIndex = iArrayIndex+1;
		//alert("next iArrayIndex: #"+iArrayIndex+"#");
		if (iArrayIndex < 10) {
			sNextElementTitel = sNextElementTitel + "0";
		}
		sNextElementTitel = sNextElementTitel + (iArrayIndex).toString();
		//alert("sNextElementTitel:"+sNextElementTitel);
		
		// durchsuche alle anderen Elemente nach dem neuen Element-Titel
		for (i=0; i < mapElements.length; i++) {
			// hat das Element die gesuchte Kategorie
			if( (mapElements[i]['category'] == sElementCategory) && (mapElements[i]['titel'] == sNextElementTitel) && (mapElements[i]['visible'] < 1) )
					iNextIndexToAddToMap = i;	
		}
	}
	
	return iNextIndexToAddToMap;		
	
}

/*
 * function removeFromMap()
 * 
 * Removes the Element with given Element-ID from the GoogleMap
 */
function removeFromMap(lMapElementIndex){
	
	var i=0;
	var underlinePos = "";
	var sTitleSubStr = "";
	var iArrayIndex = -1;
	var sElementCategory = "";
	var sNextElementTitel = "";
	var iNextIndexToRemoveFromMap = -1;	
	
	if( mapElements[lMapElementIndex]['polyline'] != 0 ){
		map.removeOverlay(mapElements[lMapElementIndex]['polyline']);
	}
	if( mapElements[lMapElementIndex]['marker'] != 0 ){
		map.removeOverlay(mapElements[lMapElementIndex]['marker']);
	}
	mapElements[lMapElementIndex]['visible']=0;
	
	// existiert ein weiteres Element, dessen Kategorie dieselbe, wie die des gerade angezeigten Elementes ist, 
	// und dessen Titel sich aus dem aktuellen Titel+1 zusammensetzt
	underlinePos = mapElements[lMapElementIndex]['titel'].indexOf("_");
	if (underlinePos > -1) {// underline gefunden
		// extrahiere den Index-String
		sTitleSubStr = mapElements[lMapElementIndex]['titel'].substr(underlinePos+1,mapElements[lMapElementIndex]['titel'].length);
		// konvertiere diesen in eine integer-Zahl
		iArrayIndex = parseInt(sTitleSubStr,10);
		// hole die Kategorie des aktuellen Elementes
		sElementCategory = mapElements[lMapElementIndex]['category'];
		//alert("sElementCategory: "+sElementCategory);
		// setze nächsten gesuchten Titel zusammen
		sNextElementTitel = mapElements[lMapElementIndex]['titel'].substr(0,underlinePos+1);
		//alert("sNextElementTitel: "+sNextElementTitel);
		if(iArrayIndex<9)
			sNextElementTitel = sNextElementTitel + "0";
		sNextElementTitel = sNextElementTitel + (iArrayIndex+1).toString();
		//alert("sNextElementTitel: "+sNextElementTitel);
		
		// durchsuche alle anderen elemente nach dem neuen Element-Titel
		for (i = iArrayIndex; i < mapElements.length; i++) {
			// hat das Element die gesuchte Kategorie
			if ( (mapElements[i]['category'] == sElementCategory) && (mapElements[i]['titel'] == sNextElementTitel) && (mapElements[i]['visible'] == 1))
				iNextIndexToRemoveFromMap = i;
		}
	}
	//alert("###iNextIndexToRemoveFromMap:###"+iNextIndexToRemoveFromMap);
	return iNextIndexToRemoveFromMap;		

}

/*
 * function updateElementDivClass()
 * 
 * Funktion zum Update der Elemente-Container (li-Elemente).
 * In Abhängigkeit des Parameters "visible" werden dis css-Klassen ausgetauscht
 * 
 */
function updateElementDivClass(){
	
	for (var i=0; i<mapElements.length; i++) {
		if (!$(mapElements[i]['id'])) {
			//alert("DOM Object not exists!: "+mapElements[i]['id']);
			continue;
		}
		if (mapElements[i]['visible'] == 1) {
			$(mapElements[i]['id']).addClass("mapMenuElements_active");
		}
		else {
			$(mapElements[i]['id']).removeClass("mapMenuElements_active");
		}
	}
}



