  //Declare global variables  
  var geocoder = null;
  var router = null;
  var routePoints = [];
  var routePointsCount = null;
  var geocodedPointsCount = null;
  var routeID = null;
  var viaLocs = new Array();
  var startLoc = null;
  var destLoc = null;
    
  function goMap24() { 	
    Map24.loadApi( ["core_api", "wrapper_api"] , map24ApiLoaded );
  }
  
  function map24ApiLoaded(){
    Map24.MapApplication.init( { NodeName: "maparea" } ); 
    //Disable print description button
    document.getElementById("print").disabled = false;
  }
 
  function startRouting(){
  	
    //Initialize the array for storing route points
    routePoints = {};
    //Initialize the counter for geocoded addresses
    geocodedPointsCount = 0;
 
    //Retrieve start and destination of the route from the input fields
    var start = Map24.trim( $v('start') );
    var destination = Map24.trim( $v('destination') );
    
    //Check if the start and the destination form fields are empty
    if( start == "" ) { alert("Please enter start address!"); return; }
    if( destination == "" ) { alert("Please enter destination address!"); return; }
    
    //Retrieve via points from the input fields
    //Ignore empty fields and fields that are filled with whitespaces only.
    var vias = [];
    for( var i=0; i < 4; i++ ){
      if( Map24.trim( $v( "via_"+i ) ) != "" )
        vias.push( $v("via_"+i) );
    }
 
    //Create a counter that contains the number of route points
    routePointsCount = 2 + vias.length;
    
    //Disable the button for starting a route calculation
    document.getElementById("button_calculate_route").disabled = true;
    
    //Create a geocoder stub
    if( geocoder == null ) geocoder = new Map24.GeocoderServiceStub();
    
    //Geocode the start address of the route
    geocoder.geocode({ 
      SearchText: start, 
      CallbackFunction: setRoutePoint, 
      CallbackParameters: {position: "start"}
    });
    
    //Geocode the destination address of the route.
    geocoder.geocode({
      SearchText: destination,  
      CallbackFunction: setRoutePoint,
      CallbackParameters: {position: "destination"}
    });
    
    //Geocode the via points.
    for( var i=0; i < vias.length; i++ ) {
      geocoder.geocode({
        SearchText: vias[i],
        CallbackFunction:  setRoutePoint,
        //Specify the position in the array of via points in the CallbackParameters field 
        //with an additional parameter (index).
        CallbackParameters: { position: "via", index: i }
      });
    }
  }
  
  //Callback function that is called when the geocoding result is available.
  //The locations parameter contains an array with multiple alternative geocoding results.
  //The params parameter passes the value of CallbackParameters that specifies which route 
  //end point is returned (start or destination point).
  function setRoutePoint(locations, params){
  	
    //Check if the geocoded address is a via point.
    if( params.position == "via") {
      //Check if via points were provided in the request at all.
      if( typeof routePoints[ "via" ] == "undefined") 
        routePoints[ "via" ] = [];
      //Store the via point
      routePoints[ params.position ][ params.index ] = locations[0];
    }
    else 
      //Store the geocoded start or destination point
      routePoints[ params.position ] = locations[0];
    
    //Increment the counter for geocoded addresses
    geocodedPointsCount++;
    
    //If all addresses are geocoded successfully, this function calls the calculateRoute() function.
    if( geocodedPointsCount == routePointsCount ) {
      calculateRoute(); 
    }  
  }
  
  //Calculate the route. The via points are added in the ViaPoints field.
  function calculateRoute() {
 
    //Create a routing service stub
    if( router == null ) router = new Map24.RoutingServiceStub();
    
    //Calculate the route. 
    router.calculateRoute({
      Start: routePoints["start"],
      Destination: routePoints["destination"],
      DescriptionLanguage: "es",
      ViaPoints: routePoints["via"],
      CallbackFunction: displayRoute,
      //The ShowRoute parameter is set to false, the route is not shown automatically.
      //This is necessary if you want to change the default color used for showing the route.
      //To show the route call the Map24.RoutingServiceStub.showRoute() function in the callback function.
      ShowRoute: false
    }); 
  }
 
  //Callback function used to access the calculated route of type Map24.WebServices.Route
  //and to print a detailed route description.
  function displayRoute( route ){
    //Remember the routeId. It is used e.g. to hide the route.
    routeID = route.RouteID;
    
    //Show the route with blue color and transparency.
    //The transparency can be set to a value between 0 (completely transparent) and 255 (opaque).
    router.showRoute( {
      RouteId: routeID,
      Color: ['#00F', 150]
    });
    //Add a location at the position of the route's start point.
    startLoc = new Map24.Location({
      Longitude: routePoints["start"].getLongitude(),
      Latitude: routePoints["start"].getLatitude(),
      Description: "Start Point",
      SymbolId: 20950
    }); 
    startLoc.commit();
    
    //Add a location at the position of the route's destination point.
    destLoc = new Map24.Location({
      Longitude: routePoints["destination"].getLongitude(),
      Latitude: routePoints["destination"].getLatitude(),
      Description: "Destination Point",
      SymbolId: 20958
    });
    destLoc.commit();    
      	
    //Add locations at the position of the route's via points.	
    for(var i = 0; i < (routePointsCount-2); i++){
      var loc = new Map24.Location({
        Longitude: routePoints["via"][i].getLongitude(),
        Latitude: routePoints["via"][i].getLatitude(),
        Description: "Via Point "+(i+1),
        SymbolId: 20951
      });
      loc.commit();   
      viaLocs[i] = loc; 
    }
  
 
    //Access the assumed time needed for traversing the route in hours
    var totalTime = ((route.TotalTime)/(60*60) ).toPrecision(3) 
    //Access the total lenght of the route in kilometers
    var totalLength = (route.TotalLength/1000) 
    //Create table with description of the route
    var div_content = "Total Time: " + totalTime + " h<br>" ;     
    div_content += "Total Length: "+ totalLength +" km<br>";
    div_content += "<br>";
    
    //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++){
      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:
        div_content += (i+1) + ". " + route.Segments[i].Descriptions[j].Text.replace(/(\[|\[\/)[0-9A-Z_]+\]/g, '' ) + "<br>";
      }
    } 
    
    document.getElementById('routeDescription').innerHTML = div_content;
    document.getElementById("button_hide_route").disabled = false;
    document.getElementById("button_remove_route").disabled = false;
    document.getElementById("print").disabled = false;
  }
  
   //Show route
  function showRoute(routeID) {
  	router.showRoute({RouteId: routeID});
  	 startLoc.show();
    destLoc.show();
    
    for(var i = 0; i < routePointsCount-2; i++){
      viaLocs[i].show();
    }  
    document.getElementById("button_show_route").disabled = true;
    document.getElementById("button_hide_route").disabled = false;
    document.getElementById("button_remove_route").disabled = false;
  }   
   
  //Hide route
  function hideRoute(routeID) {
  	router.hideRoute({RouteId: routeID});
  	startLoc.hide();
    destLoc.hide();
    
    for(var i = 0; i < routePointsCount-2; i++){
      viaLocs[i].hide();
    }  
    document.getElementById("button_remove_route").disabled = true;
    document.getElementById("button_show_route").disabled = false;
    document.getElementById("button_hide_route").disabled = true;
  }
    
  //Remove route
  function removeRoute(routeID) {
    router.removeRoute({RouteId: routeID});
    startLoc.remove();
    destLoc.remove();
    for(var i = 0; i < routePointsCount-2; i++){
      viaLocs[i].remove();
    }
  
    document.getElementById("routeDescription").innerHTML = "";
    document.getElementById("button_calculate_route").disabled = false;
    document.getElementById("button_show_route").disabled = true;
    document.getElementById("button_hide_route").disabled = true;
    document.getElementById("button_remove_route").disabled = true;
    document.getElementById("print").disabled = true; 
  }
   
  //Helper function for accessing the div specified in the id parameter.
  //The function checks first if the div contains content.
  function $v( id ) { 
    return (document.getElementById( id ).value != "undefined") ?  
    document.getElementById( id ).value : ""; 
  }
  
  //Print Description function. 
  //The function opens a print preview window of the route description and one can choose the printer.
  function printRouteDescription(){
    var printContent = document.getElementById("routeDescription");
    var windowPrint = window.open('','','left=0,top=0,width=0,height=0,toolbar=0,scrollbars=0,status=0');
    windowPrint.document.write(printContent.innerHTML);
    windowPrint.document.close();
    windowPrint.focus();
    windowPrint.print();
    windowPrint.close();
  }