// the map
var mdvJpMaps = new Array();
var mapType = null;
// coordinates of the right mouse click
var ctxCoords = null;
// tooltips array
var toolTipHelpers = new Array();
// usages
var usages = new Array('origin', 'destination', 'via', 'sf', 'dm');
// display/hide poi categories
var displayPOICat = true;
var mapsPhase2 = true;

// map configuration
function initMdvMapConfig(usage) {
	// input map configuration
	mdvMapConfig.add('serverURL', mapTiles); 
	mdvMapConfig.add('efaURL', '/lite2/XSLT_COORD_REQUEST');
	mdvMapConfig.add('transparentImg', 'images/map/transparent.gif');
	mdvMapConfig.add('imagePath', 'images/map/');
	mdvMapConfig.add('network', network);
	mdvMapConfig.add('defaultScale', defaultScale);	
	mdvMapConfig.add('xCenterReal', mapCenterX);
	mdvMapConfig.add('yCenterReal', mapCenterY);
	mdvMapConfig.add('mapName', nameMap);
	mdvMapConfig.add('block', '100');
	mdvMapConfig.add('toolTimeOut', '20');
	mdvMapConfig.add('zoomOnDoubleClick', 'true');
	mdvMapConfig.add('useBubblePinForEFAInfo', 'true');
	mdvMapConfig.add('useBubbleOverflowForEFAInfo', 'true');
	if(usage=='dm'){
		mdvMapConfig.add('useBubbleForEFAInfo', 'true');
		mdvMapConfig.add('useBubbleForEFAInfoPOI', 'false');
		mdvMapConfig.add('info.stop.size.width', '280');
		mdvMapConfig.add('info.stop.size.height', '200');
	}
	else{ 
		mdvMapConfig.add('info.stop.size.width', '200');
		mdvMapConfig.add('info.stop.size.height', '150');
	}
	if(mapType!='mdvROPMap'){
		mdvMapConfig.add('omitMouseWheel', 'true');
	}
	mdvMapConfig.add('language', mapLanguage);
	mdvMapConfig.add('useMagnifyGlass', 'true');
	mdvMapConfig.add('hotspotOnMouseWheel', 'true');
	mdvMapConfig.add('cursorMove', 'images/map/grabbing.cur');
	mdvMapConfig.add('info.poi.size.width', '200');
	mdvMapConfig.add('info.poi.size.height', '100');
	if(mapsPhase2== false){
		mdvMapConfig.add('info.stop.only', 'true');
	}
	mdvMapConfig.add('trips.useJsonForPath', 'true');
	
	// output map configuration
	mdvMapConfig.add('tripURL', '/lite2/XSLT_TRIP_REQUEST2');
	mdvMapConfig.add('trips.marker.size.height', '90');
	mdvMapConfig.add('trips.marker.size.width', '200');
	mdvMapConfig.add('trips.polyline.size.height', '65');
	mdvMapConfig.add('trips.polyline.size.width', '200');
	mdvMapConfig.add('trips.polyline.opacity', '0.4');
	mdvMapConfig.add('trips.polyline.weight', '4');
	mdvMapConfig.add('motColour_0', '#0000FF'); 	
	mdvMapConfig.add('motColour_1', '#FF0000');		
	mdvMapConfig.add('motColour_2', '#00797A');		
	mdvMapConfig.add('motColour_3', '#FF0000');		
	mdvMapConfig.add('motColour_4', '#7AA6FF');		
	mdvMapConfig.add('motColour_5', '#0000FF');		
	mdvMapConfig.add('motColour_6', '#0000FF');		
	mdvMapConfig.add('motColour_7', '#0000FF');		
	mdvMapConfig.add('motColour_8', '#0000FF');		
	mdvMapConfig.add('motColour_9', '#0000FF');		
	mdvMapConfig.add('motColour_10', '#0000FF');	
	mdvMapConfig.add('motColour_11', '#0000FF');	
	mdvMapConfig.add('motColour_12', '#0000FF');	
	mdvMapConfig.add('motColour_99', '#009B00');	
	mdvMapConfig.add('motColour_100', '#009B00');	
	mdvMapConfig.add('motColour_101', '#0000FF');	
	mdvMapConfig.add('motColour_102', '#0000FF');	
	mdvMapConfig.add('motColour_103', '#0000FF');	
	mdvMapConfig.add('motColour_104', '#0000FF');	
	mdvMapConfig.add('motColour_105', '#0000FF');	
	mdvMapConfig.add('motColour_106', '#0000FF');	
	mdvMapConfig.add('motColour_107', '#000000');	
	mdvMapConfig.add('motColour_108', '#0000FF');
	
	// mini map configuration
	mdvMapConfigMini.add('serverURL', miniMapTiles);
	mdvMapConfigMini.add('efaURL', '/lite/XSLT_COORD_REQUEST');
	mdvMapConfigMini.add('transparentImg', 'images/map/transparent.gif');
	mdvMapConfigMini.add('network', network);
	mdvMapConfigMini.add('defaultScale', defaultScale);	
	mdvMapConfigMini.add('xCenterReal', mapCenterX);
	mdvMapConfigMini.add('yCenterReal', mapCenterY);
	mdvMapConfigMini.add('mapName', nameMap);
	mdvMapConfigMini.add('block', '100');
	mdvMapConfigMini.add('toolTimeOut', '20');
	mdvMapConfigMini.add('zoomOnDoubleClick', 'true');	
	mdvMapConfigMini.add('hotspotOnMouseWheel', 'true');
	mdvMapConfigMini.add('cursorMove', 'images/map/grabbing.cur');
	
	// coordinate reduction
	reductionList = [
		{ maxScale:   2500, epsilon:   3.0 },
		{ maxScale:   5200, epsilon:   5.5 },
		{ maxScale:  11000, epsilon:   6.5 },          
		{ maxScale:  23000, epsilon:   8.0 },
		{ maxScale:  50000, epsilon:  10.0 },
		{ maxScale: 100000, epsilon:  20.0 },
		{ maxScale: 210000, epsilon: 100.0 }
	];
}

// ==================================================================
// Common map functionality
// ==================================================================
// This function loads and initializes the map when the site is loaded.
function onLoadMapHandler_v2(type, usage, routeIndex) {

	mapType = type;
	// load map configuration
	initMdvMapConfig(usage);
	
	if(mdvJpMaps[type] != null && type.indexOf('mdvOutputMap')!='-1'){
		onUnloadMapHandler('mdvOutputMap', mdvJpMaps[type].mdvMap.name.substring(9));
	}
	
	if(type == 'mdvInputMap' && document.getElementById('mdvInputMap').style.display=='none'){
		document.getElementById('mdvInputMap').style.display='';
	}
	else if(routeIndex > 0 && type == 'mdvOutputMap' && document.getElementById('mdvOutputMap_' + routeIndex).style.display=='none'){
		document.getElementById('mdvOutputMap_' + routeIndex).style.display='';
	}
	else if(type == 'mdvOutputMap' && document.getElementById('mdvOutputMap') && document.getElementById('mdvOutputMap').style.display=='none'){
		document.getElementById('mdvOutputMap').style.display='';
	}

	//initialize map 
	if (mdvJpMaps[type] == null){
		mdvJpMaps[type] = new MDVMapHelper(usage, routeIndex, type);
	}
};

// This function unloads the map when the site is unloaded.
function onUnloadMapHandler(type, id) {

	if (mdvJpMaps[mapType])
		mdvJpMaps[mapType].destroy();
	
	if(document.getElementById('mdvInputMap'))
		document.getElementById('mdvInputMap').style.display='none';
		
	if(document.getElementById('mdvOutputMap'))
		document.getElementById('mdvOutputMap').style.display='none';
		
	if(document.getElementById('mdvOutputMap_' +id))
		document.getElementById('mdvOutputMap_' +id).style.display='none';
		
};

// This function destroys the map and mini map and clears the cache.
MDVMapHelper.prototype.destroy = function() {

	if(document.getDivsByClassName('MDVMapControl')[0])
		document.removeElement(document.getDivsByClassName('MDVMapControl')[0]);
	
	if(document.getElementById('mdvMap_mdvMap_mapper0_mapTiles'))
		document.removeElement(document.getElementById('mdvMap_mdvMap_mapper0_mapTiles'));
		
	if(document.getElementById('mdvMap_mdvMarkers'))
		document.removeElement(document.getElementById('mdvMap_mdvMarkers'));
		
	if(document.getElementById('mdvMap_mapper0'))
		document.removeElement(document.getElementById('mdvMap_mapper0'));
		
	if(document.getElementById('mdvMap_mapper1'))
		document.removeElement(document.getElementById('mdvMap_mapper1'));

	mdvJpMaps[mapType].mdvMap.destroy();
	mdvJpMaps[mapType].mdvMap = null;
	mdvJpMaps[mapType].mdvMiniMap.destroy();
	mdvJpMaps[mapType].mdvMiniMap = null;
	mdvJpMaps[mapType] = null;
	
};

// This function loads the map and minimap
function MDVMapHelper(usage, routeIndex, type) {
	this.mdvMap = null;
	this.mdvMiniMap = null;
	this.markerLayer = null;
	this.usage = usage;
	this.marker = null;
	this.type = type;
	this.journeyOverview = false;
	this.mdvMapTripsLoaded = false;
	this.smslookup = false;
	
	if(document.getElementById('itdLPxx_link') && document.getElementById('itdLPxx_link').value=='smslookup'){
		this.smslookup = true;
	}

	this.infoEx = null;
	this.infoExCallback = {
		id : '',
		gadName : '',
		request : null
	};
	// poi categories
	this.curCategories = {
		accommodation: false,
		attractions: false,
		sport: false,
		education: false,
		infrastructure: false,
		health: false,
		eat: false,
		shopping: false	
	};
	
	// output map functionality
	if (this.type=='mdvOutputMap') {
		this.routeIndex = routeIndex;
		this.viewport = document.getElementById('mdvJpMap_' + routeIndex);
		this.trips = null;
	}

	// initialize map and register events
	if (this.mdvMap == null) {
	
		if(this.type=='mdvOutputMap'){
			this.mdvMap = new MDVMap(document.getElementById('mdvJpMap_' + routeIndex));
		}
		else{
			this.mdvMap = new MDVMap(document.getElementById('mdvMap'));
		}
		
		// store result of infoEx to display and hide POIs
		if (this.type!='mdvROPMap') {

			this.infoEx = new MDVMapEFAInfoEx(this.mdvMap, pinComparator, null, getBusPointImg);
			this.mdvMap.events.registerEvent(MDVEvent_AJAX_CALLBACK, this.infoEx, this.storeInfoExCallback.bind(this));
			this.mdvMap.events.registerEvent(MDVEvent_MAP_INITIALISED, null, changeCheckboxState);
		}
		else if(this.type=='mdvROPMap') {
			new MDVMapEFAInfoEx(this.mdvMap, pinComparatorRouteMap, null, getBusPointImg);
			this.mdvMap.events.registerEvent(MDVEvent_MAP_INITIALISED, null, changeCheckboxState);
		}

	
		// context menu (input map only)
		if (this.type!='mdvROPMap' && this.type!='mdvOutputMap') {
			this.ctxMenuArr = new Array();
			 if (this.usage=='destination'){
				this.ctxMenuArr[0] = new MDVMapMenuItem(setDestination, this.setCoordinates);
			}
			else if (this.usage=='via'){
				this.ctxMenuArr[0] = new MDVMapMenuItem(setVia, this.setCoordinates);
			}
			else if (this.usage=='sf'){
				this.ctxMenuArr[0] = new MDVMapMenuItem(setOrigin, this.setCoordinates);
			}
			else{ 
				this.ctxMenuArr[0] = new MDVMapMenuItem(setOrigin, this.setCoordinates);
			}
				
			this.ctxMenuArr[1] = new MDVMapMenuItem('Services', this.getServiceInfo);
			this.ctxMenu = new MDVMapMenu(this.ctxMenuArr);
			new MDVMapContextMenu(this.mdvMap, this.ctxMenu);
			this.mdvMap.events.registerEvent(MDVEvent_CONTEXT_MENU, this, this.ContextMenuHandler); 
		}
		else{
			this.ctxMenuArr = new Array();
			this.ctxMenuArr[0] = new MDVMapMenuItem('Services', this.getServiceInfo);
			this.ctxMenu = new MDVMapMenu(this.ctxMenuArr);
			new MDVMapContextMenu(this.mdvMap, this.ctxMenu);
			this.mdvMap.events.registerEvent(MDVEvent_CONTEXT_MENU, this, this.ContextMenuHandler); 
		}
		
		this.mdvMap.events.registerEvent(MDVEvent_TOOLTIP, this, this.onToolTip);

		if(mapLanguage =='de'){
			var controlText = new Array();
			controlText['goNorth'] = 'Norden';
			controlText['goWest'] = 'Westen';
			controlText['goEast'] = 'Osten';
			controlText['goSouth'] = 'Süden';
			controlText['lastResult'] = 'Letztes Ergebnis';
			controlText['zoomIn'] = 'Vergrößern';
			controlText['zoomOut'] = 'Verkleinern';
		}
		else if(mapLanguage =='fr'){
			var controlText = new Array();
			controlText['goNorth'] = 'Norden';
			controlText['goWest'] = 'Westen';
			controlText['goEast'] = 'Osten';
			controlText['goSouth'] = 'Süden';
			controlText['lastResult'] = 'Dernier résultat';
			controlText['zoomIn'] = 'Vergrößern';
			controlText['zoomOut'] = 'Verkleinern';
		}
		
		new MDVMapControl(this.mdvMap, controlText);
		new MDVMapNavigator(this.mdvMap);
		
		// cklick objects on map (input map only)
		if(this.smslookup ==true){
			this.mdvMap.events.registerEvent(MDVEvent_OBJECT_CLICKED, this, this.submitSMSObject);
		}
		
		else if (this.type!='mdvOutputMap' && this.type!='mdvROPMap'){
			this.mdvMap.events.registerEvent(MDVEvent_OBJECT_CLICKED, this, this.submitObject);
		}
		// apply reduction list to journeys on output map
		else {
			this.trips = new MDVMapEFATrips(this.mdvMap, { reductionList: reductionList });
		}
		
		this.markerLayer = this.mdvMap.createLayer('variousMarkers');
		this.markerLayer.setZIndex('300');
		this.mdvMap.addLayer(this.markerLayer);
	}

	
	// initialize the mini map
	if (this.mdvMiniMap == null) {
		if(this.type=='mdvOutputMap'){
			this.mdvMiniMap = new MDVMap(document.getElementById('mdvMiniMap_' + routeIndex));
		}
		else{
			this.mdvMiniMap = new MDVMap(document.getElementById('mdvMiniMap'));
		}
		
		new MDVMapNavigator(this.mdvMiniMap); 
	}
	
	// execute map and minimap
	if (this.mdvMap && this.mdvMiniMap) {
		this.mdvMap.execute(mdvMapConfig);			
		this.mdvMiniMap.execute(mdvMapConfigMini);
		this.sync = new MDVMapSyncBound(this.mdvMap, this.mdvMiniMap);
	}

	this.mdvMap.events.registerEvent(MDVEvent_CENTRE_CHANGED, this, function(id, msg, obj) {
		this.sync.updateMiniMap(null, null, this.mdvMap);
	}); 

	// centre on identified origin/destination
	if(document.getElementById('nameX_' + this.usage)){
		this.doIdentified(this.usage);
	}
		
	// set poi categories
	if (document.getElementById('accommodationPOI' + this.mdvMap.name) && this.curCategories) {
		this.curCategories.accommodation = document.getElementById('accommodationPOI' + this.mdvMap.name).checked;
		this.curCategories.attractions = document.getElementById('attractionsPOI' + this.mdvMap.name).checked;
		this.curCategories.sport = document.getElementById('sportPOI' + this.mdvMap.name).checked;
		this.curCategories.education = document.getElementById('educationPOI' + this.mdvMap.name).checked;
		this.curCategories.infrastructure = document.getElementById('infrastructurePOI' + this.mdvMap.name).checked;
		this.curCategories.health = document.getElementById('healthPOI' + this.mdvMap.name).checked;
		this.curCategories.eat = document.getElementById('eatPOI' + this.mdvMap.name).checked;
		this.curCategories.shopping = document.getElementById('shoppingPOI' + this.mdvMap.name).checked;	 
	}	
	
	if(this.usage=='overview'){
		this.journeyOverview= true;
	}

	// display journey
	if (this.type=='mdvOutputMap' && this.routeIndex && document.getElementById('sessionID') && document.getElementById('requestID')){
		this.displayJourney(this.routeIndex, this.journeyOverview);
	}


	// set marker for adresses 
	if(this.smslookup == false){
		this.setMarker();
	}
	
	// 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);
	attachEventListener(document, 'mouseover', this.mdvMiniMap.release.bind(this.mdvMiniMap), false);
};

// This function hides the minimap for the first three zoom level.
MDVMapHelper.prototype.miniMapControl = function (id, msg, index) {

	if(document.getElementById('mdvMiniMap')) {
		// hide mini map is zoom level is 0, 1 or 2
		if (index < 3){
			document.getElementById('mdvMiniMap').style.display ='none';
		}
		// show mini map
		else {
			document.getElementById('mdvMiniMap').style.display ='';
		}
	}
	
	if(document.getElementById('mdvMiniMap_' + this.routeIndex )) {
		// hide mini map is zoom level is 0, 1 or 2
		if (index < 3){
			document.getElementById('mdvMiniMap_' +this.routeIndex ).style.display ='none';
		}
		// show mini map
		else {
			document.getElementById('mdvMiniMap_' +this.routeIndex ).style.display ='';
		}
	}
};

//this function create a tooltip
MDVMapHelper.prototype.onToolTip = function(id, msg, obj) {

	if(!obj.getParent().objectId){
		return false;
	}

	// show border on mouseover 
	var border = '2px solid red';
	var type = 'origin';
	var addText = '';
	var id = obj.getParent().objectId.id;
	var type = obj.getParent().objectId.type;
	
	
	if (obj.parentMarker.toolTip.isVisible() && obj.parentMarker.imgSrc && obj.type!='bubble') {
	
		if(obj.parentMarker.imgSrc.indexOf('pin.gif')!='-1' || obj.parentMarker.imgSrc.indexOf('origin.gif')!='-1'){
			border = '2px solid green';
			type = 'origin';
		}
		else{
			type = 'destination';
		}
		obj.parentMarker.toolTip.container.div.className= 'MDVToolTip_' +type;
	}
	
 	if (obj.getParent().objectId && obj.getParent().objectId.type == 'ENTRANCE' && !obj.processed) {
		obj.setInnerHTML('entrance to ' + obj.getInnerHTML());
	}
	else if (obj.getParent().objectId && obj.getParent().objectId.type == 'BUS_POINT' && !obj.processed) 
	{
		var stopName = obj.getInnerHTML();
		var stopNameChar = '';
		var ifr = ' ';
		var ifrFront = '';
	
		for (var a=0; a < obj.getParent().objectId.attrs.length; a++) {
		
			if (this.smslookup == false && obj.getParent().objectId.attrs[a].name == 'STOP_POINT_REFERED_NAME') {
				stopName = obj.getParent().objectId.attrs[a].value;
			}
			
			if (this.smslookup == true && obj.getParent().objectId.attrs[a].name == 'STOP_POINT_REFERED_NAMEWITHPLACE') {
				stopName = obj.getParent().objectId.attrs[a].value;
			}
			
			if (obj.getParent().objectId.attrs[a].name == 'STOP_POINT_CHARACTERISTICS') {
				stopNameChar = obj.getParent().objectId.attrs[a].value;
			}
			
			if (obj.getParent().objectId.attrs[a].name == 'IDENTIFIER') {
	
				var objValue =obj.getParent().objectId.attrs[a].value +'';
				if(objValue.indexOf('YYY')=='-1'){
					ifr += objValue;
				}
			}
			
			if(document.getElementById('itdLPxx_link') && document.getElementById('itdLPxx_link').value=='smslookup'){
				if (obj.getParent().objectId.attrs[a].name == 'SMS-Code') {
					addText += '<br/>SMS-Code: <b>' + obj.getParent().objectId.attrs[a].value +'</b>'
				} 
			}
		}  
		
		if(ifr && ifr.indexOf('->')!='-1'){
			ifr = ifr.replace(/->SW/, '(SW-Bound)');
			ifr =ifr.replace(/->SE/, '(SE-Bound)');
			ifr =ifr.replace(/->NE/, '(NE-Bound)');
			ifr =ifr.replace(/->NW/, '(NW-Bound)');
			ifr =ifr.replace(/->W/, '(W-Bound)');
			ifr =ifr.replace(/->S/, '(S-Bound)');
			ifr =ifr.replace(/->E/, '(E-Bound)');
			ifr =ifr.replace(/->N/, '(N-Bound)');
		}  
		
		if(stopNameChar.length > 0){
		
			stopNameChar =stopNameChar.replace(/Outside/, 'o/s ');
			stopNameChar =stopNameChar.replace(/Adjacent/, 'adj ');
			stopNameChar =stopNameChar.replace(/Opposite/, 'opp ');
			stopNameChar =stopNameChar.replace(/Near/, 'nr ');
			stopNameChar =stopNameChar.replace(/Behind/, 'behind ');
			
			if(stopNameChar.indexOf('o/s')!='-1' || stopNameChar.indexOf('adj')!='-1'
				|| stopNameChar.indexOf('opp')!='-1' || stopNameChar.indexOf('nr')!='-1'
				|| stopNameChar.indexOf('behind')!='-1'){
				
				if(ifr.indexOf('Bound')!='-1'){
					ifr = '';
				}
				
				if(this.smslookup == false){
					ifrFront = stopNameChar + ifr + ' ';
					stopNameChar = '';
				 	ifr = ''; 
				}
			}
		} 
		
		obj.setInnerHTML('<b>' + ifrFront + stopName + ' '  +stopNameChar + ifr + '</b>' + addText );
	}
	else if(this.type=='mdvROPMap'){
	
		var stopName = obj.getInnerHTML();
	
			if(stopName && stopName.indexOf('->')!='-1'){
			stopName = stopName.replace(/->SW/, '(SW-Bound)');
			stopName =stopName.replace(/->SE/, '(SE-Bound)');
			stopName =stopName.replace(/->NE/, '(NE-Bound)');
			stopName =stopName.replace(/->NW/, '(NW-Bound)');
			stopName =stopName.replace(/->W/, '(W-Bound)');
			stopName =stopName.replace(/->S/, '(S-Bound)');
			stopName =stopName.replace(/->E/, '(E-Bound)');
			stopName =stopName.replace(/->N/, '(N-Bound)');
		}  
	
		obj.setInnerHTML('<b>' + stopName + '</b>' + addText );
	}

	if(this.usage=='dm'){
	
		if( type=='STOP' || type=='BUS_POINT'){
			
		  if (obj.processed == null) {
			 var text = obj.getInnerHTML();
		        text += '<br/>';
		        text += '<div id="dm_'+ id + '">Loading... </div>'; 
		        obj.setInnerHTML(text);
		        obj.update();

			    obj.dm = new MDVEFADepartureMonitor(id, '../em/XSLT_DM_REQUEST'); 
			    obj.dm.getDepartures(id);  
		        obj.processed = true; 
		    }
		    else { 
		        obj.dm.getDepartures(id);
		    } 
		
		return;
		
		}
	
	}
	else{
		obj.processed = true;
		return;
	}
};

// ==================================================================
// Input map functionality.
// ==================================================================

// Center map on the identified location.
MDVMapHelper.prototype.doIdentified = function(usage) {
	var zl = 7;
	var nc = null;
	var mapName = nameMap;
	var x = document.getElementById('nameX_' + usage).value;
	var y = document.getElementById('nameY_' + usage).value;
	
	if (x <= 0 || y <= 0) 
		return;
	
	nc = new MDVCoordinates(mapName, parseInt(x,10), parseInt(y,10));
	this.mdvMap.setCentre(nc);
	this.mdvMap.setZoomLevel(parseInt(zl,10));
	this.mdvMap.update();
};

// This function sets the origin/destination marker
MDVMapHelper.prototype.setMarker = function() {
	for (var i=0; i < usages.length; i++) {
	
		if (document.getElementById('nameX_' + usages[i]) && document.getElementById('nameY_' + usages[i])) {
			var mc = new MDVCoordinates(nameMap, parseInt(document.getElementById('nameX_' + usages[i]).value,10), parseInt(document.getElementById('nameY_' + usages[i]).value,10)-10);
			
			var text;
			var size = new MDVPoint(300, 200);
			
			if(usages[i]=='destination') {
				if (document.getElementById('nameDisplay_destination') 
					&& document.getElementById('nameDisplay_destination').value!=''){
					
					text = document.getElementById('nameDisplay_destination').value;
				}
				else{
					text = mapDestination;
				}
			}
			else if(usages[i]=='via') {
				if (document.getElementById('nameDisplay_via') 
					&& document.getElementById('nameDisplay_via').value!=''){
					
					text = document.getElementById('nameDisplay_via').value;
				}
				else{
					text = mapVia;
				}
			}
			else if(usages[i]=='dm') {
				if (document.getElementById('nameDisplay_dm') 
					&& document.getElementById('nameDisplay_dm').value!=''){
					
					text = document.getElementById('nameDisplay_dm').value;
				}
				else{
					text = mapOrigin;
				}
			}
			else if(usages[i]=='sf') {
				if (document.getElementById('nameDisplay_sf') 
					&& document.getElementById('nameDisplay_sf').value!=''){
					
					text = document.getElementById('nameDisplay_sf').value;
				}
				else{
					text = mapOrigin;
				}
			}
			else {
				if (document.getElementById('nameDisplay_origin') 
					&& document.getElementById('nameDisplay_origin').value!=''){
					
					text = document.getElementById('nameDisplay_origin').value;
				}
				else{
					text = mapOrigin;
				}
			}
			
			this.marker = this.mdvMap.createMarker(mc, 0, this.getImage(usages[i]));
			var tool = this.mdvMap.createToolTip('<b>' + text + '</b>');
			this.marker.setToolTip(tool);
			this.markerLayer.addMarker(this.marker);
		}
	}
};

// This function returns the marker image.
MDVMapHelper.prototype.getImage = function(usage) {
	var img = 'images/map/origin.gif';

	switch(usage) {
		case 'destination':
			img = 'images/map/destination.gif';
			break;
		case 'via':
			img = 'images/map/via.gif';
			break;
	}

	var i = new Image();
	i.src = img;

	return img;
};

// This function sets the parameters for the request and submits the form
MDVMapHelper.prototype.submitObject = function(id, msg, obj) {
	
	var prefix = '';
	var type;
	var odvID = obj.id;
	
	if (obj.type == 'POI_POINT' || type == 'POI_AREA') {
		type= 'poiID';
	}
	else if (obj.type == 'STOP' || obj.type == 'BUS_POINT')
	{
		type = 'stopID';
	}
		
	switch (type) {
		case 'coord':
			document.getElementById('nameInfo_' + this.usage).value = odvID; 
			document.getElementById('typeInfo_' + this.usage).value = 'coord';
			document.getElementById('placeInfo_' + this.usage).value = '';
			break;
		case 'poiID':
		
			if(odvID.indexOf('-')!='-1'){
				odvID = odvID.substr(odvID.indexOf('-') + 1);
			}
			else if(odvID.indexOf('|')!='-1'){
				odvID = odvID.substr(odvID.indexOf('|') + 1);
			}
			
			document.getElementById('placeInfo_' + this.usage).value = obj.omc + ':-1';
			document.getElementById('typeInfo_' + this.usage).value = type;
			document.getElementById('nameInfo_' + this.usage).value = odvID;
			document.getElementById('nameState_' + this.usage).value = 'empty';
			document.getElementById('placeState_' + this.usage).value = 'empty';
			break;
		case 'stopID':
			document.getElementById('placeInfo_' + this.usage).value = '';	
			document.getElementById('typeInfo_' + this.usage).value = type;
			document.getElementById('nameInfo_' + this.usage).value = odvID;
			document.getElementById('nameState_' + this.usage).value = 'empty';
			document.getElementById('placeState_' + this.usage).value = 'empty';
			break;
	}	
	if (document.forms[0].execInst){
		document.forms[0].execInst.value = 'verifyOnly';
	}
		
	document.forms[0].submit();
};

// This function sets the parameters for the request and submits the form
MDVMapHelper.prototype.submitSMSObject = function(id, msg, obj) {
	var prefix = '';
	var type;
	var odvID = obj.id;
	
	if (obj.type == 'POI_POINT' || type == 'POI_AREA') {
		type= 'poiID';
	}
	else if (obj.type == 'STOP' || obj.type == 'BUS_POINT')
	{
		type = 'stopID';
	}

	var URL = 'XSLT_TRIP_REQUEST2?language=en';
		
	switch (type) {
		case 'coord':
			URL +='&name_origin=' + odvID; 
			URL +='&type_origin=coord';
			break;
		case 'poiID':
			odvID = odvID.substr(odvID.indexOf('|') + 1);
			URL +='&name_origin=' + odvID; 
			URL +='&type_origin=poiID';
			URL +='&placeInfo_origin=' +  obj.omc + ':-1';
			
			break;
		case 'stopID':
			URL +='&name_origin=' + odvID; 
			URL +='&type_origin=stopID';
			break;
	}	
		
	URL += '&execInst=verifyOnly&sessionID=0'
		
	URLOrig = URL;
	URLDest = URL.replace(/origin/g,"destination");
	ttText = obj.marker.toolTip.innerHTML + '<br/><br/>';
	ttText += 'Travel <a href="' + URLOrig + '">from here</a><br/>Travel <a href="' + URLDest +'">to here</a>';
	
	var tooltip = mdvJpMaps[mapType].mdvMap.createToolTip(new MDVPoint(250, 140), ttText);
	tooltip.setPin(true);
	
	var coord = new MDVCoordinates(obj.marker.coords.mapName, parseInt(obj.marker.coords.x), parseInt(obj.marker.coords.y));
  
    mdvJpMaps[mapType].hiddenMarker = mdvJpMaps[mapType].mdvMap.createMarker(coord, new MDVPoint(0, 0), 'images/map/transparent.gif');
    mdvJpMaps[mapType].hiddenMarker.setToolTip(tooltip);
	mdvJpMaps[mapType].markerLayer.addMarker(mdvJpMaps[mapType].hiddenMarker);
	mdvJpMaps[mapType].hiddenMarker.toolTip.display();
	
};

// ==================================================================
// Trip request context menu functions.
// ==================================================================

MDVMapHelper.prototype.ContextMenuHandler = function(id, status, obj) {

	if(this.type=='mdvROPMap' || this.type=='mdvOutputMap')
	{
		if(status == true && this.mdvMap.config.getZoomLevelIndex() > 5 && mapsPhase2 == true){
			this.ctxMenu.div.style.display ='block'; 
		}
		else{
			this.ctxMenu.div.style.display='none';
		}
	}
	else{
		if(this.mdvMap.config.getZoomLevelIndex() > 5 && mapsPhase2 == true){
			this.ctxMenu.div.childNodes[1].style.display ='';
		}
		else{
			this.ctxMenu.div.childNodes[1].style.display='none';
		}
	}

	if(status == true)
		ctxCoords = obj;
}

// This context menu functions submits a selected point.
MDVMapHelper.prototype.getServiceInfo = function() {

	var host   = this.mdvMap.config.get('efaURL');
	
	var _params = { 
		language: 'en', 
		coord: Math.floor(ctxCoords.x + 0.5) + ':' + Math.floor(ctxCoords.y + 0.5) + ':' + ctxCoords.mapName, 
		type_1: 'LINE', 
		radius_1: '100',
		inclFilter: '1', 		
		coordListFormat: 'STRING', 
		itdLPxx_mdvMapName: 'mdvMap_' + this.mdvMap.getName(), 
		coordListOutputFormat: 'STRING' 
	};

	var _ajax = mdvLib.ajax({ host: host, parameters: _params, onComplete: MDVMapEFALine_onAjaxComplete });
	
};

 function MDVMapEFALine_onAjaxComplete(request) {
 	var json = null;
 	var efa = null;
 	
	// Check if we need to use the prototype lib.
 	if (request && request.responseText)	{
 		json = request.responseText;
 	// Otherwise use jQuery lib.
 	} else if (request) {
 		json = request;
 	}
	
 	eval('efa = ' + json + ';'); 	
 	
  	for (var i=0; i < efa.parameters.length; i++) {
  		if (efa.parameters[i].name == 'mdvMapName') {
  			mdvMapName = efa.parameters[i].value;
  			break;
  		}
  	}
	
	var lines = efa.coordInfo.pins;
	var table = '<table>';
	
	if(lines){
		
		if(!lines.length){
		
			lines = efa.coordInfo.pins.pin;
			table += '<tr><td><b>';
			table += lines.desc ;
			table += '</b></td><td>';
			
			for(l =0; l < lines.attrs.length; l++){
				if(lines.attrs[l].name=='LINE_OPERATOR_NAME'){
					table +='<b>'+ lines.attrs[l].value + ':</b> ';
				}
			}
			
			for(l =0; l < lines.attrs.length; l++){
				if(lines.attrs[l].name=='LINE_DESCRIPTION'){
					table += lines.attrs[l].value;
				}
			} 
			table += '</td></tr>';
		
		}
		else{
			for(var i =0; i < lines.length; i++){
			
				table += '<tr><td><b>';
				table += lines[i].desc ;
				table += '</b></td><td>';
				
				for(l =0; l < lines[i].attrs.length; l++){
					if(lines[i].attrs[l].name=='LINE_OPERATOR_NAME'){
						table +='<b>'+ lines[i].attrs[l].value + ':</b> ';
					}
				}
				
				for(l =0; l < lines[i].attrs.length; l++){
					if(lines[i].attrs[l].name=='LINE_DESCRIPTION'){
						table += lines[i].attrs[l].value;
					}
				} 
				
				table += '</td></tr>';
			}
		
		}
	}
	else{
		table += '<tr><td>No serving lines</td></tr>';
	}
				
	table += '</table>';

	var coords = efa.coordInfo.request.coords;
	var tooltip = mdvJpMaps[mapType].mdvMap.createToolTip(new MDVPoint(250, 180), '<b>Matching Services</b><br/>' + table);
	tooltip.setPin(true);
	
	var coord = new MDVCoordinates(coords.mapName, parseInt(coords.x), parseInt(coords.y));
                  
    mdvJpMaps[mapType].hiddenMarker = mdvJpMaps[mapType].mdvMap.createMarker(coord, new MDVPoint(0, 0), 'images/map/transparent.gif');
    mdvJpMaps[mapType].hiddenMarker.setToolTip(tooltip);
	mdvJpMaps[mapType].markerLayer.addMarker(mdvJpMaps[mapType].hiddenMarker);
	mdvJpMaps[mapType].hiddenMarker.toolTip.display();
	
	sorter.init("sorter",1);
	sorter.init("sorter",0);
	
 }
 
// sort overview table 
var table=function(){

	function sorter(n){
		this.n=n; this.t; this.b; this.r; this.a=[]; this.l=0
	}
	
	sorter.prototype.init=function(tableID,f){
		// get table
		this.t=document.getElementById(tableID);
		this.b=this.t.getElementsByTagName('tbody')[0];
		this.r=this.b.rows; 
		var l=this.r.length;
		
		 for(var i=0;i<l;i++){
			this.a[i]={}; 
		} 
		
		if(f!=null){
			var a=new Function(this.n+'.work('+f+')'); a()
		}
	}
	sorter.prototype.work=function(y){
		
		this.b=this.t.getElementsByTagName('tbody')[0]; 
		this.r=this.b.rows;
		
		for(i=0;i<this.r.length;i++){
			this.a[i].o=i; 
			this.a[i].value=this.r[i].childNodes[y].innerText;
		}

		this.a.sort(compare); 
		
		var n=document.createElement('tbody');
		
		for(i=0;i<this.r.length;i++){
			var r=this.r[this.a[i].o].cloneNode(true);
			n.appendChild(r);
		}

		this.t.replaceChild(n,this.b)
		
	}
	
	function compare(f,c){
		f=f.value,c=c.value;
		
		var i=parseFloat(f.replace(/(\$|\,)/g,'')),n=parseFloat(c.replace(/(\$|\,)/g,''));
		if(!isNaN(i)&&!isNaN(n)){f=i,c=n}
		return (f>c?1:(f<c?-1:0))
	}
	return{sorter:sorter}

}();

var sorter=new table.sorter("sorter");

//function set the coordinates form the context  menue
MDVMapHelper.prototype.setCoordinates = function() {

	var usage = mdvJpMaps[mapType].usage;

	if (mdvJpMaps[mapType].mdvMap) {
		// text displayed in the GUI
		var text  = mapOrigin;

		if(usage=='destination'){
			text = mapDestination;
		}
		else if(usage=='via'){
			text = mapVia;
		}
		
		// store coordinates and type
		document.getElementById('nameInfo_' + usage).value = parseInt(ctxCoords.x) + ':' + parseInt(ctxCoords.y) + ':' + ctxCoords.mapName + ':' + text; 
		
		if(usage=='dm'){
			document.getElementById('itdLPxx_mapCoord').value = parseInt(ctxCoords.x) + ':' + parseInt(ctxCoords.y) + ':' + ctxCoords.mapName + ':' + text; 
		}
		
		document.getElementById('typeInfo_' + usage).value = 'coord';
		document.getElementById('nameState_' + usage).value = 'notidentified';
		if (document.getElementById('placeState_' + usage))
			document.getElementById('placeState_' + usage).value = 'notidentified';
		if (document.getElementById('placeInfo_' + usage))
			document.getElementById('placeInfo_' + usage).value = '';
		
		mdvJpMaps[mapType].mdvMap.mapper.style.cursor = 'wait';
		document.forms[0].execInst.value = 'verifyOnly';
		document.forms[0].submit();
	}
};	

// ==================================================================
// POI functions.
// ==================================================================
// This function hides the POI checkboxes.
function disableCheckboxes(bool) {
	 if(mdvLib.typeOf(bool) !== 'boolean') {
		return;
	}
	
	if (bool) {
	
		for (var i =0; i < document.getDivsByClassName('POICategories').length; i++){
			document.getDivsByClassName('POICategories')[i].style.display='none';
		}
	}
	else if (displayPOICat){
		for (var i =0; i < document.getDivsByClassName('POICategories').length; i++){
			document.getDivsByClassName('POICategories')[i].style.display='block';
		}
	}
	else {
		for (var i =0; i < document.getDivsByClassName('POICategories').length; i++){
			document.getDivsByClassName('POICategories')[i].style.display='none';
		}
	} 
}

// This function displays/hides all POIs.
function toggleAllPOIs(state) {

	if (state) {
		document.getElementById('accommodationPOI' + mdvJpMaps[mapType].mdvMap.name).checked = true;
		document.getElementById('attractionsPOI' + mdvJpMaps[mapType].mdvMap.name).checked = true;
		document.getElementById('sportPOI' + mdvJpMaps[mapType].mdvMap.name).checked = true;
		document.getElementById('educationPOI' + mdvJpMaps[mapType].mdvMap.name).checked = true;
		document.getElementById('infrastructurePOI' +mdvJpMaps[mapType].mdvMap.name).checked = true;
		document.getElementById('healthPOI' +mdvJpMaps[mapType].mdvMap.name).checked = true;
		document.getElementById('eatPOI' +mdvJpMaps[mapType].mdvMap.name).checked = true;
		document.getElementById('shoppingPOI' +mdvJpMaps[mapType].mdvMap.name).checked = true;
		// store checkbox value
		mdvJpMaps[mapType].curCategories['accommodation'] = true;
		mdvJpMaps[mapType].curCategories['attractions'] = true;
		mdvJpMaps[mapType].curCategories['sport'] = true;
		mdvJpMaps[mapType].curCategories['education'] = true;
		mdvJpMaps[mapType].curCategories['infrastructure'] = true;
		mdvJpMaps[mapType].curCategories['health'] = true;
		mdvJpMaps[mapType].curCategories['eat'] = true;
		mdvJpMaps[mapType].curCategories['shopping'] = true;
		// update Pins
		if(mdvJpMaps[mapType].infoExCallback.request !== null) {
			mdvJpMaps[mapType].infoEx.processPins(mdvJpMaps[mapType].infoExCallback.id, mdvJpMaps[mapType].infoExCallback.gadName, mdvJpMaps[mapType].infoExCallback.request);
		}	
	}
	else {
		document.getElementById('accommodationPOI' + mdvJpMaps[mapType].mdvMap.name).checked = false;
		document.getElementById('attractionsPOI' + mdvJpMaps[mapType].mdvMap.name).checked = false;
		document.getElementById('sportPOI' + mdvJpMaps[mapType].mdvMap.name).checked = false;
		document.getElementById('educationPOI' + mdvJpMaps[mapType].mdvMap.name).checked = false;
		document.getElementById('infrastructurePOI'  + mdvJpMaps[mapType].mdvMap.name).checked = false;
		document.getElementById('healthPOI'  + mdvJpMaps[mapType].mdvMap.name).checked = false;
		document.getElementById('eatPOI'  + mdvJpMaps[mapType].mdvMap.name).checked = false;
		document.getElementById('shoppingPOI'  + mdvJpMaps[mapType].mdvMap.name).checked = false;
		// store checkbox value
		mdvJpMaps[mapType].curCategories['accommodation'] = false;
		mdvJpMaps[mapType].curCategories['attractions'] = false;
		mdvJpMaps[mapType].curCategories['sport'] = false;
		mdvJpMaps[mapType].curCategories['education'] = false;
		mdvJpMaps[mapType].curCategories['infrastructure'] = false;
		mdvJpMaps[mapType].curCategories['health'] = false;
		mdvJpMaps[mapType].curCategories['eat'] = false;
		mdvJpMaps[mapType].curCategories['shopping'] = false;
		
		// update Pins
		if(mdvJpMaps[mapType].infoExCallback.request !== null) {
			mdvJpMaps[mapType].infoEx.processPins(mdvJpMaps[mapType].infoExCallback.id, mdvJpMaps[mapType].infoExCallback.gadName, mdvJpMaps[mapType].infoExCallback.request);
		}	
	}
	mdvJpMaps[mapType].mdvMap.update();
	
}

// This function is called if a POI checkbox is selected or deselected.
function setPOICheckbox(obj) {

	if (!mdvJpMaps) {
		return;
	}
	
	// store checkbox value
	mdvJpMaps[mapType].curCategories[obj.value] = obj.checked;
		
	// update Pins
	if(mdvJpMaps[mapType].infoExCallback.request !== null) {
		mdvJpMaps[mapType].infoEx.processPins(mdvJpMaps[mapType].infoExCallback.id, mdvJpMaps[mapType].infoExCallback.gadName, mdvJpMaps[mapType].infoExCallback.request);
	}	
	
	mdvJpMaps[mapType].mdvMap.update();
}

// This function determines which POI will be displayed on the map.
function pinComparator(pin) {

	var checkOMC = pin.omc +'';

	 if(checkOMC.substring(0,5)!='31117' && pin.marker.imgSrc.indexOf('mot4')!='-1')
	{
		pin.marker.imgSrc = 'images/map/mot4_2.gif';
	} 

	if(pin.type == 'BUS_POINT'){
		for (var a=0; a < pin.attrs.length; a++) {
			if (pin.attrs[a].name == 'STOP_AREA_NAME' && pin.attrs[a].value.indexOf('NCS')!='-1') {
				return false;
			}

			if (pin.attrs[a].name == 'IDENTIFIER' && pin.attrs[a].value.toString().length == 5 && parseInt(pin.attrs[a].value) >= 0) {
				return false;
			}
		} 
		
		
	}
	
	if(pin.type == 'STOP' && mdvJpMaps[mapType].mdvMap.config.getZoomLevelIndex() > 6){
		return false;
	}
	
	if (pin.type === 'POI_POINT' || pin.type === 'POI_AREA') {
		var mm	= pin.attrs;
		if (mm && mm.length > 0) {
			var cat = getPoiCategory(mm);
			if (cat !== '' && cat !== 'IRRELEVANT') {
				return true;
			}
			return false;
		}
	}

	return true;
}

// This function determines which POI will be displayed on the map.
function pinComparatorRouteMap(pin) {
	
	if(pin.type == 'STOP' || pin.type === 'BUS_POINT'){
		return false;
	}
	
	if (pin.type === 'POI_POINT' || pin.type === 'POI_AREA') {
		var mm	= pin.attrs;
		if (mm && mm.length > 0) {
			var cat = getPoiCategory(mm);
			if (cat !== '' && cat !== 'IRRELEVANT') {
				return true;
			}
			return false;
		}
	}

	return true;
}


function getMOTImage(mot, type, pin){

}

function getBusPointImg(pin) {

	var imgPath = 'images/map/';
	
	var omc = pin.omc + '';
	
	if (this.mdvMap.config.get('imagePath')){
		imgPath = this.mdvMap.config.get('imagePath');
	}
		
	if (this.letters[pin.identifier] && this.letters[pin.identifier].src) {
	  	return this.letters[pin.identifier].src;
	} 
	else if (pin.identifier && pin.identifier.toString().indexOf('->') > -1) {
		imgPath += 'pointi.gif';		
		return imgPath;
	} 
	else if (pin.identifier && pin.identifier  > 1000) {
		imgPath += 'pointi.gif';		
		return imgPath;
	}
	else if (omc.indexOf('31117')!='-1' && (pin.id.substring(pin.id.lastIndexOf('|')+1) > 1000 || pin.id.substring(pin.id.lastIndexOf('-')+1) > 1000)) {
		imgPath += 'pointi.gif';		
		return imgPath;
	}
	else {
	
		if(omc.indexOf('31117')!='-1'){
            if (pin.id.lastIndexOf('|') > 0)  {
                imgPath += 'point_' + pin.id.substring(pin.id.lastIndexOf('|')+1) + '.gif';
            }
            else {
                imgPath += 'point_' + pin.id.substring(pin.id.lastIndexOf('-')+1) + '.gif';
            }
		}
		else{
			imgPath += 'pointi.gif';
		}

		return imgPath;
	}
}

// This function returns the POI categorie.
function getPoiCategory (attr) {
	var ret = '';
	
	function isRelevantCategory(strVal) {
		if (mdvJpMaps[mapType].curCategories.accommodation == true && 
			(strVal === 'Accommodation')) {
			return 'accommodation';
		}
		if (mdvJpMaps[mapType].curCategories.attractions == true && 
			strVal === 'Attractions') {
			return 'attractions';
		} 
		if (mdvJpMaps[mapType].curCategories.sport == true && 
			strVal === 'Sport And Entertainment') {
			return 'sport';
		} 
		if (mdvJpMaps[mapType].curCategories.education == true && 
			strVal === 'Education') {
			return 'education';
		} 
		if (mdvJpMaps[mapType].curCategories.infrastructure == true && 
			strVal === 'Public Infrastructure') {
			return 'infrastructure';
		} 
		if (mdvJpMaps[mapType].curCategories.health == true && 
			strVal === 'Health') {
			return 'health';
		} 
		if (mdvJpMaps[mapType].curCategories.eat == true && 
			(strVal === 'Eat And Drink')) {
			return 'eat';
		} 
		if (mdvJpMaps[mapType].curCategories.shopping == true && 
			strVal === 'Shopping') {
			return 'shopping';
		} 
		return 'IRRELEVANT';
	}
	
	for (var m=0; m < attr.length; m++) {
		var tmpNode = attr[m];
		
		if (tmpNode.name.indexOf('POI_HIERARCHY_0') !== -1) {
			ret = isRelevantCategory(tmpNode.value);
		}
		
		if (ret != '' && ret != 'IRRELEVANT') {
			return ret;
		}
	}
	
	return ret;
}

// This function determines if the POI checkboxes has to be disabled. They will be disabled if no POIs available in the current zoom level.
function changeCheckboxState(id, msg, obj) {
	var zoomlevel = obj.config.getZoomLevelIndex();

	if (zoomlevel < 7) {
		disableCheckboxes(true);
		return;
	} 
	
	disableCheckboxes(false);
}

// This function stores the infoEx callback.
MDVMapHelper.prototype.storeInfoExCallback = function(id, gadName, request) {
	this.infoExCallback.id = id;
	this.infoExCallback.gadName = gadName;
	this.infoExCallback.request = request;

};

// ==================================================================
// Map output functions.
// ==================================================================

// This function displays a journey on the map.
 MDVMapHelper.prototype.displayJourney = function(tripIndex, journeyOverview) {
	
	var sessionID = document.getElementById('sessionID').value;
	var requestID = document.getElementById('requestID').value;
	
	this.trips.loadTrip(sessionID, requestID, tripIndex, journeyOverview);	
	this.mdvMapTripsLoaded = true;
}; 

// This function centers the map on a certail location within the route
MDVMapHelper.prototype.displayJourneyPoint = function(x, y) { 

	if (x!='' && y!='') {
		this.mdvMap.setCentre(new MDVCoordinates(nameMap, x, y));
		this.mdvMap.setZoomLevel(areaMapZoomLevel);
		this.mdvMap.update();
	}
}

// animation link 
MDVMapHelper.prototype.launchWizard = function(zoomLevel) {
	if (this.mdvMapTripsLoaded) {
		this.trips.launchWizard(zoomLevel);		
	}
};

// animation link 
MDVMapHelper.prototype.launchWizardROP = function(zoomLevel) {

	if (this.mdvMapper == null)
		this.mdvMapper = new MDVMapObjectMapper(this);	

	this.mdvMapper.launchWizardROP(zoomLevel);
}

// ==================================================================
// Overwritten map functionality.
// ==================================================================

// This function creates the map control outside of the map.
MDVMapControl.prototype.execute = function () {

	// Fetch Images
	this.preloadImgs();

	// Store Origin Coords and ZoomLevel
	this.origin = new MDVCoordinates(this.mdvMap.config.get('mapName'),
	parseInt(this.mdvMap.config.get('xCenterReal')),
	parseInt(this.mdvMap.config.get('yCenterReal')));

	this.zoomLevel = this.mdvMap.config.get('defaultScale');

	// Bounding Box
	this.mapControl = this.createDiv();
	this.mapControl.className = 'MDVMapControl';
	
	var controlElem = document.getElementById('mapControl');
	
	if(this.mdvMap.name.indexOf('_')!='-1'){
		controlElem =	document.getElementById('mapControl_' + this.mdvMap.name.split('_')[1])
	}
	
	controlElem.innerHTML = '';
	controlElem.appendChild(this.mapControl);

	// Container for Arrows
	this.arrowContainer = this.createDiv();
	this.arrowContainer.className = 'MDVMapControl_Arrows';
	// Container for Zoom Levels
	this.zoomContainer = this.createDiv();
	this.zoomContainer.className = 'MDVMapControl_ZoomLevels';

	// List of all Zoom Levels
	this.zoomLevels = new Array();

	this.mapControl.appendChild(this.arrowContainer);
	this.mapControl.appendChild(this.zoomContainer);

	// Populate
	this.populateContainers();

	// Update
	this.update();
};
 
// This function processes the poi and stop pins on map. 
MDVMapEFAInfoEx.prototype.processPins = function(id, gadName, request) {

	if (gadName != 'MDVMapEFAInfoEx')
		return false;
		
	// Clear job ID
	mdvTimer.remove(this.id); this.id = null;

	// TODO: Check whether we need to handle the request or not...
	var zoomLevel = this.mdvMap.config.getZoomLevel(this.mdvMap.config.getZoomLevelIndex());
	var showStops = zoomLevel.get('showSTOP') == "true" ? true : false;
	var showPOI   = zoomLevel.get('showPOI') == "true" ? true : false;

	this.stops.removeAll();
	this.poi.removeAll();

	if (request.coordInfo && request.coordInfo.request) {
		var reqCoord = new MDVCoordinates(request.coordInfo.request.coords.mapName, 
			request.coordInfo.request.coords.x, 
			request.coordInfo.request.coords.y);

		if (!reqCoord.equals(this.mdvMap.getCentre())) {
			return false;
		}
	}

	var updateStops = false;
	var updatePOI 	= false;

	if (!request.coordInfo.pins || request.coordInfo.pins.length <= 0) {
		this.mdvMap.events.triggerEvent(MDVEvent_ERROR, 'MDVMap wasn\'t able to get pins from map request.');
		return false;
	}
	
	var allPins = [];
	if (mdvLib.typeOf(request.coordInfo.pins)==='object' && request.coordInfo.pins.pin) {
		allPins.push(request.coordInfo.pins.pin);
	} 
	else {
		allPins = request.coordInfo.pins;
	}

	for(var i=0; i<allPins.length; i++) {
		var pinName = allPins[i].desc;
		var	pinId	= allPins[i].id;
		var	pinType	= allPins[i].type;
		var	pinOmc	= allPins[i].omc;
		var pinIdentifier = allPins[i].identifier;
		var tmpImg  = new Image();

		var sMeans	= allPins[i].attrs;
		if (sMeans && sMeans.length > 0 && pinType.toUpperCase() == 'POI_POINT' ) {
			var nodeValue = '';

			for (var m=0; m < sMeans.length; m++) {
				var tmpNode = sMeans[m];

				if (tmpNode.name == 'STOP_MAJOR_MEANS' || tmpNode.name == 'NaPTAN-ID' || tmpNode.name == 'StreetName' ) {
					nodeValue = tmpNode.value;
					break;
				}
			}
			tmpImg.src = this.getMOTImage(nodeValue, pinType, allPins[i]);
			
		} else {
			if (pinType.toUpperCase() == 'BUS_POINT')
				tmpImg.src = this.getBusPointImg(allPins[i]);
			else if (pinType.toUpperCase() == 'ENTRANCE')
				tmpImg.src = this.entranceImg.src;
			else if (pinType.toUpperCase() == 'GIS_POINT')
				tmpImg.src = this.poiImg.src;
			else if (pinType.toUpperCase() == 'POI_POINT')
				tmpImg.src = this.poiImg.src;
			else if (pinType.toUpperCase() == 'POI_AREA')
				tmpImg.src = this.poiImg.src;
			else
				tmpImg.src = this.stopImg.src;
		}
		
		var bubbleSize = new Array();
			bubbleSize['poi']  = new MDVPoint(284, 190);
			bubbleSize['stop'] = new MDVPoint(284, 190);
			
		if (this.mdvMap.config.get('info.stop.size.width')
			&& this.mdvMap.config.get('info.stop.size.height')) {
			
			bubbleSize['stop'] = new MDVPoint(this.mdvMap.config.get('info.stop.size.width'),
				this.mdvMap.config.get('info.stop.size.height'));
		}

		if (this.mdvMap.config.get('info.poi.size.width')
			&& this.mdvMap.config.get('info.poi.size.height')) {
			
			bubbleSize['poi'] = new MDVPoint(this.mdvMap.config.get('info.poi.size.width'), 
				this.mdvMap.config.get('info.poi.size.height'));
		}
		
		var coordList = allPins[i].coords.split(',');		

		var coords = new MDVCoordinates(request.coordInfo.request.coords.mapName,
			coordList[0],
			coordList[1]);
			
		var pos = 0.5;
		
		switch (pinType.toUpperCase()) {
			case 'ENTRANCE':
				pos = new MDVPoint(0.5, 0.5);
			break;
			case 'BUS_POINT':
				pos = new MDVPoint(0.5, 0.5);
			break;
			default:
				if (this.options['alignment'])
					pos = this.options['alignment'];
			break;
		}

		var mapPin = this.mdvMap.createMarker(coords, pos, tmpImg.src);
		var attrs = null;
		
		if (allPins[i].attrs)
			attrs = allPins[i].attrs;
	
		mapPin.objectId = { type: pinType, desc: pinName, id: pinId, omc: pinOmc, identifier: pinIdentifier, marker: mapPin, attrs: attrs };
		
		if (this.comparator) {
			if (!this.comparator(mapPin.objectId)) continue;
		}
		
		switch (pinType.toUpperCase()) {
			case 'GIS_POINT':
			case 'POI_POINT':
			case 'POI_AREA':
				var mapPinTitle = null;
				// at the moment no bubble for pois in SE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
				if (this.mdvMap.config.get('useBubbleForEFAInfoPOI') && this.mdvMap.config.get('useBubbleForEFAInfoPOI') == 'true') {
					mapPinTitle = this.mdvMap.createToolTip(bubbleSize['poi'], '<b>' + pinName + '</b>');
					if (this.mdvMap.config.get('useBubbleOverflowForEFAInfo') && this.mdvMap.config.get('useBubbleOverflowForEFAInfo') == 'true')
						mapPinTitle.setOverflow(true);
					if (this.mdvMap.config.get('useBubblePinForEFAInfo') && this.mdvMap.config.get('useBubblePinForEFAInfo') == 'true')
						mapPinTitle.setPin(true);
					mapPin.setToolTip(mapPinTitle, false);
				} else {
					mapPinTitle = this.mdvMap.createToolTip('<b>' + pinName + '</b>');
					mapPin.setToolTip(mapPinTitle, false);
				}
			break;
			default:
				var mapPinTitle = null;
				if (this.mdvMap.config.get('useBubbleForEFAInfo') && this.mdvMap.config.get('useBubbleForEFAInfo') == 'true') {
					mapPinTitle = this.mdvMap.createToolTip(bubbleSize['stop'], '<b>' + pinName + '</b>');
					if (this.mdvMap.config.get('useBubbleOverflowForEFAInfo') && this.mdvMap.config.get('useBubbleOverflowForEFAInfo') == 'true')
						mapPinTitle.setOverflow(true);
					if (this.mdvMap.config.get('useBubblePinForEFAInfo') && this.mdvMap.config.get('useBubblePinForEFAInfo') == 'true')
						mapPinTitle.setPin(true);
					mapPin.setToolTip(mapPinTitle, false);
				} else {
				
					mapPinTitle = this.mdvMap.createToolTip('<b>' + pinName + '</b>');
					mapPin.setToolTip(mapPinTitle, false);
				}
			break;
		}

		switch (pinType.toUpperCase()) {
			case 'GIS_POINT':
			case 'POI_POINT':
			case 'POI_AREA':
				// Add marker but don't perform update (false)
				if (showPOI) {
					// Check whether the marker is already available in the layer.
					for (var m=0; m < this.poi.getMarkers().length; m++) {
						var pois = this.poi.getMarkers();
						if (pois[m].objectId.id == mapPin.objectId.id 
							&& pois[m].objectId.omc == mapPin.objectId.omc) {
							stopIt = true;
							break;
						}
					}
					
					if (stopIt)
						continue;
					
					this.poi.addMarker(mapPin, false);
					updatePOI 	= true;
				}
				break;
			default:
				// Add marker but don't perform update (false)
				if (showStops) {
					var stopIt = false;
					
					// Check whether the marker is already available in the layer.
					for (var m=0; m < this.stops.getMarkers().length; m++) {
						var stops = this.stops.getMarkers();
						if (stops[m].objectId.id == mapPin.objectId.id) {
							stopIt = true;
							break;
						}
					}
					
					if (stopIt)
						continue;
					
					this.stops.addMarker(mapPin, false);
					updateStops = true;
				}
				break;
		}
	}  
	
	// Check whether we need to update the marker layers
	if (updateStops) 
		this.stops.update();
	if (updatePOI) 
		this.poi.update();
	
	this.centre = new MDVCoordinates(this.mdvMap.getCentre().mapName,
		this.mdvMap.getCentre().x,
		this.mdvMap.getCentre().y);

	return true;
}

// This function fetches the pins.
MDVMapEFAInfoEx.prototype.fetchPins = function() {
	// Get Pins for current position & zoom level.
	if (this.mdvMap.config.get('efaURL')) {

		var host   = this.mdvMap.config.get('efaURL');
		var centre = this.mdvMap.getCentre();
		var language = this.mdvMap.config.get('language') != null ? this.mdvMap.config.get('language') : 'en';
		var zoomLevel = this.mdvMap.config.getZoomLevel(this.mdvMap.config.getZoomLevelIndex());
		var isLast = this.mdvMap.config.getZoomLevel(parseInt(this.mdvMap.config.getZoomLevelIndex())+1) == null;
		var isOneBeforeLast = this.mdvMap.config.getZoomLevel(parseInt(this.mdvMap.config.getZoomLevelIndex())+2) == null && this.mdvMap.config.getZoomLevel(parseInt(this.mdvMap.config.getZoomLevelIndex())+1) != null;

		var showStops = zoomLevel.get('showSTOP') == "true" && this.stops.visible ? 1 : 0;
		var showPOI = 0;
	
			showPOI   = zoomLevel.get('showPOI') == "true" && this.poi.visible ? 1 : 0;
		
		var poiArea = this.mdvMap.config.get('poiArea') =="true";
		var poiPoint = this.mdvMap.config.get('poiPoint')=="false";  		  		
		
		var vpReal = this.mdvMap.getViewportRealExtends();
		var radius = Math.floor(0.5 + Math.sqrt((Math.pow(vpReal.width/2, 2) 
			+ Math.pow(vpReal.height/2, 2))));

		var _params = { language: language, 
			coord: Math.floor(centre.x + 0.5) + ':' + Math.floor(centre.y + 0.5) + ':' + centre.mapName, 
			inclFilter: 1, purpose: '', max: -1, coordListFormat: 'STRING', addCoordInfo: 'NAPTAN',  language: 'en', itdLPxx_mdvMapName: 'mdvMap_' + this.mdvMap.getName(), coordListOutputFormat: 'STRING' };
		
		var ifilter = 1;
		
		if (showStops) {
			var temp = '';
			
			if (zoomLevel.get('showSTOP.majorMeans')) {
				temp = zoomLevel.get('showSTOP.majorMeans');
			}
			
			_params['type_' + ifilter] = 'STOP';
			_params['radius_' + ifilter] = radius;
			_params['inclDrawClasses_' + ifilter] = temp;
			
			ifilter++;

			if ((isLast || isOneBeforeLast) && !this.stopsOnly) {
				temp = '';
				
				_params['type_' + ifilter] = 'ENTRANCE';
				_params['radius_' + ifilter] = radius;
				_params['inclDrawClasses_' + ifilter] = temp;
				ifilter++;
				
				temp = '';

				_params['type_' + ifilter] = 'BUS_POINT';
				_params['radius_' + ifilter] = radius;
				_params['inclDrawClasses_' + ifilter] = temp;

				ifilter++;
			}
		}
		
		if (showPOI) {
			var temp = '';

			// All POI DrawClasses
			for (var ii=39; ii <= 80; ii++) {
				temp += ii + ':';
			}
			
			if(poiArea){
				temp ='';
				_params['type_' + ifilter] = 'POI_AREA';
				_params['radius_' + ifilter] = radius;
				_params['inclDrawClasses_' + ifilter] = temp;

				ifilter++;
			}
			
			if(!poiPoint){
				temp ='';
				_params['type_' + ifilter] = 'POI_POINT';
				_params['radius_' + ifilter] = radius;
				_params['inclDrawClasses_' + ifilter] = temp;

				ifilter++;
			}
			
			if (this.options && this.options.pools) {
				for (pl in this.options.pools) {
					_params['type_' + ifilter] = pl;
					_params['radius_' + ifilter] = radius;

					if (this.options.pools[pl].inclDrawClasses && this.options.pools[pl].inclDrawClasses.length > 0)
						_params['inclDrawClasses_' + ifilter] = this.options.pools[pl].inclDrawClasses;

					if (this.options.pools[pl].exclLayers && this.options.pools[pl].exclLayers.length > 0)
						_params['exclLayers_' + ifilter] = this.options.pools[pl].exclLayers;
					
					ifilter++;
				}
			}
		}
		
		//SMS Lookup 
		if(document.getElementById('itdLPxx_link') && document.getElementById('itdLPxx_link').value=='smslookup'){
			_params['filterRegionId'] = '2';
		}
		var _ajax = mdvLib.ajax({ host: host, parameters: _params, onComplete: MDVMapEFAInfoEx_onAjaxComplete });
	}
};

// route map functions 
MDVMapHelper.prototype.mapIt = function (id, type, line, coords) {
	if (this.mdvMapper == null)
		this.mdvMapper = new MDVMapObjectMapper(this);	

	this.mdvMapper.mapIt(id, type, line, coords);	
};

MDVMapHelper.prototype.unMapIt = function (dir, line, coord) {
	if (this.mdvMapper == null)
		this.mdvMapper = new MDVMapObjectMapper(this);	

	this.mdvMapper.unMapIt(dir, line, coord);	
};

function MDVMapObjectMapper(helper) {
	this.helper = helper;
	this.mdvMap = this.helper.mdvMap;
	this.routes  = [];
	
	this.animateLayer = null;
	
  	// Wizard
  	this.wizardJobID = null;
  	this.wizardIndex = null;
  	this.wizardScreenPlay = new Array();
	
	// new layer for routes dir H
	this.layer  = this.mdvMap.createLayer('routes_H');
	this.layer.setZIndex(3);
	this.mdvMap.addLayer(this.layer);
	
	// new layer for routes dir R
	this.layerR  = this.mdvMap.createLayer('routes_R');
	this.layerR.setZIndex(3);
	this.mdvMap.addLayer(this.layerR);
}

// add required line
MDVMapObjectMapper.prototype.mapIt = function (id, type, line, coords) {
	this.fetch(id, type, line, coords);	
	//this.updateWizard();
	this.animateLayer = this.mdvMap.getLayer('type')
};

// remove required line
MDVMapObjectMapper.prototype.unMapIt = function (dir, line, coord) {
	this.mdvMap.getLayer('routes_' + dir).removeAll()
};

MDVMapObjectMapper.prototype.launchWizardROP = function(zoomLevel) {
		this.launchWizard(zoomLevel);		
};

MDVMapObjectMapper.prototype.apply = function (item) {

	if (!item)
		return;
		
	var n = item.obj.firstChild;	
	
	while (n) {
		if (n.nodeType == 3) {
			n.nodeValue = 'Unmap it';
			break;
		}
			
		n = n.nextSibling;
	}
	
	var img = document.getElementById('img_' + item.obj.id);
	
	if (img) {
		img.src = item.image;
	}
};

// send ajax request for each line
MDVMapObjectMapper.prototype.fetch = function (id, type, line, coords) {
	var _param = { line: line, 
				hideBannerInfo: 1, 
				coordListOutputFormat: 'STRING', 
				filterEpsilon: '5.0',
				returnSinglePath: '1',
				itdLPxx_id: id,
				itdLPxx_type: type,
				itdLPxx_coords: coords	};
				
		_param = $H(_param);
		_param = _param.toQueryString();

	var _ajax = new Ajax.Request('../lite/XSLT_GEOOBJECT_REQUEST', { method: 'post', parameters: _param, onComplete: this.onRouteCallback.bind(this) });
};

MDVMapObjectMapper.prototype.onRouteCallback = function (request) {

	var json = request.responseText;
	var efa = null;
	
	eval('efa = ' + json + ';');
	
	if (!efa || !efa.geoObjects || 
		!efa.geoObjects.items || 		
		!efa.geoObjects.items.item.paths ||
		!efa.geoObjects.items.item.mode.diva)
			return;
			
	this.checkSize();
	
	var p = efa.parameters[0] || efa.parameters;
	var i=0;
	var id='';
	var coords = null;
	var dir = efa.geoObjects.items.item.mode.diva.direction;
	
	var routesLayer = this.layer;
	
	if(dir=='R'){
		routesLayer = this.layerR;
	}
	
	do {
		i++;
	 	if (p && p.name == 'coords') {
			coords = p.value;
		}
		if (p && p.name == 'id') {
			id = p.value;
		}
		
	} while (p = efa.parameters[i]);
	
	var mapItId = document.getElementById(id);

	
	var pointLength = Math.round(efa.geoObjects.items.item.points.length / 2);
	
	if (coords && coords!=':') {
		var c = coords.split(':');
		this.mdvMap.setCentre(new MDVCoordinates('NBWT', c[0], c[1]));
		this.mdvMap.update();
	}
	else if(efa.geoObjects.items.item.points[pointLength].ref.coords){
		var c = efa.geoObjects.items.item.points[pointLength].ref.coords.split(',');
		this.mdvMap.setCentre(new MDVCoordinates('TFLV', c[0], c[1]));
	
		this.mdvMap.update();
	}
	
	efa.geoObjects.items.item.mode.diva.toString = function () {		
		var branch = this.branch;
		
		if (branch < 10)
			branch = '0' + branch;

		var line = this.line;

		if (line < 10)
			line = '00' + line;
		else if (line < 100)
			line = '0' + line;
		
		return this.network + ':' + branch + line + 
			':' + this.supplement.replace(/\_/gi, ' ') + ':' + this.direction + ':' +
			this.project + '::0';
	};
	
	var color = '#939598';
	var img = '';
	
	var item = { obj: mapItId, color: color, image: img,
		line: efa.geoObjects.items.item.mode.diva.toString(), 
		polylines: [], stops: []
	}
	
	var path = efa.geoObjects.items.item.paths[0] || efa.geoObjects.items.item.paths.path;
	var i = 0;
	
	// add polyline
	do {
		i++;
		var p = this.mdvMap.createPolyline(path);
		
		var code = efa.geoObjects.items.item.mode.code;
		
		//Linecolor for route maps 
		if(dir=='H'){
			color = '#FF6600';
		}
		else{
			color = '#3B00FA';
		}
		
		p.add('colour', color);
		p.add('opacity', '0.8');
		routesLayer.addPolyline(p, efa.geoObjects.items.item.paths[i]==null);
		if (item)
			item.polylines.push(p);
		
	} while (path = efa.geoObjects.items.item.paths[i]);
	
	i = 0;
	
	var coordList = { x: [], y: [] };
	
	this.beautify(efa.geoObjects.items.item);
	this.animateLayer = routesLayer;
	this.mdvMap.update(); 
	this.updateWizard();
	
	var stop = efa.geoObjects.items.item.points[0] || efa.geoObjects.items.item.points;	

	i = 0;
	
	// add stops
	do {
		i++;
		
		var cs     		= stop.ref.coords.split(',');
		var stopName    = stop.name;
		var coords 		= new MDVCoordinates('TFLV', cs[0], cs[1]);
		var marker 		= null;
		
		if (coords.x > 0 && coords.y > 0) {
		
			var mot = efa.geoObjects.items.item.mode.code;
			
			if(efa.geoObjects.items.item.mode.diva && efa.geoObjects.items.item.mode.diva.network!='tfl' && efa.geoObjects.items.item.mode.code==4)
			{
				mot = '4_2';
			}

			marker = this.mdvMap.createMarker(coords, new MDVPoint(0.5, 0.5), this.getIcon(mot));
		 
			// set marker on line 
			var tt = this.mdvMap.createToolTip('<b>' + stopName + '</b>');
			tt.stop = stop;
			marker.setToolTip(tt); 
			routesLayer.addMarker(marker, efa.geoObjects.items.item.points[i]==null);
		}		

		if (marker)
			item.stops.push(marker);
		
		stop = efa.geoObjects.items.item.points[i];
	} while (stop);  
	
	this.apply(item);
	this.routes.push(item);
	
};

// this funciton get the right mot icon 
MDVMapObjectMapper.prototype.getIcon = function (mot) {
	var ext = 'pointi';
	return 'images/map/' + ext + '.gif';
};

MDVMapObjectMapper.prototype.checkSize = function() {
	if (this.routes.length >= 3) {
		var trash = this.routes.shift();
		this.remove(trash);
	}
};

MDVMapObjectMapper.prototype.beautify = function (item) {

	var coords = this.mdvMap.getPolylineCoords();
	var x = coords[0];
	var y = coords[1];
	
	x.sort(MDVMap_NumSort);
	y.sort(MDVMap_NumSort);
	
	var width  = x[x.length-1] - x[0];
	var height = y[y.length-1] - y[0];
	var newX   = parseInt(x[0]) + Math.floor(0.5 + width/2);
	var newY   = parseInt(y[0]) + Math.floor(0.5 + height/2);     	
	
	var centre = new MDVCoordinates(this.mdvMap.config.get('mapName'),
		newX, newY);
		
	var zoom = 0;
	var extd = this.mdvMap.getViewportExtends();
	
	var zls = this.mdvMap.config.getZoomLevels();
	for (var i=zls.length-1; i >= 0; i--) {
		var zl = zls[i];
		var bWidth = false;
		var bHeight = false;
		
		var vpTiles = new MDVPoint(extd.width / parseInt(zl.get('tileSizeX')),
			extd.height / parseInt(zl.get('tileSizeY')));
		
		var numTiles = new MDVPoint(zl.get('numberOfTilesX'), zl.get('numberOfTilesY'));
		var realExtends = new MDVPoint(zl.get('realWidth'), zl.get('realHeight'));
		
		var tileSize = new MDVPoint(Math.floor(0.5 + realExtends.x / numTiles.x),
			Math.floor(0.5 + realExtends.y / numTiles.y));
			
		var real = new MDVPoint(tileSize.x * vpTiles.x, tileSize.y * vpTiles.y);    		
		
		if (real.x > (width*1.15) && !bWidth) {
			zoom = i;
			bWidth = true;
		}		

		if (real.y > (height*1.15) && !bHeight) {
			zoom = i;
			bHeight = true;
		}
		
		if (bWidth && bHeight)
			break;
	}

	this.mdvMap.setCentre(centre);
	this.mdvMap.setZoomLevel(zoom);
};

 MDVMapObjectMapper.prototype.launchWizard = function (zoomLevel) {
	mdvTimer.remove(this.wizardJobID);
	
	this.mdvMap.stepPx = 4;
	this.mdvMap.stepTime = 40;
	this.mdvMap.cancelMoveBySeq();
	this.wizardJobID = null;
	
	var zl = this.mdvMap.config.getZoomLevel(zoomLevel);
	if (zl) {
		if (zl.get('trace.step.px'))
			this.mdvMap.stepPx = parseInt(zl.get('trace.step.px'));
		if (zl.get('trace.step.time'))
			this.mdvMap.stepTime = parseInt(zl.get('trace.step.time'));
	}

  	if (this.animateLayer.polylines.length > 0) {
		if (zoomLevel >= 0)
	  		this.animateLayer.mdvMap.setZoomLevel(zoomLevel);
  		this.mdvMap.setCentre(this.animateLayer.polylines[0].getAllCoords()[0].clone());
  		this.mdvMap.update();
  	} 	
  	
	this.wizardIndex = 0;
  	this.wizardJobID = mdvTimer.add(1, this, this.wizardRun, [null, null, null]);
  };
  
  MDVMapObjectMapper.prototype.wizardRun = function(id, msg, obj) {  	
  
  	var _sp = this.wizardScreenPlay[this.wizardIndex];
  	this.wizardIndex++; 
  	
  	if (id == MDVEvent_ROUTE_TRACE_FINISHED || !_sp.object.getAllCoords())
  		this.mdvMap.events.deregisterEvent(MDVEvent_ROUTE_TRACE_FINISHED, this, this.wizardRun);
  	
	if(!_sp.object.getAllCoords()){
		return;
	}
	
  	if (_sp) {  	
  		switch (_sp.type) {
  			case 'marker':
  				if (_sp.state)
					_sp.object.toolTip.display();
				else
					_sp.object.toolTip.hide();

				this.wizardJobID = mdvTimer.add(_sp.timeout, this, this.wizardRun, [null, null, null]);
  			break;
  			default:  				
  				this.mdvMap.events.registerEvent(MDVEvent_ROUTE_TRACE_FINISHED, this, this.wizardRun);
  				var coords = _sp.object.getAllCoords();
  				var mrkr = null;

				if (_sp.object && _sp.object.isInterchange)
					mrkr = _sp.object.layer.markers[0].imgSrc;
  				this.wizardJobID = mdvTimer.add(_sp.timeout, this, this.wizardMoveBySeq, [coords, mrkr]);
  			break;
  		}

  	}  	
  };
  
MDVMapObjectMapper.prototype.wizardMoveBySeq = function (coords, marker) {
  	this.mdvMap.moveBySeq(coords, marker);
};
  
  
MDVMapObjectMapper.prototype.updateWizard = function () {
  	var _polyline = this.animateLayer.polylines[0];

	// Delete elements....
  	for (var sp=this.wizardScreenPlay.length; sp > 0; sp--)
  		this.wizardScreenPlay.pop();

	this.wizardScreenPlay.push({ object: _polyline, type: 'polyline', state: true, timeout: 10 });
  	
  	return true;
  };
  
  
function blockMouseWheel(obj){
	obj.style.display='none';
	mdvJpMaps[mapType].mdvMap.config.params.omitMouseWheel = 'false';
}

MDVMapNavigator.prototype.onmousewheel = function(e) {
	e = e ? e : window.event;
	
	if (this.mdvMap.config.get('omitMouseWheel') && this.mdvMap.config.get('omitMouseWheel') == 'true') {
		this.stopEvent(e);
		
		if(document.getElementById('blockMouseWheel')){
			document.getElementById('blockMouseWheel').style.display='block';
		}
		else if(document.getElementById('blockMouseWheel_' + this.mdvMap.name.substring(9))){
			document.getElementById('blockMouseWheel_' + this.mdvMap.name.substring(9)).style.display='block';
		}
		
		return false;
	}

	var ua = navigator.userAgent;
	var centreOnMouseWheel = null;
	var hotspotOnMouseWheel = null;

	// If 'centreOnMouseWheel' or 'hotspotOnMouseWheel' is active populate centreOnMouseWheel.
	if (this.mdvMap.config.get('centreOnMouseWheel') && this.mdvMap.config.get('centreOnMouseWheel') == 'true')
		centreOnMouseWheel = this.mwHotSpot;
	else if (this.mdvMap.config.get('hotspotOnMouseWheel') && this.mdvMap.config.get('hotspotOnMouseWheel') == 'true')
		hotspotOnMouseWheel = this.mwHotSpot;

  	var wheelDelta = e.wheelDelta ? e.wheelDelta : e.detail*-1;
	
  	if (ua.indexOf('Opera') >= 0)
  		wheelDelta *= -1;

  	if (wheelDelta > 0) {
  		var zoomLevel = this.mdvMap.config.getZoomLevel(this.mdvMap.config.getZoomLevelIndex()+1);
  		if (zoomLevel != null) {
  			var nc = this.mdvMap.getCentre();
  			
			// If new centre is not null apply it to the map
  			if (centreOnMouseWheel)
  				this.mdvMap.setCentre(centreOnMouseWheel);
  			else if(hotspotOnMouseWheel) {
  				nc = this.getNewHotspotCentre(hotspotOnMouseWheel, this.mdvMap.config.getZoomLevelIndex()+1);
  			}

	  		centreOnMouseWheel = null;
	  		hotspotOnMouseWheel = null;

	  		if (this.mdvMap.config.get('useMagnifyGlass') && this.mdvMap.config.get('useMagnifyGlass') == 'true') {
		  		this.mdvMap.magnify(this.mdvMap.config.getZoomLevelIndex()+1, nc);
		  		this.mdvMap.switchMapper();
	  		} else {
		  		this.mdvMap.setZoomLevel(this.mdvMap.config.getZoomLevelIndex()+1);
		  		this.mdvMap.setCentre(nc);
	  			this.mdvMap.update();
	  		}
  		}
  	}
  	else {
  		var zoomLevel = this.mdvMap.config.getZoomLevel(this.mdvMap.config.getZoomLevelIndex()-1);
  		if (zoomLevel != null) {
  			var nc = this.mdvMap.getCentre();

  			if(hotspotOnMouseWheel && !centreOnMouseWheel) {
  				nc = this.getNewHotspotCentre(hotspotOnMouseWheel, this.mdvMap.config.getZoomLevelIndex()-1);
  			}

	  		centreOnMouseWheel = null;
	  		hotspotOnMouseWheel = null;

	  		if (this.mdvMap.config.get('useMagnifyGlass') && this.mdvMap.config.get('useMagnifyGlass') == 'true') {
		  		this.mdvMap.magnify(this.mdvMap.config.getZoomLevelIndex()-1, nc);
		  		this.mdvMap.switchMapper();
	  		} else {
		  		this.mdvMap.setZoomLevel(this.mdvMap.config.getZoomLevelIndex()-1);
  				this.mdvMap.setCentre(nc);		  		
	  			this.mdvMap.update();
	  		}
  		}
  	}

   	this.stopEvent(e);
   	return false;
  };
  
 MDVMapEFAInfoEx.prototype.trigger = function () {
	// Pre-fetch Images
  	var ipath = 'images/';
  	if (this.mdvMap.config.get('imagePath'))
  		ipath = this.mdvMap.config.get('imagePath');
  		
  	if (this.options['imagePath'])
  		ipath = this.options['imagePath'];

	if (!this.imgsLoaded) {
	  	this.stopImg.src = ipath + 'stop.gif';
	  	this.mot1Img.src = ipath + 'mot1.gif';
	  	this.mot2Img.src = ipath + 'mot2.gif';
	  	this.mot3Img.src = ipath + 'mot3.gif';
	  	this.mot4Img.src = ipath + 'mot4.gif';
	  	this.mot5Img.src = ipath + 'mot5.gif';
	  	this.mot6Img.src = ipath + 'mot6.gif';
	  	this.mot7Img.src = ipath + 'mot7.gif';
	  	this.mot8Img.src = ipath + 'mot8.gif';
	  	this.mot9Img.src = ipath + 'mot9.gif';
	  	this.mot10Img.src = ipath + 'mot10.gif';
	  	this.mot11Img.src = ipath + 'mot11.gif';
	  	this.mot12Img.src = ipath + 'mot12.gif';
	  	this.poiImg.src = ipath + 'pin.gif'
	  	this.entranceImg.src =  ipath + 'entrance.gif';
	  	this.pointImg.src =  ipath + 'point.gif';
	  	
	  	if (this.mdvMap.config.get('info.stop.only') && this.mdvMap.config.get('info.stop.only') == 'true')
	  		this.stopsOnly = true;
	  	
	  	this.imgsLoaded = true;
	}

	if (this.id) {
		// Clear job ID
		mdvTimer.remove(this.id); this.id = null;  			
	}
	
	// TODO: Probably we should store the timeout value in config.
	this.id = mdvTimer.add(700, this, this.execute, []);
  };


MDVMapEFATrips.prototype.processTrip = function(id, gName, efa) {

  	if (gName != 'MDVMapEFATrips') {
  		return false;
  	}
  		
  	var hostUrl, _params, createPath, process, alignment = 0.5, leg = null;
  		
  	if (this.options['alignment']) {
	  	alignment = this.options['alignment'];
  	}
  		
 	this.response = efa;
  	this.clear();
	
	createPath = function(mode) {
		var l = 0, tripIsArr;
		var _response = mode === 'lite' ? this.response : this.responseJson;
		
		while (leg) {
			
			// JSON result does not contain points and mode info
			// so borrow it from the lite request
			if (mode === 'json') {
				tripIsArr = mdvLib.typeOf(this.response.trips.trip.legs) === 'array';
				leg.points = tripIsArr ? this.response.trips.trip.legs[l].points : this.response.trips.trip.legs.leg.points;
				leg.mode = tripIsArr ? this.response.trips.trip.legs[l].mode : this.response.trips.trip.legs.leg.mode;
			}
			
			var type = leg.mode.type;
			var points = leg.points;				
			var colour = this.getLegColour(type);
			var opacity = '0.5';
			var weight = 3;
			var p = null;
			
			if(leg.mode.diva && leg.mode.diva.network!='tfl' && leg.mode.code==4)
			{
				type = '4_2';
			}
			
			var list = this.getReductionList(leg);
			list.sort(MDVMapEFATrips_ScaleSort);
			
			if (this.mdvMap.config.get('trips.polyline.opacity'))
				opacity = this.mdvMap.config.get('trips.polyline.opacity');
	
			if (this.mdvMap.config.get('trips.polyline.weight'))
				weight = this.mdvMap.config.get('trips.polyline.weight');
			
			// partial route info contains no path description
			if (!leg.path) {
				// do we have turn instructions? If so use these...
				if (leg.turnInst && leg.turnInst.length > 0) {
					
					var  pathStr = '';
					
					for(var i=0; i<leg.turnInst.length; i++) {
						for (var p in leg.turnInst[i]) {
							if(p==='coords') {
								pathStr += leg.turnInst[i][p] + ' ';
							}	
						}
					} 
					// remove trailing blank 
					pathStr = pathStr.substring(0, pathStr.length-1);	
				
				// ... if not, draw a direct line from point to point. 
				} else {
					
					var  pathStr = '';
					
					for(var i=0; i<leg.points.length; i++) {
						if (leg.points[i].ref) {
							for (var p in leg.points[i].ref) {
								if(p==='coords') {
									pathStr += leg.points[i].ref[p] + ' ';
								}	
							}
						}
					} 
					pathStr = pathStr.substring(0, pathStr.length-1);
				}
			} else {
			// we got a path description	
				var pathStr = leg.path.replace(/\.00000/gi, '');
			}		
			
			if (list.length > 0) {
				p = this.mdvMap.createPolyline(pathStr, { reductionList: list });
				this.polylines.push(p);
			} else {
				p = this.mdvMap.createPolyline(pathStr);
				this.polylines.push(p);
			}
			
			p.add('colour', colour);
			p.add('opacity', opacity);
			p.add('weight', weight);
		
			if (!p.markers['departure']) {
				var coords = p.getAllCoords();
				var m = this.getMarker(type, 'departure', coords[0], alignment, l);
					
				p.markers['departure'] = m;
				p.markers['departure'].mode  = type;
				p.markers['departure'].point = points[0];
			}
	
			if (!p.markers['arrival']) {
				var coords = p.getAllCoords();
				var m = this.getMarker(type, 'arrival', coords[coords.length-1], alignment, l);
					
				p.markers['arrival'] = m;
				p.markers['arrival'].mode  = type;
				p.markers['arrival'].point = points[1];
			}
			
			p.leg = leg;
			this.layer.addPolyline(p, false);
			
			// Check for interchange
			if (leg.interchange) {
				
				var next = _response.trips.trip.legs[(l+1)];
				
				// if the mode is json, fetch next points from lite response
				var nextPoints = mode === 'lite' ? next.points : this.response.trips.trip.legs[l+1].points;
				
				var ic = this.mdvMap.createPolyline(leg.interchange.path);
					colour = this.getLegColour(99);
					ic.add('colour', colour);
					ic.add('opacity', opacity);
					ic.add('weight', weight);
					ic.leg = leg;
					ic.isInterchange = true;
			
				var m = this.getMarker(99, 'departure', coords[coords.length-1], alignment, l);
					ic.markers['departure'] 		= m;
					ic.markers['departure'].mode 	= 99;
					ic.markers['departure'].point	= points[1];
	
				var nextCoords = next.path.split(' ');
					nextCoords = nextCoords[0].split(',');
						
				var c = new MDVCoordinates(coords[coords.length-1].mapName, nextCoords[0], nextCoords[1]);
					m = this.getMarker(99, 'arrival', c, alignment, l);
					ic.markers['arrival'] 			= m;
					ic.markers['arrival'].mode  	= 99;
					ic.markers['arrival'].point 	= nextPoints[0];
				
				this.layer.addPolyline(ic, false);
				this.polylines.push(ic);
			}
			
			l++; leg = _response.trips.trip.legs[l];
		}
		
	}.bind(this);
	
	
	process = function(mode) {
		createPath(mode);
		if (this.doBeautify) {
			this.beautify();
		}
		this.processMarkers();
		this.mdvMap.update();
		this.processPolylines();
	
	}.bind(this);
	
	// path description via lite request
	if (this.mdvMap.config.get('trips.useJsonForPath') !== 'true') {
		if (this.response.trips.trip.legs.leg && !this.response.trips.trip.legs.length) {
			leg = this.response.trips.trip.legs.leg;
		} else if (this.response.trips.trip.legs.length) {
			leg = this.response.trips.trip.legs[0];
		}
		process('lite');
		//we're done here.
		return true; 
	}
	
	hostUrl = /^\/(?:[\w\-%]+\/)*(\w+)\??/.exec(window.location.pathname);
	hostUrl = hostUrl && hostUrl[1];
	
	_params = {
		sessionID: this.tripParams.sessionId,
		requestID: this.tripParams.requestId,
		coordOutputFormatTail: '0',
		command: 'tripCoordSeq:' + this.tripParams.tripIndex,
		filterEpsilon: this.tripParams.reductionList,
		output: 'JSON'
	}; 

	if (typeof hostUrl === 'string') {	
		
		mdvLib.ajax({ 
			host: hostUrl, 
			parameters: _params, 
			onComplete: function(r) { 
				
				var _response = r.responseText || r;
				_response = _response.replace(/\.00000/gi, '');
				eval('this.responseJson = ' + _response + ';');
				//invalid JSON?
				if (!this.responseJson) {
					return false;
				}
				if (this.responseJson.trips.trip.legs.leg && !this.responseJson.trips.trip.legs.length) {
					leg = this.responseJson.trips.trip.legs.leg;
				} else if (this.responseJson.trips.trip.legs.length) {
					leg = this.responseJson.trips.trip.legs[0];
				}
				
				process('json'); 
			
			}.bind(this)
		});
	} else {
	}
  };
  
  
//overwrite the mdvMap.js layer update
 MDVLayer.prototype.update = function() {
	for (var m=0; m < this.markers.length; m++) {
		if (this.name != 'efa_trip')
			this.markers[m].setVisibility(this.visible);
		this.markers[m].update();
	}

	if(this.mdvMap.renderer && this.name === 'efa_trip' || this.name=='routes_R' || this.name=='routes_H'){
	
		if (this.mdvMap.renderer && this.polylines.length > 0)
			this.mdvMap.renderer.update();
			
		for (var p=0; p < this.polylines.length; p++) {
			if (this.polylines[p] && this.polylines[p].append)
				this.mdvMap.renderer.removePolyline(this.polylines[p]);
			this.mdvMap.renderer.drawPolyline(this.polylines[p]);
		}
	}
	  	
	this.mdvMap.events.triggerEvent(MDVEvent_LAYER_UPDATED, 'MDVMap has updated layer (' + this.name + ')', this);
};  
  
 function MDVVMLRenderer(mdvMap, container) {
	this.mdvMap 	= mdvMap;
	this.container 		= container; 
	this.max			= null;
	this.min			= null;
	this.border			= 50;
	this.offset			= new MDVPoint(0, 0);
	this.boundingBox	= null;
	this.group			= null;
	
	document.namespaces.add("v", "urn:schemas-microsoft-com:vml");     	
	var style = document.createStyleSheet();

	style.addRule('v\\: *', "behavior: url(#default#VML);");
	style.addRule('v\\:shape', "behavior: url(#default#VML);");
	style.addRule('v\\:stroke', "behavior: url(#default#VML);");
	
	this.group = document.createElement('v:group');
	this.container.appendChild(this.group);
	
	// Inherit from MDVRenderer
	for (var method in MDVRenderer.prototype) {

	if (!MDVVMLRenderer.prototype[method])
	  MDVVMLRenderer.prototype[method] = MDVRenderer.prototype[method];
	}
  }
  
  MDVVMLRenderer.prototype.drawPolyline = function (polyline) {
	if (!polyline)
		return false;
		
	var pathStr = 'm';
	var coords = polyline.getAllCoords();
	for (var i=0; i < coords.length; i++) {      			
		var point = this.mdvMap.getPoint(coords[i]);					
		
		var x = point.x - this.offset.x;
		var y = point.y - this.offset.y;
		
		pathStr += x + ',' + y;

		if (i < coords.length-1)
			pathStr += ' ';
		if (i == 0)
			pathStr += 'l';
	}
	pathStr += ' e'; 
	
	var width  = this.boundingBox[1].x - this.boundingBox[0].x;
	var height = this.boundingBox[1].y - this.boundingBox[0].y;
	var left = this.boundingBox[0].x;
	var top  = this.boundingBox[0].y;
	
	var colour = polyline.get('colour');
	if (!colour)
		colour = 'red';

	var weight = polyline.get('weight');
	if (!weight)
		weight = '4px';
		
	var opacity = polyline.get('opacity');
	if (!opacity)
		opacity = '0.5';
		
	if (!polyline.append) {
		
		var shape = document.createElement("v:shape");
			shape.style.position = 'relative';
			shape.style.top = '0px';
			shape.style.left = '0px';
			shape.style.width = width;
			shape.style.height = height;
			
			shape.setAttribute('filled', 'false');
			shape.setAttribute('stroked', 'true');
			shape.setAttribute('strokecolor', colour);
			shape.setAttribute('strokeweight', weight);
			shape.setAttribute('path', pathStr);
			
		var stroke = document.createElement("v:stroke");
			stroke.setAttribute('opacity', opacity);
			stroke.setAttribute('joinstyle', 'round');
			stroke.setAttribute('endcap', 'round');
			
			shape.appendChild(stroke);	      		
		this.group.appendChild(shape);
		shape.parentPolyline = polyline;
		polyline.element = shape;
		polyline.element.mdvMap = this.mdvMap;
		polyline.append = true;
		
	} else if (polyline.element.path.value != pathStr) {
		polyline.element.path.value = pathStr;
	}
	
	if (polyline.toolTip)
		polyline.setToolTip(polyline.toolTip);
	
	return true;
  };
  
 MDVVMLRenderer.prototype.removePolyline = function (polyline) {
	if (!polyline || !polyline.append || polyline.element == null)
		return false;

		this.group.removeChild(polyline.element);
		polyline.element.onmousedown = null;
		polyline.element.onmousemove = null;
		polyline.element.onmouseout = null;
		polyline.element.onmouseover = null;
		polyline.element.onmouseup = null;

		if (polyline.element.toolTip)
			polyline.element.toolTip = null;

		if (polyline.element.mdvMap)
			polyline.element.mdvMap = null;

		polyline.element = null;
		polyline.append = false;
	
	return true;
 };
  
  MDVVMLRenderer.prototype.setBoundingBox = function () {
		var width  = this.boundingBox[1].x - this.boundingBox[0].x;
		var height = this.boundingBox[1].y - this.boundingBox[0].y;
		
		var left = this.boundingBox[0].x;
		var top  = this.boundingBox[0].y;
	
		this.offset = new MDVPoint(left, top);
		
		this.group.style.behavior = 'url(#default#VML)';
		this.group.style.width  = width + 'px';
		this.group.style.height = height + 'px';
		this.group.style.position = 'absolute'
		this.group.style.left = left + 'px';
		this.group.style.top = top + 'px';
		this.group.setAttribute('coordsize', width + ',' + height);
		this.group.coordsize.value = width + ',' + height;
	
		return true;			
  };
  
  
  MDVLayer.prototype.addMarker = function(marker) {
  		var update = true;
	  	for (var m=0; m < this.markers.length; m++) {
	  		if (this.markers[m].id == marker.id) {
	  			return false;
	  		}
	  	}
	  	
	  	if (arguments.length == 2)
		{
	  		update = arguments[1];
		}
		
	  	marker.layer = this;

		this.markers.push(marker);		
		marker.img.src = marker.imgSrc;

		return true;
  };
  
/* overwritte the existing function - > FF3 issue */
MDVToolTipContainer.prototype.init = function () {
	var that = this;
	this.div = document.createElement('div');
	this.div.style.zIndex = 100;
	this.div.style.position = 'absolute';
	this.div.style.top = '0px';
	this.div.style.left = '0px';
	this.div.toolTip = null;
	
	if (!this.isAppend()) {
		this.mdvMap.markerObjects.appendChild(this.div);
		this.setAppend(true);
	}
	
	this.div.onmouseover = MDVToolTipContainer_cancelHide;
	this.div.onmousemove = MDVToolTipContainer_cancelHide;
	this.div.onmouseout  = function() {
							  //if no onClick handler is assigned, close TT after short delay
							  if (!that.mdvMap.config.get('tooltipHandler')) {
								MDVToolTipContainer_triggerHide.bind(this)();
							  }	
							};
	this.div.onmousedown = MDVToolTipContainer_onMouseDown;
	this.div.ondblclick = MDVToolTipContainer_onMouseDown;

	this.setVisibility(false);
	
	return this.div != null;
};
 
MDVToolTip.prototype.display = function () {
	if (this.isDisabled())
		return false;
		
	// Hide all tool tips first
	if (this.mdvMap)
		this.mdvMap.hideToolTips();
	
	// Check whether we need to require a container first
	if (!this.getContainer())
		this.require();
		
	// ...did it work?
	if (!this.getContainer())
		return false;
		
	//var update = this.update();
	this.getContainer().setInnerHTML(this.getInnerHTML());
	this.setVisibility(true);
	
	this.mdvMap.events.triggerEvent(MDVEvent_TOOLTIP, 'MDVMap Tool Tip...', this);
	var update = this.update();
	return update;
};
  
 
//departure board
function MDVEFADepartureMonitor(id, url) {
    this.id 	= id;
    this.url 	= url;
}

// request departures (AJAX)
MDVEFADepartureMonitor.prototype.getDepartures = function(identifier) {

	var stopID = this.id

	if(isNaN(stopID) && stopID.indexOf('|')!='-1'){
		stopID = stopID.substring(0,stopID.indexOf('|'));
	}

	var _params = { 
		language: mapLanguage, 
		name_dm: stopID, 
		type_dm: 'stopID', 
		mode: 'direct', 
        limit: '10',
	    limitEachStop: '1', 
	    itdLPxx_id: identifier , 
		itdLPxx_page: 'tooltip', 
		deleteAssignedStops_dm:'1'
		};
		
		if(mdvJpMaps[mapType].mdvMap.config.getZoomLevelIndex() > 6){
			_params['nameArea_dm']= identifier.split('|')[1];
			_params['nameKey_dm']=identifier.split('|')[2];
			_params['plSpec_dm']='1';
		}
						
    var _ajax = mdvLib.ajax({ host: this.url, parameters: _params, 
                                  onComplete: MDVEFADepartureMonitor_onAjaxComplete.bind(this) });
}

// get the HTML code for departure monitor
function MDVEFADepartureMonitor_onAjaxComplete(request) {

    if (request.responseText) {
		var target = document.getElementById('dm_'+ this.id);
		target.innerHTML = request.responseText;
     }
}