//Declare global variables  
var geocoder = null;
var proximity = null;
var router = null;
var routePoints = [];
var routeID = null;
var radius = (typeof map24Radius != 'undefined') ? map24Radius : 25000;
var startPointAlternatives = new Array();
var destinationPointAlternatives = new Array();
var helicopter = false;
var threeD = 0;
var map = null;
var conn = null;
var locConn = null;
var lbsAddress = null;
var lbsLongitude = null;
var lbsLatitude = null;
var debugMap24 = false;
var crResults = null;

function initMap24() {
	Map24.loadApi( ["core_api", "wrapper_api"] , map24ApiLoaded );
}

function map24ApiLoaded(){
	if (debugMap24) {
		Map24.Debug.LogToFirefoxConsole = true;
		Map24.Debug.enable(true, Map24.E_ALL);
	}
	if (document.location.href.indexOf('popup_view') == -1) {
		// no popup
		Map24.MapApplication.init({NodeName: "maparea", MapType: "Static"});
		if (jq('#servicemode').val() == 'lbs') {
			// Location Based Search
			map = new Map24.Map();
	    	//Open a connection to the Web services.
	    	conn = map.WebServices.openConnection();
	    	//Open a local connection.
	    	locConn = map.Local.openConnection();
		}
	} else {
		// popup window
		try {
			if (dv == false) {
				if (map_type=='2') {
					// static map
					Map24.MapApplication.init({NodeName: "maparea", MapType: "Static"});
				} else {
					// interactive java map
					Map24.MapApplication.init({NodeName: "maparea", MapType: "Applet"});
				}
			} else {
				map = new Map24.Map()
				map.addCanvas( new Map24.Canvas( { NodeName: "maparea" } ), "c" );
				if (map_type=='2') {
					// static map
					map.addMapClient( new Map24.MapClient.Static(), "mapclient" );
				} else {
					// interactive java map
					map.addMapClient( new Map24.MapClient.Applet(), "mapclient" );
				}
				map.show( "mapclient", "c" ); 
		    	//Open a connection to the Web services.
		    	conn = map.WebServices.openConnection();
		    	//Open a local connection.
		    	locConn = map.Local.openConnection();
		}
		} catch(e) { alert(e); }
		// should we start route calculation?
		if (dv==false) {
	    	popupRoutePreparation();
		} else {
			try {
				getLocationDescription();
			} catch (e) { alert(e); }
			centerOnDetailLocation();
		}
	}
}

// register the initMap24 function
if (typeof addDOMLoadEvent != 'undefined') {
	addDOMLoadEvent(initMap24);
}

function checkRPInput(form_obj) {
    //Retrieve start and destination of the route from the input fields
    var start = Map24.trim( jq('#departure').val() );
    var destination = Map24.trim( jq('#destination').val() );
    
	if (start=="" || destination=="") {
		// we have to display the error div - using prototype!
		jq('#routeplannerform1_error').show();
		return false;
	}
	// we have to hide the error message (if it is displayed)
	jq('#routeplannerform1_error').hide();
	
	//Initialize the array for storing route points
    routePoints = {};
    //Create a geocoder stub
    if( geocoder == null ) geocoder = new Map24.GeocoderServiceStub();
        
	//Geocode the start address of the route
    geocoder.geocode({
      SearchText: start,
      //Define a maximum number of geocoding results to limit
      //the number of entries that will be shown in the result lists
      MaxNoOfAlternatives: 5,
      CallbackFunction: selectRPDepartureAndDestination,
      CallbackParameters: {position: "start"}
    });
    
    //Geocode the destination address of the route.
    geocoder.geocode({
      SearchText: destination,
      MaxNoOfAlternatives: 5,
      CallbackFunction: selectRPDepartureAndDestination,
      CallbackParameters: {position: "destination"}
    });
    
	return false;
}

function selectRPDepartureAndDestination(locs, params) {
	//Declare local variables
    var country = null;
    var city = null;
    var zip = null;
    var street = null;
    var houseNo = null;
    var state = null;
    var result = "";

    //Iterate through the array of geocoded addresses
    for( var i=0; i<locs.length; i++ ){
		//Access the fields of the geocoded address
		country = locs[i].getCountry();
		city = locs[i].getCity();
		zip = locs[i].getZip();
		street = locs[i].getStreet();
		houseNo = locs[i].getHouseNo();
		state = locs[i].getState();
		longitude = locs[i].getLongitude();
		latitude = locs[i].getLatitude();
		
		//If an address field is null, it is not shown in the result list.
		//Otherwise, the field's value is shown together with the category,
		//e.g. "City: Frankfurt".
		city == null? city = "": city = city;
		zip == null? zip = "": zip = " ("+zip+")";
		street == null? street = "": street = ", "+street;
		houseNo == null? houseNo = "": houseNo = " "+houseNo;
		country == null? country = "": country = country + " - ";
		state == null? state = "": state = state+": ";
		address = country+state+city+zip+street+houseNo;
		
		//Add the geocoded address to the result list
		result +='<option value="'+longitude+'|'+latitude+'|'+address+'">'+address+"</option>";
   	}

   	//Print alternative geocoded addresses for the start point in a list
   	if (params.position=="start"){
    	//Store alternatives for start point in an arrayStreet, City, ...
      	for( var i=0; i<locs.length; i++ ){
        	startPointAlternatives[i] = locs[i];
      	}

      	//Show geocoded alternatives for the start point in a list
      	jq('#departure_select').html(result);
    } else {
    	//Store alternatives for destination point in an array
      	for( var i=0; i<locs.length; i++ ){
        	destinationPointAlternatives[i] = locs[i];
      	}
      	//Show geocoded alternatives for the destination point in a list
      	jq('#destination_select').html(result);
    }
    // check if both departure and destination has got results
    if (startPointAlternatives.length > 0 && destinationPointAlternatives.length > 0) {
		// hide first form, show second
		jq('#routeplannerform1').hide();
		jq('#routeplannerform2').show();
    }
}

function checkLocationRPInput(form_obj) {
    //Retrieve departure of the route from the input field
    var start = Map24.trim( jq('#departure').val() );
    
    if (start=="") {
        // we have to display the error div - using prototype!
        jq('#routeplannerform1_error').show();
        return false;
    }
    // we have to hide the error message (if it is displayed)
    jq('#routeplannerform1_error').hide();
    
    //Initialize the array for storing route points
    routePoints = {};
    //Create a geocoder stub
    if( geocoder == null ) geocoder = new Map24.GeocoderServiceStub();
        
    //Geocode the departure address of the route
    geocoder.geocode({
      SearchText: start,
      //Define a maximum number of geocoding results to limit
      //the number of entries that will be shown in the result lists
      MaxNoOfAlternatives: 5,
      CallbackFunction: selectLocationRPDeparture,
      CallbackParameters: {position: "start"}
    });
    
    return false;
}

function selectLocationRPDeparture(locs, params) {
    //Declare local variables
    var country = null;
    var city = null;
    var zip = null;
    var street = null;
    var houseNo = null;
    var state = null;
    var result = "";

    //Iterate through the array of geocoded addresses
    for( var i=0; i<locs.length; i++ ){
        //Access the fields of the geocoded address
        country = locs[i].getCountry();
        city = locs[i].getCity();
        zip = locs[i].getZip();
        street = locs[i].getStreet();
        houseNo = locs[i].getHouseNo();
        state = locs[i].getState();
        longitude = locs[i].getLongitude();
        latitude = locs[i].getLatitude();
        
        //If an address field is null, it is not shown in the result list.
        //Otherwise, the field's value is shown together with the category,
        //e.g. "City: Frankfurt".
        city == null? city = "": city = city;
        zip == null? zip = "": zip = " ("+zip+")";
        street == null? street = "": street = ", "+street;
        houseNo == null? houseNo = "": houseNo = " "+houseNo;
        country == null? country = "": country = country + " - ";
        state == null? state = "": state = state+": ";
        address = country+state+city+zip+street+houseNo;
        
        //Add the geocoded address to the result list
        result +='<option value="'+longitude+'|'+latitude+'|'+address+'">'+address+"</option>";
    }

    //Print alternative geocoded addresses for the departure point in a list
    //Store alternatives for start point in an array
    for( var i=0; i<locs.length; i++ ){
        startPointAlternatives[i] = locs[i];
    }

    //Show geocoded alternatives for the start point in a list
    jq('#departure_select').html(result);

    // check if departure has got results
    if (startPointAlternatives.length > 0) {
        // hide first form, show second
        jq('#routeplannerform1').hide();
        jq('#routeplannerform2').show();
    }
}

function checkLBSInput(form_obj) {
    //Retrieve departure of the lbs from the input field
    var departure = Map24.trim( jq('#departure').val() );
	if (departure=="") {
		// we have to display the error div - using prototype!
		jq('#lbsform1_error').show();
		return false;
	}
	// we have to hide the error message (if it is displayed)
	jq('#lbsform1_error').hide();
	
	//Initialize the array for storing route points
    routePoints = {};
    //Create a geocoder stub
    if( geocoder == null ) geocoder = new Map24.GeocoderServiceStub();
        
	//Geocode the start address of the route
    geocoder.geocode({
      SearchText: departure,
      //Define a maximum number of geocoding results to limit
      //the number of entries that will be shown in the result lists
      MaxNoOfAlternatives: 5,
      CallbackFunction: selectLBSDeparture,
      CallbackParameters: {}
    });
        
	return false;
}

function selectLBSDeparture(locs, params) {
	//Declare local variables
    var country = null;
    var city = null;
    var zip = null;
    var street = null;
    var houseNo = null;
    var state = null;
    var result = "";

    //Iterate through the array of geocoded addresses
    for( var i=0; i<locs.length; i++ ){
		//Access the fields of the geocoded address
		country = locs[i].getCountry();
		city = locs[i].getCity();
		zip = locs[i].getZip();
		street = locs[i].getStreet();
		houseNo = locs[i].getHouseNo();
		state = locs[i].getState();
		var longitude = locs[i].getLongitude();
		var latitude = locs[i].getLatitude();
		
		//If an address field is null, it is not shown in the result list.
		//Otherwise, the field's value is shown together with the category,
		//e.g. "City: Frankfurt".
		city == null? city = "": city = city;
		zip == null? zip = "": zip = " ("+zip+")";
		street == null? street = "": street = ", "+street;
		houseNo == null? houseNo = "": houseNo = " "+houseNo;
		country == null? country = "": country = country + " - ";
		state == null? state = "": state = state+": ";
		address = country+state+city+zip+street+houseNo;
		
		//Add the geocoded address to the result list
		result +='<option value="'+longitude+'|'+latitude+'|'+address+'">'+address+"</option>";
   	}

   	//Print alternative geocoded addresses for the departure in a list
	//Store alternatives for start point in an array
  	for( var i=0; i<locs.length; i++ ){
    	startPointAlternatives[i] = locs[i];
  	}

  	//Show geocoded alternatives for the start point in a list
  	jq('#departure_select').html(result);
    // check if both departure and destination has got results
    if (startPointAlternatives.length > 0) {
		// hide first form, show second
		jq('#lbsform1').hide();
		jq('#lbsform2').show();
    }
}

function checkCarReturnInput(form_obj) {
	if (jq('#manufacturer_1').val() == '') {
		// we have to display the error div - using prototype!
        jq('#crform1_error').show();
        return false;
	}
    //Retrieve departure of the route from the input field
    var start = Map24.trim( jq('#departure').val() );
    
    if (start=="") {
        // we have to display the error div - using prototype!
        jq('#crform1_error').show();
        return false;
    }
    // we have to hide the error message (if it is displayed)
    jq('#crform1_error').hide();
    
    //Initialize the array for storing route points
    routePoints = {};
    //Create a geocoder stub
    if( geocoder == null ) geocoder = new Map24.GeocoderServiceStub();
        
    //Geocode the departure address of the route
    geocoder.geocode({
      SearchText: start,
      //Define a maximum number of geocoding results to limit
      //the number of entries that will be shown in the result lists
      MaxNoOfAlternatives: 5,
      CallbackFunction: selectLocationRPDeparture,
      CallbackParameters: {position: "start"}
    });
    
    return false;
}

function resetRoutePlanner() {
	// hide the other forms
	jq('#lbsform2').hide();
	jq('#routeplannerform2').hide();
	jq('#crform3').hide();
	// clean the result divs
	jq('#lbsresults').html('');
	jq('#dekraresults').html('');
	// show first form
	jq('#lbsform1').show();
	jq('#routeplannerform1').show();
}

function getPopupSize() {
	var size = 'width=1024,height=850';
	if (Map24.Browser.MOZILLA == true) {
		size = 'innerHeight=850,innerWidth=1024';
	}
	return size
}

function openRoutePlanner(popup_url, form_obj) {
	// get selected locations and map type
	var departure = jq('#departure_select:first').val().split('|');
	var destination = jq('#destination_select:first').val().split('|');
	var map_type = (form_obj.map_type[0].checked == true) ? 1 : 2;
	// generate query string for popup
	var query = popup_url + "?start_long="+departure[0]+"&start_lat="+departure[1]+"&start_address=" + escape(departure[2]);
	query += "&destination_long="+destination[0]+"&destination_lat="+destination[1]+"&destination_address=" + escape(destination[2]) + "&mt=" + map_type;
	openMap24Window(query);	
}
	
function openMap24Window(popup_url) {
	// open popup window
	window.open(popup_url,"RoutePlanner",getPopupSize() + ",location=no,menubar=no,resizable=yes,scrollbars=yes,status=yes,toolbar=no");
	return false;
}

function popupRoutePreparation() {
	//Create a geocoder stub
    start = new Map24.Location({
    	Longitude: start_long,
    	Latitude: start_lat
    });
    dest = new Map24.Location({
    	Longitude: destination_long,
    	Latitude: destination_lat
    });
    router = new Map24.RoutingServiceStub();
	router.calculateRoute({
  		Start: start,
  		Destination: dest,
  		DescriptionLanguage: descriptionLanguage,
  		CallbackFunction: popupRouteDisplay,
  		ShowRoute: false
	});
}

function setRouteEndPoint(locations, params){
	//Access the geocoded address and add it to the routePoints array.
	//The geocoded address is stored at the first position in the locations array.
	routePoints[ params.position ] = locations[0];

	//After both the start and the destination addresses are geocoded, this function calls the calculateRoute() function.
	if( typeof routePoints["start"] != "undefined" && typeof routePoints["destination"] != "undefined") {
      	popupRouteCalculation(); 
	}
}

function popupRouteCalculation() {
	router = new Map24.RoutingServiceStub();
	router.calculateRoute({
  		Start: routePoints["start"],
  		Destination: routePoints["destination"],
  		DescriptionLanguage: descriptionLanguage,
  		CallbackFunction: popupRouteDisplay,
  		ShowRoute: false
	});
	routePoints = [];
}

function popupRouteDisplay( route ){
    //Remember the routeId. It is used e.g. to hide the route.
    routeID = route.RouteID;
    router.showRoute( {
      RouteId: routeID,
      Color: ['#00F', 150]
    });
    
    //Access the assumed time needed for traversing the route in hours
    var totalTime = ((route.TotalTime)/(60*60) ).toPrecision(3)
    var hours = Math.floor(totalTime);
    var minutes = Math.round((totalTime - hours)*60);
    if (minutes < 10) {
    	minutes = '0' + minutes;
    }
    //Access the total lenght of the route in kilometers
    var totalLength = Math.round(route.TotalLength/1000)
    // write these values into the document
    jq('#routeTravelTime').html(hours+':'+minutes+" h");
    jq('#routeTravelDistance').html(totalLength + " km"); 
    //Create table with description of the route
    var div_content = '<table border="0"><tbody>';
    var tr_class = '';
    var desc_arr = null;
    
    //Iterate through the route segments and output the step-by-step textual description of the route
    for(var i = 0; i < route.Segments.length; i++){
    	tr_class = (i % 2) == 1 ? ' class="route-even-leg"' : '';
    	div_content += '<tr' + tr_class + '><td class="route-leg">' + (i+1) + ".</td><td>";
    	desc_arr = new Array();
      	for(var j = 0; j < route.Segments[i].Descriptions.length; j++){
      		//The route description contains tags for further evaluation. For example, the [M24_STREET] tag is used 
      		//to denote a street in the description. Add the following line of code to replace these tags by a blank:
        	desc_arr[desc_arr.length] = route.Segments[i].Descriptions[j].Text.replace(/(\[|\[\/)[0-9A-Z_]+\]/g, '' );
      	}
      	div_content += desc_arr.join('<br />') + "</td></tr>";
    }
    div_content += '</tbody></tr>'
    jq('#routeDescription').html(div_content);
    jq('#map_popup_route_description').show();
}

function toggleHelicopter() {
	if (routeID && map_type=='1') {
		butHeli = jq('#toggleHelicopter');
		if (helicopter == false) {
			//Map24.MapApplication.controlComponent({Control:"SHOW",Component:"M3DROUTE"});
			Map24.MapApplication.controlComponent({Control:"SHOW",Component:"SHOWM3DROUTE"});
			Map24.MapApplication.displayHelicopterFlight({ RouteId: routeID });
			butHeli.removeClass().addClass('map-button-toggle-on').blur();
			helicopter = true;
			if (threeD == 0) {
				jq('#toggle3D').removeClass().addClass('map-button-toggle-on');
				threeD = 2;
			}
		} else {
			Map24.MapApplication.controlComponent({Control:"HIDE",Component:"M3DROUTE"});
			Map24.MapApplication.controlComponent({Control:"HIDE",Component:"SHOWM3DROUTE"});
			butHeli.removeClass().addClass('map-button-toggle-off').blur();
			helicopter = false;
			if (threeD == 2) {
				toggle3D();
			}
		}
	}
}

function toggle3D() {
	if (routeID && map_type=='1') {
		but3D = jq('#toggle3D');
		if (threeD == 0) {
			Map24.MapApplication.controlComponent({Control:"SHOW",Component:"M3D"});
			Map24.MapApplication.controlComponent({Control:"SHOW",Component:"SHOWM3D"});
			but3D.removeClass().addClass('map-button-toggle-on').blur();
			threeD = 1;
		} else {
			Map24.MapApplication.controlComponent({Control:"HIDE",Component:"M3D"});
			Map24.MapApplication.controlComponent({Control:"HIDE",Component:"SHOWM3D"});
			but3D.removeClass().addClass('map-button-toggle-off').blur();
			threeD = 0;
		}
	}
}

function localeSearch(form_obj) {
	// get necessary values
	var selection = jq('#departure_select').val();
	var sel_values = selection.split('|');
	// if selection is empty or number of elements not right
	if (selection == '' || sel_values.length != 3) {
		jq('#lbsform1_error').show();
		return false;
	}

	lbsLongitude = sel_values[0];
	lbsLatitude = sel_values[1];
	lbsAddress = sel_values[2];
	
	// hide error message
	jq('#lbsform1_error').hide()
	
	/*
	//Send a geocoder request. Pass the address and optionally 
    //the maximum number of search alternatives in the request
    conn.searchFree( new Map24.WebServices.Message.searchFreeRequest({
        MapSearchFreeRequest: new Map24.WebServices.MapSearchFreeRequest({
          SearchText: lbsAddress,
          MaxNoOfAlternatives: 25
        })
      }),
      //Since the response of the searchFree request contains relevant informations, an onSuccess 
      //handler is passed here that accesses those informations.
      onSuccessSearchFree,
      onError,
      onTimeout
    );
    */
	findLocations(null, radius, map24Layers);
}

//Find the locations within the given radius around a given point provided in the ''geocodedAddress''
//parameter. The method searches for the locations in the provided Map24 Layers.
function findLocations( geocodedAddress, radius, map24Layers ){
	if (geocodedAddress != null) {
		lbsLongitude = geocodedAddress.getProperty("Coordinate").getProperty("Longitude");
	  	lbsLatitude = geocodedAddress.getProperty("Coordinate").getProperty("Latitude");
	}
    
    conn.findByPoints( new Map24.WebServices.Message.findByPointsRequest({
      FindByPointsRequest: new Map24.WebServices.FindByPointsRequest({
        CustomerLayerIDs: map24Layers,
        Radius: radius,
        //Define the point around which the search is performed 
        //in an object of type ''Map24.WebServices.CoordinateAndAddress''
        Points: [
          new Map24.WebServices.CoordinateAndAddress({
            Coordinate: new Map24.WebServices.Coordinate({
              //Access the coordinates of the point from the geocoded address
              Longitude: lbsLongitude,
              Latitude: lbsLatitude
            })
          })
        ]
      })}),
      onSuccessFindByPoints,
      onError,
      onTimeout
    );
}
 
//Implement function that is called when the client receives a MapSearch result from 
//the server. Now you can access the result and call the findLocations() function.
function onSuccessSearchFree( connection, request, response ){
    //Access the geocoded addresses
    var responseMapSearchFree = this.Response.getProperty("MapSearchResponse");
    var alternatives = responseMapSearchFree.getProperty("Alternatives");
    //Use only the first geocoded address as parameter
    var geocodedAddress = alternatives[0];
    //Call the findLocations() function, passing the parameters
    findLocations( geocodedAddress, radius, map24Layers );  
}

//Find the locations within the given radius around a given point provided in the ''geocodedAddress''
//parameter. The method searches for the locations in the provided Map24 Layers.
function findCarReturnStations() {
	// get location coordinates from departure_select field
	geoCodedArr = jq('#departure_select').val().split('|');
	lbsLongitude = geoCodedArr[0];
	lbsLatitude = geoCodedArr[1];
	lbsAddress = geoCodedArr[2];
	
	// get the Layer IDs -> check both map24Layers variable and manufacturer select (as both are synchronized it doesn't matter which one we choose)
	manuCombi = jq('#manufacturer_2').val();
	manufacturerLayerID = manuCombi.split('|')[1];
	// look whether the manufacturer's layer ID is already in the list
	if (map24Layers[0] != manufacturerLayerID) {
		map24Layers[1] = manufacturerLayerID;
	} else {
		map24Layers = new Array(map24Layers[0]);
	}
	
	if (conn == null) {
		// Location Based Search
		map = new Map24.Map();
		//Open a connection to the Web services.
    	conn = map.WebServices.openConnection();
    	//Open a local connection.
    	locConn = map.Local.openConnection();
	}
  
  conn.findByPoints( new Map24.WebServices.Message.findByPointsRequest({
    FindByPointsRequest: new Map24.WebServices.FindByPointsRequest({
      CustomerLayerIDs: map24Layers,
      Radius: radius,
      //Define the point around which the search is performed 
      //in an object of type ''Map24.WebServices.CoordinateAndAddress''
      Points: [
        new Map24.WebServices.CoordinateAndAddress({
          Coordinate: new Map24.WebServices.Coordinate({
            //Access the coordinates of the point from the geocoded address
            Longitude: lbsLongitude,
            Latitude: lbsLatitude
          })
        })
      ]
    })}),
    onSuccessFindCarReturnStationsByPoints,
    onError,
    onTimeout
  );
}
 
//This handler is called when a FindByPointsResponse is available
function onSuccessFindByPoints( connection, request, response ){    
    var responseFindByPoints = this.Response.getProperty("FindByPointsResponse");
                                            
    var addresses = responseFindByPoints.getProperty("Addresses")[0];  
    //Access the locations
    var locs = addresses.getProperty("Map24Locations");
    
    // prepare the first part of the URL - take coordinates and address
    // from starting point for the route planning popups
    var rp_start = "?start_long="+lbsLongitude+"&start_lat="+lbsLatitude+"&start_address=" + escape(lbsAddress);    
    
    //Create a list that shows the results
    var result= "";
    
    // get Template for location view
    var loc_templ = jq('#lbsresults').html();
    
    // flag for checking whether the legend should be displayed
    var hasHighlighted = false;
        
    //Iterate through the array of locations
    for( var i=0; i<locs.length; i++ ){
      
    	//Access information about the location and store it in a string
     	var addressText = '' + loc_templ;
     	// replace the highlighting class
     	if (locs[i].getProperty("LayerID")==highlightedLayerId) {
     		hasHighlighted = true;
     		addressText = addressText.replace(/LBSRESULT_CLASS/, "highlighted-lbs-result-container");
     	} else {
            addressText = addressText.replace(/LBSRESULT_CLASS/, "lbs-result-container");
     	}
     	addressText = addressText.replace(/LBSRESULT_NAME/, cleanupProperty(locs[i].getProperty("Name1")));
     	addressText = addressText.replace(/LBSRESULT_STREET/, cleanupProperty(locs[i].getProperty("Street")));
     	// get the zip + location
     	var zip = cleanupProperty(locs[i].getProperty("ZIP"));
     	var zip_loc = zip ? zip + ' ' : '';
     	zip_loc += cleanupProperty(locs[i].getProperty("City"));
     	addressText = addressText.replace(/LBSRESULT_LOCATION/, zip_loc);
     	// calculate distance in kilometres
     	var dist = (locs[i].getProperty("Distance")/1000).toFixed(2);
     	addressText = addressText.replace(/LBSRESULT_DISTANCE/, dist);
     	// generate the links for the detailed view and the route planner
     	var longitude = locs[i].getProperty("Longitude");
     	var latitude = locs[i].getProperty("Latitude");
     	// url for detailed view
     	addr = escape(cleanupProperty(locs[i].getProperty("Street")) + ', ' + zip_loc);
     	var dv_url = "?start_long="+longitude+"&start_lat="+latitude+"&start_address="+addr;
     	dv_url += "&start_name="+escape(cleanupProperty(locs[i].getProperty("Name1")))+"&dv=1&mt=";
     	addressText = addressText.replace(/LBSRESULT_DV_INTERACTIVE/, dv_url+'1');
     	addressText = addressText.replace(/LBSRESULT_DV_STATIC/, dv_url+'2');
     	// route planning
     	var rp_url = rp_start+"&destination_long="+longitude+"&destination_lat="+latitude+"&destination_address="+addr;
     	rp_url += "&destination_name="+escape(cleanupProperty(locs[i].getProperty("Name1")))+"&dv=0&mt=";
     	addressText = addressText.replace(/LBSRESULT_RP_INTERACTIVE/, rp_url+'1');
     	addressText = addressText.replace(/LBSRESULT_RP_STATIC/, rp_url+'2');
      	result += addressText;
    }
    jq('#lbsresults').html(result);
    // display the legend text?
    if (hasHighlighted) jq('#lbslegend').show(); 
    // hide the infotext too (like in old website)
	jq('#mp_infotext').hide();
	jq('#lbsform2').hide();
	jq('#lbsform3').show(); 
}

function cleanupProperty(prop) {
	return (typeof(prop) == 'undefined') ? '-' : prop;
}

// retrieve location information into associative array
function createLocationEntry(loc) {
	var entry = new Array();
	var props = new Array('Name1', 'Street', 'ZIP', 'City', 'Distance', 'Longitude', 'Latitude', 'Phone', 'Fax', 'EMail');
	for (var c=0; c<props.length;c++) {
		entry[props[c]] = cleanupProperty(loc.getProperty(props[c]));
	}
	return entry;
}

function switchLocationResultDisplay(dekra) {
	if (dekra == true) {
		// display DEKRA div
		jq('#manufacturer_header').hide();
		jq('#lbsresults').hide();
		jq('#dekra_header').show();
    	jq('#dekra_link').hide();
    	jq('#dekraresults').show();
    	if (map24Layers.length > 1) {
    		jq('#manufacturer_link').show();
    	}
	} else {
		// display car dealer div -> DEKRA div has to be there too
		jq('#manufacturer_header').show();
    	jq('#manufacturer_link').hide();
    	jq('#lbsresults').show();
    	jq('#dekra_header').hide();
    	jq('#dekra_link').show();
    	jq('#dekraresults').hide();
	}
	return false;
}

//This handler is called when a FindByPointsResponse is available
function onSuccessFindCarReturnStationsByPoints( connection, request, response ){    
    var responseFindByPoints = this.Response.getProperty("FindByPointsResponse");
    
    var addresses = responseFindByPoints.getProperty("Addresses")[0];  
    //Access the locations
    var locs = addresses.getProperty("Map24Locations");
    
    // prepare the first part of the URL - take coordinates and address
    // from starting point for the route planning popups
    var rp_start = "?start_long="+lbsLongitude+"&start_lat="+lbsLatitude+"&start_address=" + escape(lbsAddress);    
    
    //Create a list that shows the results
    var result= "";
    
    // get Template for location view
    var loc_templ = jq('#lbsresults_template').html();
    
    // reset JS Array for Result Storage
    crResults = new Array();
    
    // temporary array for generated HTML code
    // first index contains hits for Dekra, secondary one the manufacturer's
    var htmlArr = new Array('', '');
        
    //Iterate through the array of locations
    for( var i=0; i<locs.length; i++ ){
    	entry = createLocationEntry(locs[i]);
    	crIndex = crResults.length;
    	crResults[crIndex] = entry;
      
    	//Access information about the location and store it in a string
     	var addressText = '' + loc_templ;
     	addressText = addressText.replace(/LBSRESULT_NAME/, entry["Name1"]);
     	addressText = addressText.replace(/LBSRESULT_STREET/, entry["Street"]);
     	// get the zip + location
     	var zip = entry["ZIP"];
     	var zip_loc = zip ? zip + ' ' : '';
     	zip_loc += entry["City"];
     	addressText = addressText.replace(/LBSRESULT_LOCATION/, zip_loc);
     	// calculate distance in kilometres
     	var dist = (entry["Distance"]/1000).toFixed(2);
     	addressText = addressText.replace(/LBSRESULT_DISTANCE/, dist);
     	// generate the links for the detailed view and the route planner
     	var longitude = entry["Longitude"];
     	var latitude = entry["Latitude"];
     	// url for detailed view
     	addr = escape(entry["Street"] + ', ' + zip_loc);
     	var dv_url = "?start_long="+longitude+"&start_lat="+latitude+"&start_address="+addr;
     	dv_url += "&start_name="+escape(entry["Name1"])+"&dv=1&mt=";
     	addressText = addressText.replace(/LBSRESULT_DV_INTERACTIVE/, dv_url+'1');
     	addressText = addressText.replace(/LBSRESULT_DV_STATIC/, dv_url+'2');
     	// route planning
     	var rp_url = rp_start +"&destination_long="+longitude+"&destination_lat="+latitude+"&destination_address="+addr;
     	rp_url += "&destination_name="+escape(entry["Name1"])+"&dv=0&mt=";
     	addressText = addressText.replace(/LBSRESULT_RP_INTERACTIVE/, rp_url+'1');
     	addressText = addressText.replace(/LBSRESULT_RP_STATIC/, rp_url+'2');
     	addressText = addressText.replace(/CR_RESULT_INDEX/, crIndex);
     	
     	if (locs[i].getProperty('LayerID') == map24Layers[0]) {
     		// DEKRA location
     		htmlArr[0] += addressText;
     	} else {
     		// Car dealer
     		htmlArr[1] += addressText;
     	}
      	result += addressText;
    }
    // fill in the html content for car dealers and DEKRA locations
    jq('#lbsresults').html(htmlArr[1]);
    jq('#dekraresults').html(htmlArr[0]);
    
    // handle headers and links
    if (map24Layers.length == 1) {
    	// only DEKRA - handle visibility of headers, links and divs
    	switchLocationResultDisplay(true);
    } else {
    	// Car dealer available - fill in Dealer name and handle visibility of headers, links and divs
    	manuCombi = jq('#manufacturer_2').val();
    	manufacturerName = manuCombi.split('|')[0];
    	jq('span.manufacturerName').html(manufacturerName);
    	
    	// display results for car dealer
    	switchLocationResultDisplay(false);
    }
    
    // hide the infotext too (like in old website)
	jq('#routeplannerform2').hide();
	
	// finally display result div
	jq('#crform3').show(); 
}

function switchLocationResultDisplay(dekra) {
	if (dekra == true) {
		// display DEKRA div
		jq('#manufacturer_header').hide();
		jq('#lbsresults').hide();
		jq('#dekra_header').show();
    	jq('#dekra_link').hide();
    	jq('#dekraresults').show();
    	if (map24Layers.length > 1) {
    		jq('#manufacturer_link').show();
    	}
    	if (jq('#dekraresults').html() == '') {
    		jq('#nolbsresults').show();
    	} else {
    		jq('#nolbsresults').hide();
    	}
	} else {
		// display car dealer div -> DEKRA div has to be there too
		jq('#manufacturer_header').show();
    	jq('#manufacturer_link').hide();
    	jq('#lbsresults').show();
    	jq('#dekra_header').hide();
    	jq('#dekra_link').show();
    	jq('#dekraresults').hide();
    	if (jq('#lbsresults').html() == '') {
    		jq('#nolbsresults').show();
    	} else {
    		jq('#nolbsresults').hide();
    	}
	}
	return false;
}

function submitCarReturnForm(crIndex) {
	// the index should be valid
	if (crIndex < 0 || crIndex >= crResults.length) {
		onError();
		return false;
	}
	// transfer all values from the array into the form
	entry = crResults[crIndex];
	for (var prop in entry) {
		jq('#crf_' + prop).val(entry[prop]);
	}
	// get the manufacturer and put it into the form
	jq('#crf_manufacturer').val(jq('#manufacturer_2').val().split('|')[0]);
	document.forms['crf'].submit();
}

function centerOnDetailLocation(){
    locConn.mapletRemoteControl( 
	    new Map24.WebServices.Message.mapletRemoteControlRequest({
        	MapletRemoteControlRequest: new Map24.WebServices.MapletRemoteControlRequest({
          		Map24MRC: new Map24.WebServices.Map24MRC({
            		Commands: [
              			new Map24.WebServices.XMLCommandWrapper({
                			SetMapView: new Map24.WebServices.SetMapView({
                  				Coordinates: [ 
                    				new Map24.WebServices.Coordinate({ 
                      					Longitude: start_long,  
                      					Latitude: start_lat
                    				})
                  				],
                  				ClippingWidth: new Map24.WebServices.SetMapViewClippingWidth({
                    				MinimumWidth: 400
                  				})
                			})
              			})
            		]
          		}) 
        	})
		}),
    	null,
    	onError,
    	onTimeout
	);
}

function getLocationDescription() {
	conn.findByPoints( new Map24.WebServices.Message.findByPointsRequest({
      FindByPointsRequest: new Map24.WebServices.FindByPointsRequest({
        CustomerLayerIDs: map24Layers,
        Radius: 100,
        //Define the point around which the search is performed 
        //in an object of type ''Map24.WebServices.CoordinateAndAddress''
        Points: [
          new Map24.WebServices.CoordinateAndAddress({
            Coordinate: new Map24.WebServices.Coordinate({
              //Access the coordinates of the point from the geocoded address
              Longitude: start_long,
              Latitude: start_lat
            })
          })
        ]
      })}),
      displayLocationDescription,
      onError,
      onTimeout
    );
}

function displayLocationDescription(connection, request, response) {
    var responseFindByPoints = this.Response.getProperty("FindByPointsResponse");
                                            
    var addresses = responseFindByPoints.getProperty("Addresses")[0];  
    //Access the locations
    var locs = addresses.getProperty("Map24Locations");
	
	if (locs.length > 0) {
		var loc = locs[0];
		var loc_txt = '<strong>'+loc.getProperty('Name1')+'</strong>';
		loc_txt += loc.getProperty('Name2') ? '<br />' + loc.getProperty('Name2') : '';
		loc_txt += loc.getProperty('Name3') ? '<br />' + loc.getProperty('Name3') : '';
		loc_txt += loc.getProperty('Salutation') ? '<br />' + loc.getProperty('Salutation') : '';
		loc_txt += loc.getProperty('Street') ? '<br />' + loc.getProperty('Street') : '';
		var zip = loc.getProperty('ZIP');
		var city = loc.getProperty('City');
		if ((zip != '') || (city != '')) {
			loc_txt += '<br />';
			loc_txt += (zip != '') ? zip + ' ' : '';
			loc_txt += (city != '') ? city : '';
		}
		loc_txt += '<br />';
		loc_txt += loc.getProperty('Phone') ? '<br />Tel: ' + loc.getProperty('Phone') : '';
		loc_txt += loc.getProperty('Fax') ? '<br />Fax: ' + loc.getProperty('Fax') : '';
		loc_txt += loc.getProperty('EMail') ? '<br />@: ' + loc.getProperty('EMail') : '';
		
		jq('#map_popup_start_location').html(loc_txt);
	}
}
 
//Handler that is called if an error occurs instead of receiving a respsonse via the Web 
//services connection conn.
function onError(){ alert("An Error Occured!") };
//Handler that is called if a timeout occurs instead of receiving a respsonse via the Web 
//services connection conn.
function onTimeout(){ alert("A Timeout Occured!") };

// this function should override a broken one loaded earlier
function getSearchTermsFromURI(uri) {
    var query;
    if (typeof decodeURI != 'undefined') {
    	try {
        	query = decodeURI(uri);
    	} catch (err) {
    		query = unescape(uri);
    	}
    } else if (typeof unescape != 'undefined') {
        // _robert_ ie 5 does not have decodeURI
        query = unescape(uri);
    } else {
        // we just try to be lucky, for single words this will still work
    }
    var result = new Array();
    if (window.decodeReferrer) {
        var referrerSearch = decodeReferrer();
        if (null != referrerSearch && referrerSearch.length > 0) {
            result = referrerSearch;
        }
    }
    var qfinder = new RegExp("(searchterm|SearchableText)=([^&]*)", "gi");
    var qq = qfinder.exec(query);
    if (qq && qq[2]) {
        var terms = qq[2].replace(/\+/g,' ').split(' ');
        result.push.apply(result, jq.grep(terms, function(a) { return a != ""}));
        return result;
    }
    return result.length == 0 ? false : result;
}

function synchronizeManufacturer(counter) {
	var source = null;
	var target = null;
	if (counter == '1') {
		source = jq('#manufacturer_2');
		target = jq('#manufacturer_1');
	} else if (counter == '2') {
		source = jq('#manufacturer_1');
		target = jq('#manufacturer_2');
	}
	target.val(source.val());
}