// ==================================================================
// Global variables
// ==================================================================

// traffic situation map
var trafficTiles;
var trafficHost;
// ics messages
var icsEventsArr = new Array();
// visibility of highway layer
var showHighwayLayer = true; 
// autoupdate
var autoupdate = null;
// inizialisation state of weather icons
var weatherIconsInit = false;
// zoom level of weather icons
var weatherIconsZL = -1;


// ==================================================================
// Map configuartion
// ==================================================================

// map configuration
function initMdvMapConfig() {
	mdvMapConfig.add('serverURL', absoluteServerPath.mapTiles + mapTilesTraffic);
	mdvMapConfig.add('efaURL', absoluteServerPath.efa + 'XML_MAP_REQUEST');
	mdvMapConfig.add('transparentImg', imgPath + 'transparent.gif');
	mdvMapConfig.add('imagePath', imgPath);
	mdvMapConfig.add('network', 'aut');
	mdvMapConfig.add('trips.useJsonForPath', 'true');
	mdvMapConfig.add('defaultScale', '1');
	mdvMapConfig.add('xCenterReal', mapCenterX);
	mdvMapConfig.add('yCenterReal', mapCenterY);
	mdvMapConfig.add('mapName', nameMap);
	mdvMapConfig.add('block', '100');
	mdvMapConfig.add('language', mapLanguage);
	mdvMapConfig.add('zoomOnDoubleClick', 'true');
	mdvMapConfig.add('hotspotOnMouseWheel', 'true');
	mdvMapConfig.add('cursorMove', imgPath + 'grabbing.cur');
	mdvMapConfig.add('useMagnifyGlass', 'true');
	mdvMapConfig.add('useBubbleOverflowForEFAInfo', 'true');
	trafficTiles = trafficTilesTraffic;
	trafficHost = trafficHostTraffic; 
};


// ==================================================================
// Common map functionality
// ==================================================================

// This function loads the map
function MDVMapHelper() {
	this.mdvMap = null;
	this.marker = null;
	this.roadworksLayer = null;
	this.blockingsLayer = null;
	this.informationLayer = null;
	this.events = null;

	if (this.mdvMap == null) {
		this.mdvMap = new MDVMap(document.getElementById('mdvMap'));
		new MDVMapNavigator(this.mdvMap);
		this.createMapControl();
		this.createZoomRectangle();

		//this.mdvMap.events.registerEvent(MDVEvent_MAP_INITIALISED, this, this.onNewCentre);
		this.mdvMap.events.registerEvent(MDVEvent_OBJECT_DBLCLICKED, this, function () {return true;});
		this.mdvMap.events.registerEvent(MDVEvent_OBJECT_CLICKED, this, this.highlightICSMessage);
		this.mdvMap.events.registerEvent(MDVEvent_TOOLTIP, this, this.onToolTip);
		if (enableWeather == 'true') {
			this.mdvMap.events.registerEvent(MDVEvent_ZOOM_CHANGED , this, reloadWeatherIcons);
		}
		
		// layer for  ics messages. each type of message has its own layer
		this.roadWorksLayer = this.mdvMap.createLayer('roadWorks'); 
		this.roadWorksLayer.setZIndex('32');
		this.mdvMap.addLayer(this.roadWorksLayer);
		this.blockingsLayer = this.mdvMap.createLayer('blockings'); 
		this.blockingsLayer.setZIndex('33');
		this.mdvMap.addLayer(this.blockingsLayer);
		this.informationLayer = this.mdvMap.createLayer('information'); 
		this.informationLayer.setZIndex('31');
		this.mdvMap.addLayer(this.informationLayer);
	}

	if (this.mdvMap) {
		var mdvMapTarget = document.getElementById('mdvMap');
		if (mdvMapTarget) {
			// Traffic Situation Overlay
			this.mdvMap.addOverlay(this.mdvMap.createOverlay('TrafficSituation', trafficTiles, TrafficSituationOverlay, null, overlaySorter));
			// highway overlay
			if (enableHighwayMap == 'true' && highwayMap != '') {
				this.mdvMap.addOverlay(this.mdvMap.createOverlay('Highway', highwayMap, wmsOverlay));
            }
			// VIONA overlay
			if (enableVionaMap == 'true' && vionaMap != '') {
				this.mdvMap.addOverlay(this.mdvMap.createOverlay('VIONA', vionaMap, wmsOverlay));  
            }
			// create map overlays
			createMapOverlays(this.mdvMap);
			this.mdvMap.execute(mdvMapConfig);	
		}
	}
	
	// layer for weather map
	if (enableWeather == 'true')  {
		this.weatherLayer = null;
		this.weatherLayer = this.mdvMap.createLayer('weather'); 
		this.weatherLayer.setZIndex('25');
		this.mdvMap.addLayer(this.weatherLayer);
		this.weatherLayer.setVisibility(false);
	}
	
	// display external markers
	if(enableTrafficSituationMarkers == 'true') {
		this.displayExternalMarkers(trafficSituationMapMarkers);
	}

	// map does not move if it is grapped and the mouse moved over the borders of the map
	attachEventListener(document, 'mouseover', this.mdvMap.release.bind(this.mdvMap), false);
}

 
// ==================================================================
// Update Functionality
// ==================================================================

// Update the validity selection box and the traffic situation on load or if updated manually or automatically
function updateValidity() {
	var _host = trafficHost;  
	var _date = new Date().getTime();
	var _params = { ts: _date, mapType: 'IT' };
	var _ajax = mdvLib.ajax({host: _host, method: 'get', parameters: _params, onComplete: updateValidityComplete}); 
}


// This function creates the selection of prediction interval.
function updateValidityComplete (result) {
	var _response = result.responseText || response;
	eval('var validity = ' + _response + ';');
	var div = document.getElementById('validity');
	var div2 = document.getElementById('validityClocks');
	showHighwayLayer = true;
	
	// determine index of current interval
	var activeElem = 0;
	// empty array with active intervals
	validityIntervals.length = 0;
	// determine active interval
	for (var i=0; i < validity.activeIntervals.length; i++) {
		if (validity.defaultInterval && validity.defaultInterval.displayText == validity.activeIntervals[i].displayText) {
			activeElem = i;
			break;
		}	
	}
    currentInterval = currentInterval;
	// validity clocks design
	if (div2) {
		document.getElementById('validityClocks').style.display = 'block';
		document.getElementById('noPrediction').style.display = 'none';
		document.getElementById('predictionSummary').style.display = 'none';
		
		var lastElem = 0;
		if (validity.defaultInterval) { 
			// determine last displayed interval (maximum: 4)
			if (validity && validity.activeIntervals.length && activeElem + 4 < validity.activeIntervals.length)
				lastElem = activeElem + 4;
			else 
				lastElem = validity.activeIntervals.length;
				
			// create interval array
			for (var i=activeElem; i < lastElem; i++) {
				// create interval array
				validityIntervals.push ({start: validity.activeIntervals[i].timeInterval['timeStart'], end: validity.activeIntervals[i].timeInterval['timeEnd'], active: activeInterval, referenceTime: validity.activeIntervals[i].referenceTime});
			}	
			// modify dispay
			for (var i=0; i < validityIntervals.length; i++) {
				var j = i + 1;
				// display clocks and set summary
				document.getElementById('clocks' + j).style.display = 'block';
				if (i==0) {
					document.getElementById('clock' + j + '_active').style.display = 'block';
					document.getElementById('clock' + j).style.display = 'none';
					// set summary
					document.getElementById('predictionSummary').style.display = 'block';
					document.getElementById('predictionSummaryContent').innerHTML = getWeekdayDateTimeInterval (validityIntervals[i].start, validityIntervals[i].end);
				}
				else {
					document.getElementById('clock' + j + '_active').style.display = 'none';
					document.getElementById('clock' + j).style.display = 'block';
				}
				document.getElementById('clock' + j + '_unavailable').style.display = 'none';
			}
		}
		// show clocks for unavailable intervals
		for (var i= validityIntervals.length + 1; i < 5; i++) {
			document.getElementById('clock' + i + '_active').style.display = 'none';
			document.getElementById('clock' + i).style.display = 'none';
			document.getElementById('clock' + i + '_unavailable').style.display = 'block';
		}
		// error message if no prediction available 
		if (validityIntervals.length == 0) 
			document.getElementById('noPrediction').style.display = 'block';
	}
	// validity pulldown design
	else if (div && validity && validity.activeIntervals.length > 0 && validity.defaultInterval) {	
		var text = '<select name="validity" id="validityPeriod" onchange="updateICSMessages();toggleHighwaySituation(null);">'; 
		for (var i=0; i < validity.activeIntervals.length; i++) {
			var activeInterval = false;
			if (i == activeElem)
				activeInterval = true;
			// create interval array
			validityIntervals.push ({start: validity.activeIntervals[i].timeInterval['timeStart'], end: validity.activeIntervals[i].timeInterval['timeEnd'], active: activeInterval, referenceTime: validity.activeIntervals[i].referenceTime});
			text += '<option value="' + validityIntervals[i].referenceTime + '" ';
			if (activeInterval)
				text += 'selected="selected" ';
			text += '>';
			text += validity.activeIntervals[i].displayText;
			text += '</option>';
		}
		text += '</select>';
		div.innerHTML = text;
	}
	// no validity
	else if (div) {
		div.innerHTML = '<div class="validityText">' + noValidity + '</div>';
	}
		
	// update ics messages
	updateICSMessages();
	
	// update weather icons
	if (enableWeather == 'true') {
		reloadWeatherIcons (true);
	}
}


// This function toggles the traffic situation auto update 
function toggleAutoUpdate(state) {
	// enable auto-update
	if (state) {
		document.getElementById('updateButton').style.display = 'none';
		updateValidity();
		autoupdate = window.setInterval('updateValidity()', updateFrequencyTraffic);
	}
	// disable auto-update
	else if (autoupdate) {
		document.getElementById('updateButton').style.display = 'block';
		window.clearInterval(autoupdate);
	}
}


// ==================================================================
// Display ICS Messages in the list and on the map.
// ==================================================================

// This function toggles the ICS message symbol layers on the map.
MDVMapHelper.prototype.toggleLayer = function (dom) {
    if (!dom) {
        return;
    }
    
    var name = dom.getAttribute('name').split('_');
	
    if (name[2]) {
		if (name[2] == 'blockings') {
			this.blockingsLayer.setVisibility(dom.checked);
        }
		else if (name[2] == 'roadWorks') {
			this.roadWorksLayer.setVisibility(dom.checked);
        }
        else if (name[2] == 'externalMarkers'){
			this.externalMarkersLayer.setVisibility(dom.checked);
            this.mdvMap.update();
        }
		else {
			this.informationLayer.setVisibility(dom.checked);
        }
    }
	// close open tooltips
	closeTooltips (name[2]);
}


// This function closes open tooltips of message symbols on closed layers.
function closeTooltips (type) {
	// close tooltips on the map
	var layer;
	if (type == 'blocking')
		layer = mdvMap.mdvMap.getLayer('blockings');	
	else if (type == 'roadWorks')
		layer = mdvMap.mdvMap.getLayer('roadWorks');	
	else 
		layer = mdvMap.mdvMap.getLayer('information');	
	if (layer) {
		var markers = layer.getMarkers();
		for (var m = 0; m < markers.length; m++) {
			markers[m].toolTip.setFixed(false);
			markers[m].toolTip.hide();
		}
	}
}


// This function updates the ICS message symbols on the map and the message list.
function updateICSMessages() {
	if (icsITMessages == 'true') {
		var _url = absoluteServerPath.virtDir + 'XSLT_TRIP_REQUEST2?currentPage=trafficSituation&language=' + mapLanguage + '&itdLPxx_updateItICS=true';
		var _ajax = mdvLib.ajax({ host: _url, method: 'get', parameters: {}, onComplete: updateICSMessagesComplete });
	}
}

// Display the ICS messages list
function updateICSMessagesComplete (result) {
	var div = document.getElementById('updateICSMessages');
	if (div) {	
		var countEvents = 0;
		if (icsEventsArr.length > 0) {
			// display messages
			if (result.responseText != '')
				div.innerHTML = result.responseText;
			// hide messages which are not within the current validity period
			for (var  i=0; i < icsEventsArr.length; i++) {
				var validMsg = checkICSMsgValidity(icsEventsArr[i]);
				hideInvalidICSMessage(icsEventsArr[i][0].id, validMsg);
				if (validMsg)
					countEvents += 1; 
			}
			// toggle visible/invisible message types
			toggleAllTrafficInfos();
		}
		// no messages available 
		if (countEvents == 0) 
			div.innerHTML = noMessage;
		// update icons on map
		mdvMap.displayITEvents();
	}
}


// ==================================================================
// Highway map
// ==================================================================

// This function displays/hides the highway traffic situation wms and the viona wms
function toggleHighwaySituation (state) {
	// workaround for selectbox (IE cannot handle events for options)
	if (state == null) {
		if (enableHighwayMap == 'true' && validityIntervals[document.getElementById('validityPeriod').selectedIndex].active) {
			showHighwayLayer = true;
		}
		else {
			showHighwayLayer = false;
		}
	}
	else {
		showHighwayLayer = state;
	}
}


// ==================================================================
// Weather map
// ==================================================================

// Toggle weather layer.
// Parameter:	state[true|false] - display/hide layer
function toggleWeatherLayer (state) {
	// load weather icons if not loaded already
	if(state && !weatherIconsInit) {
		var weather = new MDVEFAWeather(absoluteServerPath.efa + weatherPath);
		weather.getWeatherIcons();
		weatherIconsInit = true;
	}
	mdvMap.weatherLayer.setVisibility(state);
}


// Reload weather icons, e.g. on zoom level change or on update.
// Parameter: 	bool [true|false] - optional parameter to enforce reload 
function reloadWeatherIcons (bool) {
	// test if weather layer is visible and if currently loaded weather icons do not match the current zoom level or if
	// a reload was enforced
	if (mdvMap && mdvMap.weatherLayer.visible && (weatherIconsZL != mdvMap.mdvMap.config.getZoomLevelIndex() || bool == true)) {
		var weather = new MDVEFAWeather(absoluteServerPath.efa + weatherPath);
		mdvMap.weatherLayer.removeAllMarkers();
		weather.getWeatherIcons();
	}	
	// if the enforced update did not take place because the layer was invisible, update the icons as soon as the layer 
	// is enabled 
	if (mdvMap && !mdvMap.weatherLayer.visible && bool == true) {
		weatherIconsInit = false;
	}
	return true;
}


function MDVEFAWeather(url) {
    this.url = null;
    
    var zoomlevel = mdvMap.mdvMap.config.getZoomLevelIndex();
    
    // no icons for detail map available
    if (zoomlevel < 3) {
        this.url 		= url + 'weatherIcons' + zoomlevel + '.js';
    }
}


// Request weather icons with AJAX request
MDVEFAWeather.prototype.getWeatherIcons = function(identifier) {
    if (this.url) {
        var _date = new Date().getTime();
        var _params = { ts: _date};
        var ajax = mdvLib.ajax({ host: this.url, parameters: _params, method: 'get', onComplete: MDVEFAWeather_onAjaxComplete });
    }
}


// Display weather icons
function MDVEFAWeather_onAjaxComplete(response) {
	var json;
	var _response = response.responseText || response;
	eval('json=' + _response + ';');
	var size = new MDVPoint(300, 70);
    
	// create weather icons
    for (var j=0; j < json.length; j++ ) {
        if ((json[j].interval.start.toLocaleString() == validityIntervals[currentInterval].start.toLocaleString() 
            && json[j].interval.end.toLocaleString() == validityIntervals[currentInterval].end.toLocaleString())
            || (json[j].interval.start.toLocaleString() < validityIntervals[currentInterval].start.toLocaleString() 
            && json[j].interval.end.toLocaleString() > validityIntervals[currentInterval].start.toLocaleString())) {
            for (var i=0; i < json[j].symbols.length; i++) {
                var coord = new MDVCoordinates(nameMap, parseInt(json[j].symbols[i].coordx), parseInt(json[j].symbols[i].coordy));
                var marker =  mdvMap.mdvMap.createMarker(coord, 0.5, getWeatherIcon(json[j].symbols[i].type, json[j].symbols[i].id));
                var toolTitle = json[j].symbols[i].tt.de;
                if (mapLanguage != 'de') {
                    toolTitle = json[j].symbols[i].tt.en;
                }
                var tool = mdvMap.mdvMap.createToolTip(size,'<b>' + toolTitle + '</b>');
                tool.content = '';
                tool.temperature = json[j].symbols[i].temperature;
                tool.wind = json[j].symbols[i].wind;
                tool.fallout = json[j].symbols[i].fallout;
                marker.setToolTip(tool);
                marker.toolTip.setPin(true);
                mdvMap.weatherLayer.addMarker(marker);
            }
        }
    
    }
	mdvMap.mdvMap.update();
	weatherIconsZL = mdvMap.mdvMap.config.getZoomLevelIndex();
}


// Gets the weather icon. 
// Parameter:	imageType [day|night] - day icon or night icon
// 				imageId - ID of icon
function getWeatherIcon(imageType, imageId) {
	return imgPath + "weather/" + imageType + "/"+ imageId + '.png';
}


// ==================================================================
// Tooltips
// ==================================================================

// Tooltip.
function MDVToolTipHelper(toolTip) {
	this.toolTip = toolTip;
	this.processed = false;
}


// This function creates the tooltip bubble.
MDVToolTipHelper.prototype.execute = function(tooltip) {
	if (!this.processed) {
        // weather
        if (tooltip.temperature) {
            var id = tooltip.getParent().id;
            var body = '<div id="weather_' + id + '">';
			body += this.toolTip.getInnerHTML();
			body += '<br/><br/><table>';
            body += '<tr><td>' + weatherTemperature + '</td><td>' + tooltip.temperature + '</td></tr>';
            body += '<tr><td>' + weatherWind + '</td><td>' + tooltip.wind + '</td></tr>';
            //body += '<tr><td>Niederschlag: </td><td>' + tooltip.fallout + '</td></tr>';
            body += '</table></div>';
            this.toolTip.setInnerHTML(body);
        }
        // ICS message
        else {
            createICSBubble ('IT', tooltip);
        }
		this.processed = true;
	}
    // modify bubble size
    if (tooltip.temperature) { 
        var size = new MDVPoint(300, 130);
        this.toolTip.container.setSize(size);
        this.toolTip.container.updateBubble();
    }
}





